/* * File: AIGBasedSkolem.hpp * Author: Ajith John * * Created on 15 April, 2014 */ #include "AIGBasedSkolem.hpp" #include "Graph.hpp" /** * Initializes pub_aig_manager * @param em */ AIGBasedSkolem::AIGBasedSkolem(Aig_Man_t* aig_manager) { if (AIGBasedSkolem_instance != NULL) { cerr << "Error in AIGBasedSkolem::AIGBasedSkolem: Attempt to create multiple copies of AIGBasedSkolem" << endl; cerr << "There should be only one copy of AIGBasedSkolem" << endl; assert(0); } pub_aig_manager = aig_manager; } AIGBasedSkolem::~AIGBasedSkolem() { } AIGBasedSkolem* AIGBasedSkolem::AIGBasedSkolem_instance = NULL; AIGBasedSkolem* AIGBasedSkolem::getInstance(Aig_Man_t* aig_manager) { if(AIGBasedSkolem_instance == NULL) { try { AIGBasedSkolem_instance = new AIGBasedSkolem(aig_manager); } catch(bad_alloc&) { cerr << "Memory allocation failure in AIGBasedSkolem::getInstance" << endl; assert(0); } } return AIGBasedSkolem_instance; } void AIGBasedSkolem::initializeFactorizedSkolemFunctionGenerator(set &Factors_new, list &VariablesToEliminate) { set VariablesToEliminate_Set(VariablesToEliminate.begin(), VariablesToEliminate.end()); set Factors; if(drop_free_factors) { for(set::iterator factor_it = Factors_new.begin(); factor_it != Factors_new.end(); factor_it++) { Aig_Obj_t* factor = *factor_it; assert(factor != NULL); set support_factor; computeSupport(factor, support_factor, pub_aig_manager); set varstoelim_in_support_factor; set_intersection(support_factor.begin(), support_factor.end(), VariablesToEliminate_Set.begin(), VariablesToEliminate_Set.end(), inserter(varstoelim_in_support_factor, varstoelim_in_support_factor.begin())); if(!varstoelim_in_support_factor.empty()) { Factors.insert(factor); } }//for }//if(drop_free_factors) ends here else { Factors = Factors_new; } // Let's first remove the free factors // Let's now 1) Remove variables which are not occuring in the factors // from the set of variables to be eliminated, and // 2) Insert the factors into FactorMatrix set support; set Final_VariablesToEliminate_Set; number_of_factors = Factors.size(); // insert factors into FactorMatrix[1...number_of_factors] int factor_index = 1; // varies from 1 to number_of_factors #ifdef DEBUG_CEGAR string support_file_name = logfile_prefix; support_file_name += "support.txt"; FILE* support_fp = fopen(support_file_name.c_str(), "w"); assert(support_fp != NULL); printSet(VariablesToEliminate_Set, "Original_VariablesToEliminate_Set", support_fp); #endif map VarsToElim_To_Factors_Map; map > VarsToElim_in_Supports_of_Factors; for(set::iterator factor_it = Factors.begin(); factor_it != Factors.end(); factor_it++) { Aig_Obj_t* factor = *factor_it; assert(factor != NULL); set support_factor; computeSupport(factor, support_factor, pub_aig_manager); // AIG Manager API Call int support_size = support_factor.size(); original_factor_support_sizes.insert(make_pair(factor_index, support_size)); copy(support_factor.begin(), support_factor.end(), inserter(support, support.end())); set varstoelim_in_support_factor; set_intersection(support_factor.begin(), support_factor.end(), VariablesToEliminate_Set.begin(), VariablesToEliminate_Set.end(), inserter(varstoelim_in_support_factor, varstoelim_in_support_factor.begin())); int varstoelim_in_support_factor_size = varstoelim_in_support_factor.size(); original_factor_varstoelim_sizes.insert(make_pair(factor_index, varstoelim_in_support_factor_size)); int factor_size = computeSize(factor, pub_aig_manager); // AIG Manager API Call original_factor_sizes.insert(make_pair(factor_index, factor_size)); copy(varstoelim_in_support_factor.begin(), varstoelim_in_support_factor.end(), inserter(Final_VariablesToEliminate_Set, Final_VariablesToEliminate_Set.end())); for(set::iterator varstoelim_it = varstoelim_in_support_factor.begin(); varstoelim_it != varstoelim_in_support_factor.end(); varstoelim_it++) { string variable_to_eliminate = *varstoelim_it; map::iterator VarsToElim_To_Factors_Map_it = VarsToElim_To_Factors_Map.find(variable_to_eliminate); if(VarsToElim_To_Factors_Map_it == VarsToElim_To_Factors_Map.end()) // variable_to_eliminate occuring for the first time { VarsToElim_To_Factors_Map.insert(make_pair(variable_to_eliminate, 1)); } else { (VarsToElim_To_Factors_Map_it->second)++; } } #ifdef DEBUG_CEGAR fprintf(support_fp,"\nfactor_%d\n",factor_index); cout << endl; printSet(support_factor, "support_factor", support_fp); cout << endl; printSet(varstoelim_in_support_factor, "varstoelim_in_support_factor", support_fp); cout << endl; #endif insertIntoOneDimensionalMatrix(FactorMatrix, number_of_factors, factor_index, factor, false); #ifdef RECORD_KEEP abstracted_factor_sizes.insert(make_pair(factor_index, factor_size)); #endif if(order_of_elimination_of_variables == 2 || order_of_elimination_of_variables == 4) { VarsToElim_in_Supports_of_Factors.insert(make_pair(factor, varstoelim_in_support_factor)); } factor_index++; } original_support_size = support.size(); set_difference(support.begin(), support.end(), Final_VariablesToEliminate_Set.begin(), Final_VariablesToEliminate_Set.end(), inserter(variables_not_quantified, variables_not_quantified.begin())); original_variables = support; variables_quantified = Final_VariablesToEliminate_Set; #ifdef DEBUG_CEGAR printSet(support, "support", support_fp); printSet(Final_VariablesToEliminate_Set, "Final_VariablesToEliminate_Set", support_fp); printSet(variables_not_quantified, "variables_not_quantified", support_fp); printSet(variables_quantified, "variables_quantified", support_fp); fclose(support_fp); #endif #ifdef DETAILED_RECORD_KEEP struct timeval ordering_start_ms, ordering_finish_ms; gettimeofday (&ordering_start_ms, NULL); #endif cout << "\nFinding the order of elimination of variables\n"; if(order_of_elimination_of_variables == 1) // least-factor-first order { map > Factors_To_VarsToElim_Map; for(map::iterator VarsToElim_To_Factors_Map_it = VarsToElim_To_Factors_Map.begin(); VarsToElim_To_Factors_Map_it != VarsToElim_To_Factors_Map.end(); VarsToElim_To_Factors_Map_it++) { string variable_to_eliminate = VarsToElim_To_Factors_Map_it->first; int number_of_factors_with_variable_to_eliminate = VarsToElim_To_Factors_Map_it->second; //cout << endl << variable_to_eliminate << "\t" << number_of_factors_with_variable_to_eliminate << endl; map >::iterator Factors_To_VarsToElim_Map_it = Factors_To_VarsToElim_Map.find(number_of_factors_with_variable_to_eliminate); if(Factors_To_VarsToElim_Map_it == Factors_To_VarsToElim_Map.end()) { set variables_with_factor_count; variables_with_factor_count.insert(variable_to_eliminate); Factors_To_VarsToElim_Map.insert(make_pair(number_of_factors_with_variable_to_eliminate, variables_with_factor_count)); } else { (Factors_To_VarsToElim_Map_it->second).insert(variable_to_eliminate); } } VariablesToEliminate.clear(); for(map >::iterator Factors_To_VarsToElim_Map_it = Factors_To_VarsToElim_Map.begin(); Factors_To_VarsToElim_Map_it != Factors_To_VarsToElim_Map.end(); Factors_To_VarsToElim_Map_it++) { //cout << endl << "factor_count = " << Factors_To_VarsToElim_Map_it->first <<"\tvariables = "; set variables_with_factor_count = Factors_To_VarsToElim_Map_it->second; for(set::iterator variable_it = variables_with_factor_count.begin(); variable_it != variables_with_factor_count.end(); variable_it++) { //cout << *variable_it << ", "; VariablesToEliminate.push_back(*variable_it); } } } else if(order_of_elimination_of_variables == 3) // from external file { // we should read the order from the given file list OrderOfVariableEliminationFromFile; obtainOrderOfVariableEliminationFromFile(OrderOfVariableEliminationFromFile); #ifdef DEBUG_SKOLEM cout << endl << "OrderOfVariableEliminationFromFile" << endl; showList(OrderOfVariableEliminationFromFile); #endif VariablesToEliminate.clear(); for(list::iterator var_order_it = OrderOfVariableEliminationFromFile.begin(); var_order_it != OrderOfVariableEliminationFromFile.end(); var_order_it++) { string var_from_order_file = *var_order_it; if(Final_VariablesToEliminate_Set.find(var_from_order_file) != Final_VariablesToEliminate_Set.end()) // this is a var to elim { VariablesToEliminate.push_back(var_from_order_file); } } cout << endl << "VariablesToEliminate" << endl; showList(VariablesToEliminate); } else if(order_of_elimination_of_variables == 0) // lexico-graphic order { VariablesToEliminate.clear(); copy(Final_VariablesToEliminate_Set.begin(), Final_VariablesToEliminate_Set.end(), inserter(VariablesToEliminate, VariablesToEliminate.end())); } else if(order_of_elimination_of_variables == 2) // factor-graph-based order { VariablesToEliminate.clear(); obtainFactorGraphBasedOrdering(VarsToElim_in_Supports_of_Factors, Final_VariablesToEliminate_Set, VariablesToEliminate); } else if(order_of_elimination_of_variables == 4) // reverse factor-graph-based order { VariablesToEliminate.clear(); obtainFactorGraphBasedOrdering(VarsToElim_in_Supports_of_Factors, Final_VariablesToEliminate_Set, VariablesToEliminate); VariablesToEliminate.reverse(); } else { cout << "\nUnknown order " << order_of_elimination_of_variables << endl; assert(false); } if(apply_tsietin_encoding_on_benchmarks) { assert(order_of_elimination_of_variables == 1);//Presently implemented // only for order_of_elimination_of_variables == 1 pushTsietinVariablesUpInOrder(VariablesToEliminate); } #ifdef DETAILED_RECORD_KEEP gettimeofday (&ordering_finish_ms, NULL); total_time_in_ordering = ordering_finish_ms.tv_sec * 1000 + ordering_finish_ms.tv_usec / 1000; total_time_in_ordering -= ordering_start_ms.tv_sec * 1000 + ordering_start_ms.tv_usec / 1000; #endif number_of_vars_to_elim = VariablesToEliminate.size(); cout << "\nOrder of elimination of variables found\n"; #ifdef DETAILED_RECORD_KEEP string order_file_name = logfile_prefix; if(order_of_elimination_of_variables == 0) { order_file_name += "lexico_graphic_order.txt"; } else if(order_of_elimination_of_variables == 1) { order_file_name += "least_factor_first_order.txt"; } else if(order_of_elimination_of_variables == 2) { order_file_name += "factor_graph_based_order.txt"; } else if(order_of_elimination_of_variables == 3) { order_file_name += "external_order.txt"; } else if(order_of_elimination_of_variables == 4) { order_file_name += "reverse_factor_graph_based_order.txt"; } else { cout << "\nUnknown order " << order_of_elimination_of_variables << endl; assert(false); } FILE* order_fp = fopen(order_file_name.c_str(), "w+"); assert(order_fp != NULL); printList(VariablesToEliminate, order_fp); fclose(order_fp); #endif if(exit_after_order_finding) { return; } #ifdef DEBUG_SKOLEM cout << "number_of_factors = " << number_of_factors << endl; cout << "number_of_vars_to_elim = " << number_of_vars_to_elim << endl; #endif // create the var_name_to_var_index_map and var_index_to_var_name_map int var_index = 1; for(list::iterator list_it = VariablesToEliminate.begin(); list_it != VariablesToEliminate.end(); list_it++) { insertIntoVarNameToVarIndexMap(var_name_to_var_index_map, *list_it, var_index); insertIntoVarIndexToVarNameMap(var_index_to_var_name_map, var_index, *list_it); #ifdef DEBUG_SKOLEM cout << "(" << *list_it << ", " << var_index << ") inserted into maps "<< endl; #endif var_index++; } if(enable_cegar) { conjunction_of_factors = createAnd(Factors, pub_aig_manager); Aig_Obj_t* conjunction_of_factors_CO = Aig_ObjCreateCo( pub_aig_manager, conjunction_of_factors ); // to aviod // unwanted cleanup of conjunction_of_factors assert(conjunction_of_factors_CO != NULL); if(use_mu_based_scheme_in_cegar) { if(use_disjunction_of_bads_in_mu_based_scheme_in_cegar) { // Note that BadSets[1] = false Aig_Obj_t* bad_set_1 = createFalse(pub_aig_manager); assert(bad_set_1 != NULL); Aig_Obj_t* bad_set_1_CO = Aig_ObjCreateCo( pub_aig_manager, bad_set_1 ); // to aviod // unwanted cleanup of bad_set_1 assert(bad_set_1_CO != NULL); #ifdef DEBUG_SKOLEM cout << "\nbad_set_1 computed\n"; writeFormulaToFile(pub_aig_manager, bad_set_1, "bad_set", ".v", 1, cegar_iteration_number); #endif // Enter into matrix insertIntoOneDimensionalMatrix(BadSets, number_of_vars_to_elim, 1, bad_set_1, false); } else { // do nothing } } else { // Note that BadSets[1] = false Aig_Obj_t* bad_set_1 = createFalse(pub_aig_manager); assert(bad_set_1 != NULL); Aig_Obj_t* bad_set_1_CO = Aig_ObjCreateCo( pub_aig_manager, bad_set_1 ); // to aviod // unwanted cleanup of bad_set_1 assert(bad_set_1_CO != NULL); #ifdef DEBUG_SKOLEM cout << "\nbad_set_1 computed\n"; writeFormulaToFile(pub_aig_manager, bad_set_1, "bad_set", ".v", 1, cegar_iteration_number); #endif // Enter into matrix insertIntoOneDimensionalMatrix(BadSets, number_of_vars_to_elim, 1, bad_set_1, false); } } else if(perform_cofactor_based_quantifier_elimination_along_with_skolem_function_generation) { aig_bad_set = createFalse(pub_aig_manager); // AIG Manager API Call } else if(disable_factorization) { // do nothing } else // else { cout << "!enable_cegar and !perform_cofactor_based_quantifier_elimination_along_with_skolem_function_generation and !disable_factorization not supported with AIG Manager" << endl; assert(false); }// if...else ends here if(print_factor_graph) { if(false) { printFactorGraphAsData(Final_VariablesToEliminate_Set); } else { cout << "\nPrinting the factor graph in dot format\n"; printFactorGraph(Final_VariablesToEliminate_Set); } } if(exit_after_factor_graph_generation) { return; } if(enable_cegar && use_mu_based_scheme_with_optimizations_in_cegar && unify_code_for_mu_based_scheme_in_cegar) { if(use_bads_in_unified_cegar) { assert(use_cbzero_in_unified_cegar); use_bads_in_unified_cegar_aig = createTrue(pub_aig_manager); use_cbzero_in_unified_cegar_aig = createTrue(pub_aig_manager); } else { assert(!use_cbzero_in_unified_cegar); use_bads_in_unified_cegar_aig = createFalse(pub_aig_manager); use_cbzero_in_unified_cegar_aig = createFalse(pub_aig_manager); } Aig_Obj_t* use_bads_in_unified_cegar_aig_CO = Aig_ObjCreateCo(pub_aig_manager, use_bads_in_unified_cegar_aig); assert(use_bads_in_unified_cegar_aig_CO != NULL); Aig_Obj_t* use_cbzero_in_unified_cegar_aig_CO = Aig_ObjCreateCo(pub_aig_manager, use_cbzero_in_unified_cegar_aig); assert(use_cbzero_in_unified_cegar_aig_CO != NULL); if(use_assumptions_in_unified_cegar) { assumptions_flag = 1; } else { assumptions_flag = 0; } } #ifdef RECORD_KEEP string record_file; record_file = logfile_prefix; record_file += "skolem_function_generation_details.txt"; FILE* record_fp = fopen(record_file.c_str(), "a+"); assert(record_fp != NULL); fprintf(record_fp, "number of factors = %d\n", number_of_factors); fprintf(record_fp, "number of variables to eliminate = %d\n", number_of_vars_to_elim); // print details of original factors fprintf(record_fp, "number of variables = %d\n\n", original_support_size); fprintf(record_fp, "aig sizes of factors = "); unsigned long long int total_of_factor_sizes = 0; unsigned long long int total_of_abstracted_factor_sizes = 0; unsigned long long int total_of_factor_support_sizes = 0; unsigned long long int total_of_factor_varstoelim_sizes = 0; unsigned long long int total_of_skyline_sizes = 0; for(map::iterator original_factor_sizes_it = original_factor_sizes.begin(); original_factor_sizes_it != original_factor_sizes.end(); original_factor_sizes_it++) { fprintf(record_fp, "%d, ", original_factor_sizes_it->second); total_of_factor_sizes = total_of_factor_sizes + original_factor_sizes_it->second; if(max_factor_size == -1) { max_factor_size = original_factor_sizes_it->second; min_factor_size = original_factor_sizes_it->second; } else if(original_factor_sizes_it->second > max_factor_size) { max_factor_size = original_factor_sizes_it->second; } else if(original_factor_sizes_it->second < min_factor_size) { min_factor_size = original_factor_sizes_it->second; } } fprintf(record_fp, "\n\n"); /*fprintf(record_fp, "A_f = "); for(map::iterator abstracted_factor_sizes_it = abstracted_factor_sizes.begin(); abstracted_factor_sizes_it != abstracted_factor_sizes.end(); abstracted_factor_sizes_it++) { fprintf(record_fp, "%d, ", abstracted_factor_sizes_it->second); total_of_abstracted_factor_sizes = total_of_abstracted_factor_sizes + abstracted_factor_sizes_it->second; } fprintf(record_fp, "\n\n");*/ fprintf(record_fp, "variables in factors = "); for(map::iterator original_factor_support_sizes_it = original_factor_support_sizes.begin(); original_factor_support_sizes_it != original_factor_support_sizes.end(); original_factor_support_sizes_it++) { fprintf(record_fp, "%d, ", original_factor_support_sizes_it->second); total_of_factor_support_sizes = total_of_factor_support_sizes + original_factor_support_sizes_it->second; } fprintf(record_fp, "\n\n"); fprintf(record_fp, "variables to eliminate in factors = "); for(map::iterator original_factor_varstoelim_sizes_it = original_factor_varstoelim_sizes.begin(); original_factor_varstoelim_sizes_it != original_factor_varstoelim_sizes.end(); original_factor_varstoelim_sizes_it++) { fprintf(record_fp, "%d, ", original_factor_varstoelim_sizes_it->second); total_of_factor_varstoelim_sizes = total_of_factor_varstoelim_sizes + original_factor_varstoelim_sizes_it->second; if(max_factor_varstoelim_size == -1) { max_factor_varstoelim_size = original_factor_varstoelim_sizes_it->second; min_factor_varstoelim_size = original_factor_varstoelim_sizes_it->second; } else if(original_factor_varstoelim_sizes_it->second > max_factor_varstoelim_size) { max_factor_varstoelim_size = original_factor_varstoelim_sizes_it->second; } else if(original_factor_varstoelim_sizes_it->second < min_factor_varstoelim_size) { min_factor_varstoelim_size = original_factor_varstoelim_sizes_it->second; } } fprintf(record_fp, "\n\n"); number_of_compose_operations_for_variable = 0; ComposeTime = 0; number_of_boolean_operations_for_variable = 0; BooleanOpTime = 0; number_of_support_operations_for_variable = 0; if(enable_cegar) { if(use_mu_based_scheme_in_cegar) { #ifdef RECORD_KEEP fprintf(record_fp, "i: index of variable to be eliminated\n"); fprintf(record_fp, "v: name of variable to be eliminated\n"); fprintf(record_fp, "F_v: Number of factors with the variable to be eliminated\n"); fprintf(record_fp, "T_v: Time (in milliseconds) to generate the initial Skolem function for the variable\n"); fprintf(record_fp, "N_v: Size of the initial Skolem function for the variable\n"); fprintf(record_fp, "I_v: Indices of factors containing the variable\n"); fprintf(record_fp, "X_v: Sizes of factors containing the variable\n"); fprintf(record_fp, "Cb1_v: Sizes of elements in Cb1 of variable\n"); fprintf(record_fp, "Cb0_v: Sizes of elements in Cb0 of variable\n"); fprintf(record_fp, "\n\n"); fprintf(record_fp, "i\tv\tF_v\tT_v\tN_v\tI_v\tX_v\tCb1_v\tCb0_v\n\n"); #endif } else if(use_mu_based_scheme_with_optimizations_in_cegar) { #ifdef RECORD_KEEP fprintf(record_fp, "i: index of variable to be eliminated\n"); fprintf(record_fp, "v: name of variable to be eliminated\n"); fprintf(record_fp, "F_v: Number of factors with the variable to be eliminated\n"); fprintf(record_fp, "T_v: Time (in milliseconds) to generate the initial Skolem function for the variable\n"); fprintf(record_fp, "M_v: Size of the initial Skolem function for the variable before don't-care optimization\n"); fprintf(record_fp, "N_v: Size of the initial Skolem function for the variable after don't-care optimization\n"); fprintf(record_fp, "I_v: Indices of factors containing the variable\n"); fprintf(record_fp, "X_v: Sizes of factors containing the variable\n"); fprintf(record_fp, "Cb1_v: Sizes of elements in Cb1 of variable\n"); fprintf(record_fp, "Cb0_v: Sizes of elements in Cb0 of variable\n"); fprintf(record_fp, "B_v: Size of Bad of variable\n"); fprintf(record_fp, "\n\n"); fprintf(record_fp, "i\tv\tF_v\tT_v\tM_v\tN_v\tI_v\tX_v\tCb1_v\tCb0_v\tB_v\n\n"); #endif } else { #ifdef RECORD_KEEP fprintf(record_fp, "Details of initial abstraction generation\n\n"); fprintf(record_fp, "v\tF_v\tT_v\tN_v\tA_v\tG_v\tB_v\tB_{v+1}\tO_v\tS_v\n\n"); // more detailed output //fprintf(record_fp, "v\tF_v\tT_v\tN_v\tB_{v+1}\n\n"); #endif } } else if(perform_cofactor_based_quantifier_elimination_along_with_skolem_function_generation) { if(use_bad_in_perform_cofactor_based_quantifier_elimination_along_with_skolem_function_generation) { #ifdef RECORD_KEEP fprintf(record_fp, "v\tF_v\tT_v\tN_v\tF_v\tOB_v\tB_v\tcmp_v\tcmp_T\tS_T\tF_T\tOB_T\tB_T\tN_T\n\n"); #endif } else if(compute_quantifier_eliminated_result_using_skolem_functions && use_interpolant_as_skolem_function) { #ifdef RECORD_KEEP fprintf(record_fp, "i: index of variable to be eliminated\n"); fprintf(record_fp, "v: name of variable to be eliminated\n"); fprintf(record_fp, "F_v: Number of factors with the variable to be eliminated\n"); fprintf(record_fp, "T_v: Time (in milliseconds) to eliminate the variable\n"); fprintf(record_fp, "N_v: Size of the skolem function psi_i = interpolant between alpha_i and beta_i\n"); fprintf(record_fp, "Q_v: Size of the quantified result q_i = conjunction of factors with variable substituted by skolem function\n"); fprintf(record_fp, "A_v: Size of alpha_i\n"); fprintf(record_fp, "B_v: Size of beta_i\n"); fprintf(record_fp, "I_T: Time consumed in computing interpolant between alpha_i and beta_i\n"); fprintf(record_fp, "cmp_v: Number of composes in elimination of the variable\n"); fprintf(record_fp, "cmp_T: Time consumed in composes in elimination of the variable\n"); fprintf(record_fp, "B_v: Number of boolean operations in elimination of the variable\n"); fprintf(record_fp, "B_T: Time consumed in boolean operations in elimination of the variable\n"); fprintf(record_fp, "S_v: Number of support operations in elimination of the variable\n"); fprintf(record_fp, "S_T: Time consumed in support operations in elimination of the variable\n"); fprintf(record_fp, "I_v: Indices of factors containing the variable to be eliminated\n"); fprintf(record_fp, "X_v: Sizes of factors containing the variable to be eliminated\n"); fprintf(record_fp, "\n\n"); fprintf(record_fp, "i\tv\tF_v\tT_v\tN_v\tA_v\tB_v\tI_T\tQ_v\tcmp_v\tcmp_T\tB_v\tB_T\tS_v\tS_T\tI_v\tX_v\n\n"); #endif } else { #ifdef RECORD_KEEP fprintf(record_fp, "i: index of variable to be eliminated\n"); fprintf(record_fp, "v: name of variable to be eliminated\n"); fprintf(record_fp, "F_v: Number of factors with the variable to be eliminated\n"); fprintf(record_fp, "T_v: Time (in milliseconds) to eliminate the variable\n"); fprintf(record_fp, "N_v: Size of the skolem function psi_i = conjunction of co-factor-1's of factors\n"); fprintf(record_fp, "Q_v: Size of the quantified result q_i = (conjunction of co-factor-1's of factors) or (conjunction of co-factor-0's of factors)\n"); fprintf(record_fp, "cmp_v: Number of composes in elimination of the variable\n"); fprintf(record_fp, "cmp_T: Time consumed in composes in elimination of the variable\n"); fprintf(record_fp, "B_v: Number of boolean operations in elimination of the variable\n"); fprintf(record_fp, "B_T: Time consumed in boolean operations in elimination of the variable\n"); fprintf(record_fp, "S_v: Number of support operations in elimination of the variable\n"); fprintf(record_fp, "S_T: Time consumed in support operations in elimination of the variable\n"); fprintf(record_fp, "I_v: Indices of factors containing the variable to be eliminated\n"); fprintf(record_fp, "X_v: Sizes of factors containing the variable to be eliminated\n"); fprintf(record_fp, "\n\n"); fprintf(record_fp, "i\tv\tF_v\tT_v\tN_v\tQ_v\tcmp_v\tcmp_T\tB_v\tB_T\tS_v\tS_T\tI_v\tX_v\n\n"); #endif } } else if(disable_factorization) { #ifdef RECORD_KEEP fprintf(record_fp, "i: index of variable to be eliminated\n"); fprintf(record_fp, "v: name of variable to be eliminated\n"); fprintf(record_fp, "F_v: Number of factors with the variable to be eliminated\n"); fprintf(record_fp, "T_v: Time (in milliseconds) to eliminate the variable\n"); fprintf(record_fp, "N_v: Size of the skolem function; psi_i = interpolant between alpha_i and beta_i if interpolation_based_skolem_function_genertaion is enabled, otherwise psi_i = conjunction of co-factor-1's of factors\n"); fprintf(record_fp, "A_v: Size of alpha_i \n"); fprintf(record_fp, "B_v: Size of beta_i \n"); fprintf(record_fp, "I_T: Time consumed in computing interpolant between alpha_i and beta_i\n"); fprintf(record_fp, "C_v: Number of composes in elimination of the variable\n"); fprintf(record_fp, "C_T: Time consumed in composes in elimination of the variable\n"); fprintf(record_fp, "S_T: Time consumed in support operations in elimination of the variable\n"); fprintf(record_fp, "F_v: Indices of factors containing the variable to be eliminated\n"); fprintf(record_fp, "X_v: Sizes of factors containing the variable to be eliminated\n"); fprintf(record_fp, "\n\n"); fprintf(record_fp, "i\tv\tF_v\tT_v\tN_v\tA_v\tB_v\tI_T\tC_v\tC_T\tS_T\tF_v\tX_v\n\n"); #endif } else { cout << "!perform_cofactor_based_quantifier_elimination_along_with_skolem_function_generation and !disable_factorization not supported with AIG Manager" << endl; assert(false); } fclose(record_fp); string plot_file; plot_file = logfile_prefix; plot_file += "skolem_function_generation_details_to_plot.txt"; FILE* plot_fp = fopen(plot_file.c_str(), "a+"); assert(plot_fp != NULL); fprintf(plot_fp, "\n%s\t%s\t%s", benchmark_type.c_str(), benchmark_name.c_str(), machine.c_str()); string algorithm_string; if(enable_cegar) { algorithm_string = "cegar"; if(use_mu_based_scheme_with_optimizations_in_cegar && unify_code_for_mu_based_scheme_in_cegar) { if(use_assumptions_in_unified_cegar) { algorithm_string += "_optimized"; } else { algorithm_string += "_unoptimized"; } if(use_bads_in_unified_cegar) { algorithm_string += "_withbads"; } else { algorithm_string += "_withnegf"; } if(accumulate_formulae_in_cbzero_in_cegar) { algorithm_string += "_withaccumulate"; } else { algorithm_string += "_noaccumulate"; } } } else { algorithm_string = "monolithic"; if(compute_quantifier_eliminated_result_using_skolem_functions) { algorithm_string += "_compositionqe"; } else { algorithm_string += "_bddlikeqe"; } if(use_interpolant_as_skolem_function) { algorithm_string += "_interpolantskf"; } else { algorithm_string += "_cofactorskf"; } if(skolem_function_type_in_jiang == "cofactorone") { algorithm_string += "_cofactorone"; } else { algorithm_string += "_bothcofactors"; } } fprintf(plot_fp, "\t%s", algorithm_string.c_str()); fprintf(plot_fp, "\t%d\t%d\t%d", number_of_factors, number_of_vars_to_elim, original_support_size); if(conjunction_of_factors == NULL) { conjunction_of_factors = createAnd(Factors, pub_aig_manager); // AIG Manager API Call } assert(conjunction_of_factors != NULL); size_of_conjunction_of_factors = computeSize(conjunction_of_factors, pub_aig_manager); // AIG Manager API Call fprintf(plot_fp, "\t%d", size_of_conjunction_of_factors); float avg_of_factor_sizes = (float)total_of_factor_sizes/(float)number_of_factors; float avg_of_abstracted_factor_sizes = (float)total_of_abstracted_factor_sizes/(float)number_of_factors; float avg_of_factor_support_sizes = (float)total_of_factor_support_sizes/(float)number_of_factors; float avg_of_factor_varstoelim_sizes = (float)total_of_factor_varstoelim_sizes/(float)number_of_factors; float avg_of_skyline_sizes = (float)total_of_skyline_sizes/(float)number_of_vars_to_elim; if(order_of_elimination_of_variables == 2 || order_of_elimination_of_variables == 4) { fprintf(plot_fp, "\t%f\t%f\t%f", avg_of_factor_sizes, avg_of_factor_support_sizes, avg_of_factor_varstoelim_sizes); } else { //fprintf(plot_fp, "\t%f\t%f\t%f\t%f\t%f", avg_of_factor_sizes, avg_of_abstracted_factor_sizes, avg_of_factor_support_sizes, avg_of_factor_varstoelim_sizes, avg_of_skyline_sizes); fprintf(plot_fp, "\t%f\t%f\t%f", avg_of_factor_sizes, avg_of_factor_support_sizes, avg_of_factor_varstoelim_sizes); } fprintf(plot_fp, "\t%d\t%d\t%d\t%d", max_factor_size, min_factor_size, max_factor_varstoelim_size, min_factor_varstoelim_size); fclose(plot_fp); #endif } void AIGBasedSkolem::factorizedSkolemFunctionGenerator(set &Factors, list &VariablesToEliminate) { struct timeval cegar_step_start_ms, cegar_step_finish_ms; gettimeofday (&cegar_step_start_ms, NULL); #ifdef DETAILED_RECORD_KEEP unsigned long long int step_ms; struct timeval step_start_ms, step_finish_ms; gettimeofday (&step_start_ms, NULL); #endif initializeFactorizedSkolemFunctionGenerator(Factors, VariablesToEliminate); #ifdef DETAILED_RECORD_KEEP gettimeofday (&step_finish_ms, NULL); step_ms = step_finish_ms.tv_sec * 1000 + step_finish_ms.tv_usec / 1000; step_ms -= step_start_ms.tv_sec * 1000 + step_start_ms.tv_usec / 1000; cout << "\ninitializeFactorizedSkolemFunctionGenerator finished in " << step_ms << " milliseconds\n"; total_time_in_generator_initialization = step_ms; #endif size_computation_time_in_initialization = total_time_in_compute_size; total_time_in_generator_initialization = total_time_in_generator_initialization - size_computation_time_in_initialization; cout << "\n#factors = " << number_of_factors << "\t#variables_to_eliminate = " << number_of_vars_to_elim << endl; if(exit_after_order_finding || exit_after_factor_graph_generation) { return; } if(enable_cegar && use_mu_based_scheme_with_optimizations_in_cegar) { assert(perform_cofactor_based_quantifier_elimination_along_with_skolem_function_generation); // Generate initial Skolem functions, bad sets, cannot-be-1 and cannot-be-0 sets for(int var_to_elim_index = 1; var_to_elim_index <= number_of_vars_to_elim; var_to_elim_index++) { if(checkTimeOut()) // check for time-out { cout << "\nWarning!!Time-out inside the function AIGBasedSkolem::factorizedSkolemFunctionGenerator\n"; timed_out = true; // timed_out flag set return; } if(maximum_index_to_eliminate != -1) // to stop computation in between { if(var_to_elim_index > maximum_index_to_eliminate) { cout << "\nLet us stop here...\n"; return; } } #ifdef DEBUG_SKOLEM cout << "\ncomputing initial Skolem functions, bad sets, cannot-be-1 and cannot-be-0 sets of x_" << var_to_elim_index << endl; #endif #ifdef PRINT_VERY_DETAILED_RECORDS_ON_SCREEN cout << "\ncomputing initial Skolem functions, bad sets, cannot-be-1 and cannot-be-0 sets of x_" << var_to_elim_index << endl; #endif #ifdef RECORD_KEEP unsigned long long int duration_ms; struct timeval start_ms, finish_ms; gettimeofday (&start_ms, NULL); #endif #ifdef DETAILED_RECORD_KEEP gettimeofday (&step_start_ms, NULL); #endif findFactorsWithVariable(var_to_elim_index);// find the set of factors containing the variable if(checkTimeOut()) // check for time-out { cout << "\nWarning!!Time-out inside the function AIGBasedSkolem::factorizedSkolemFunctionGenerator\n"; timed_out = true; // timed_out flag set return; } #ifdef DETAILED_RECORD_KEEP gettimeofday (&step_finish_ms, NULL); step_ms = step_finish_ms.tv_sec * 1000 + step_finish_ms.tv_usec / 1000; step_ms -= step_start_ms.tv_sec * 1000 + step_start_ms.tv_usec / 1000; cout << "\nfindFactorsWithVariable finished in " << step_ms << " milliseconds\n"; cout << "\nnumber of factors containing the variable = " << FactorsWithVariable.size() << endl; NumberOfFactors = FactorsWithVariable.size(); FactorFindingTime = step_ms; #endif #ifdef DETAILED_RECORD_KEEP gettimeofday (&step_start_ms, NULL); #endif Aig_Obj_t* skolem_function = computeInitialSkolemFunctionsBadSetsAndCannotBeSets(var_to_elim_index); if(checkTimeOut()) // check for time-out { cout << "\nWarning!!Time-out inside the function AIGBasedSkolem::computeInitialSkolemFunctionsBadSetsAndCannotBeSets\n"; timed_out = true; // timed_out flag set return; } assert(skolem_function != NULL); #ifdef DETAILED_RECORD_KEEP gettimeofday (&step_finish_ms, NULL); step_ms = step_finish_ms.tv_sec * 1000 + step_finish_ms.tv_usec / 1000; step_ms -= step_start_ms.tv_sec * 1000 + step_start_ms.tv_usec / 1000; cout << "\ncomputeInitialSkolemFunctionsBadSetsAndCannotBeSets finished in " << step_ms << " milliseconds\n"; #endif #ifdef DETAILED_RECORD_KEEP gettimeofday (&step_start_ms, NULL); #endif if(var_to_elim_index != number_of_vars_to_elim) // We need to update the factor matrix { #ifdef DEBUG_SKOLEM cout << "\nupdating factors\n"; #endif updateFactorsWithoutComposition(var_to_elim_index); } if(checkTimeOut()) // check for time-out { cout << "\nWarning!!Time-out inside the function AIGBasedSkolem::factorizedSkolemFunctionGenerator\n"; timed_out = true; // timed_out flag set return; } #ifdef DETAILED_RECORD_KEEP gettimeofday (&step_finish_ms, NULL); step_ms = step_finish_ms.tv_sec * 1000 + step_finish_ms.tv_usec / 1000; step_ms -= step_start_ms.tv_sec * 1000 + step_start_ms.tv_usec / 1000; cout << "\nupdateFactors finished in " << step_ms << " milliseconds\n"; NextFactorGenTime = step_ms; #endif #ifdef DEBUG_SKOLEM cout << "\nclearing variable-specific data-structures\n"; #endif #ifdef DETAILED_RECORD_KEEP gettimeofday (&step_start_ms, NULL); #endif clearVariableSpecificDataStructures(); #ifdef DETAILED_RECORD_KEEP gettimeofday (&step_finish_ms, NULL); step_ms = step_finish_ms.tv_sec * 1000 + step_finish_ms.tv_usec / 1000; step_ms -= step_start_ms.tv_sec * 1000 + step_start_ms.tv_usec / 1000; cout << "\nclearVariableSpecificDataStructures finished in " << step_ms << " milliseconds\n"; #endif #ifdef RECORD_KEEP gettimeofday (&finish_ms, NULL); duration_ms = finish_ms.tv_sec * 1000 + finish_ms.tv_usec / 1000; duration_ms -= start_ms.tv_sec * 1000 + start_ms.tv_usec / 1000; SkolemFunctionGenTime = duration_ms; SkolemFunctionSize = computeSize(skolem_function, pub_aig_manager); // AIG Manager API Call #endif string var_to_elim = searchVarIndexToVarNameMap(var_index_to_var_name_map, var_to_elim_index); cout << "\nabstract skolem_function_" << var_to_elim_index << ", i.e., abstract skolem function for " << var_to_elim << " computed\n"; #ifdef RECORD_KEEP string record_file; record_file = logfile_prefix; record_file += "skolem_function_generation_details.txt"; FILE* record_fp = fopen(record_file.c_str(), "a+"); assert(record_fp != NULL); total_of_skyline_sizes_in_least_cost_ordering = 0; sum_of_number_of_factors_containing_variable = sum_of_number_of_factors_containing_variable + NumberOfFactors; //sum_of_skolem_function_sizes = 0; // we will find this before reverse-substitution total_number_of_compose_operations = total_number_of_compose_operations + number_of_compose_operations_for_variable; total_time_in_compose_operations = total_time_in_compose_operations + ComposeTime; total_time_in_alpha_combined = total_time_in_alpha_combined + AlphaCombGenTime; total_time_in_delta_part = total_time_in_delta_part + DeltaPartGenTime; total_time_in_delta_combined = total_time_in_delta_combined + DeltaCombGenTime; total_time_in_next_factor = total_time_in_next_factor + NextFactorGenTime; total_time_in_correction_part = 0; number_of_variables_eliminated = var_to_elim_index; sum_of_numbers_of_affecting_factors = 0; //fprintf(record_fp, "%s\t%d\t%llu\t%d\t%d\t", var_to_elim.c_str(), NumberOfFactors, SkolemFunctionGenTime, SkolemFunctionSize, AlphaPartSize); // more detailed output fprintf(record_fp, "%d\t%s\t%d\t%llu\t%d\t%d\t", var_to_elim_index, var_to_elim.c_str(), NumberOfFactors, SkolemFunctionGenTime, InitialSkolemFunctionSizeBeforeOptimization, SkolemFunctionSize); if(print_factor_graph) { string fg_file_name = benchmark_name_without_extension; if(disable_factorization || disable_factorization_inside_factorized_code) { fg_file_name += "_monolithic"; } else { fg_file_name += "_factorized"; } fg_file_name += "_factor_graph.dat"; FILE* fg_fp = fopen(fg_file_name.c_str(), "a+"); assert(fg_fp != NULL); for(list::iterator affect_it = FactorsAffectingSkolemFunction.begin(); affect_it != FactorsAffectingSkolemFunction.end(); affect_it++) { fprintf(fg_fp, "%d\t%d\n", *affect_it, var_to_elim_index); } fclose(fg_fp); } for(set::iterator factor_it = PreviousFactorsWithVariable.begin(); factor_it != PreviousFactorsWithVariable.end(); factor_it++) { fprintf(record_fp, "%d,", *factor_it); } fprintf(record_fp, "\t"); PreviousFactorsWithVariable.clear(); for(list::iterator size_it = sizes_of_factors_with_variable.begin(); size_it != sizes_of_factors_with_variable.end(); size_it++) { fprintf(record_fp, "%d,", *size_it); } fprintf(record_fp, "\t"); sizes_of_factors_with_variable.clear(); for(list::iterator size_it = sizes_of_cannot_be_one_elements_of_variable.begin(); size_it != sizes_of_cannot_be_one_elements_of_variable.end(); size_it++) { fprintf(record_fp, "%d,", *size_it); } fprintf(record_fp, "\t"); sizes_of_cannot_be_one_elements_of_variable.clear(); for(list::iterator size_it = sizes_of_cannot_be_zero_elements_of_variable.begin(); size_it != sizes_of_cannot_be_zero_elements_of_variable.end(); size_it++) { fprintf(record_fp, "%d,", *size_it); } fprintf(record_fp, "\t"); sizes_of_cannot_be_zero_elements_of_variable.clear(); fprintf(record_fp, "%d\t", CorrectionPartSize); fprintf(record_fp, "\n\n"); number_of_compose_operations_for_variable = 0; ComposeTime = 0; fclose(record_fp); #endif }//for ends here gettimeofday (&cegar_step_finish_ms, NULL); total_time_in_initial_abstraction_generation_in_cegar = cegar_step_finish_ms.tv_sec * 1000 + cegar_step_finish_ms.tv_usec / 1000; total_time_in_initial_abstraction_generation_in_cegar -= cegar_step_start_ms.tv_sec * 1000 + cegar_step_start_ms.tv_usec / 1000; size_computation_time_in_initial_abstraction_generation_in_cegar = total_time_in_compute_size - size_computation_time_in_initialization; total_time_in_initial_abstraction_generation_in_cegar = total_time_in_initial_abstraction_generation_in_cegar - size_computation_time_in_initial_abstraction_generation_in_cegar; // We have the initial abstract skolem functions and cannot-be sets here #ifdef DEBUG_CEGAR showCannotBeSets(); cout << "\nWe have the initial abstract skolem functions, bad sets, and cannot-be sets, starting CEGAR\n\n"; #endif #ifdef RECORD_KEEP string record_file; record_file = logfile_prefix; record_file += "skolem_function_generation_details.txt"; FILE* record_fp = fopen(record_file.c_str(), "a+"); assert(record_fp != NULL); fprintf(record_fp, "\nDetails of CEGAR\n"); assert(size_of_conjunction_of_factors != 0); fprintf(record_fp, "\nSize of F(X, Y) = %d\n\nIteration number\tIndex of the variable being refined\tTime details\tRefinement steps\n\nTime details: time to check satisfiability of exactness condition (time spent in cnf generation, time spent in simplification) (size of formula)\n\nRefinement steps: (x@origin, number of selected elements in Cb1_origin that are true + number of selected elements in Cb0_origin that are true, size of initial mu) (x@location=value, size of new element added to Cb1/Cb0_location, number of selected elements in Cb1/Cb0_location that are true, size of disjunction of selected elements in Cb1/Cb0_location that are true, size of changed mu, size of changed Skolem function before don't care optimization, size of changed Skolem function after don't care optimization, size of component of the new element added to Cb1/Cb0_location from refinement-from-bottom, number of variables avoided through generalization in refinement-from-bottom)...", size_of_conjunction_of_factors); fclose(record_fp); #endif // CEGAR starting here gettimeofday (&cegar_step_start_ms, NULL); cout << "\nInitializing CEGAR\n"; if(unify_code_for_mu_based_scheme_in_cegar && use_incremental_sat_solving_in_mu_based_scheme_with_optimizations_in_cegar) { initializeCEGAR_using_ABC(); cout << "\nCEGAR initialized\n"; pSat_for_exactness_check = sat_solver_new(); int correction_index = number_of_vars_to_elim; cegar_iteration_for_correction_index = 0; map Model_of_ExactnessCheck; map Refinement_Hint_Of_CannotBe_One_To_Eliminate_This_CEX; map Refinement_Hint_Of_CannotBe_Zero_To_Eliminate_This_CEX; bool skolem_function_is_exact; while(correction_index >= 1) { #ifdef DEBUG_SKOLEM cout << "\nCorrecting Skolem function for x_" << correction_index << endl; #endif if(checkTimeOut()) // check for time-out { cout << "\nWarning!!Time-out inside the function AIGBasedSkolem::factorizedSkolemFunctionGenerator\n"; timed_out = true; // timed_out flag set return; } #ifdef RECORD_KEEP record_fp = fopen(record_file.c_str(), "a+"); assert(record_fp != NULL); fprintf(record_fp, "\n\n%d\t%d", cegar_iteration_number, correction_index); fclose(record_fp); #endif Model_of_ExactnessCheck.clear(); skolem_function_is_exact = checkIfSkolemFunctionAtGivenIndexIsExact_using_Mu_Based_Scheme_With_Optimizations_With_Unified_Code_And_Incremental_Solving(correction_index, Model_of_ExactnessCheck, Refinement_Hint_Of_CannotBe_One_To_Eliminate_This_CEX, Refinement_Hint_Of_CannotBe_Zero_To_Eliminate_This_CEX, VariablesToEliminate); cout << "\ncegar_iteration_number = " << cegar_iteration_number << ", " << "\tcegar_iteration_for_correction_index = " << cegar_iteration_for_correction_index << "\tcorrection_index = " << correction_index << "\tassumptions_flag = " << assumptions_flag << " finished\n"; #ifdef DEBUG_SKOLEM cout << "\nPress any key to continue..."; char c = getchar(); #endif if(allow_intermediate_generic_sat_calls) // generic sat calls possible in between specific calls { if(skolem_function_is_exact) { if(assumptions_flag == 0 || assumptions_flag == 2)// no assumptions; skolem functions exact { #ifdef DEBUG_SKOLEM cout << "\nAll skolem functions are exact\n"; #endif break; } else if(assumptions_flag == 1)// with assumptions; this skolem function is exact // let's do a generic check { #ifdef DEBUG_SKOLEM cout << "\nSkolem function at location " << correction_index << " is exact. Let's do a generic check\n"; #endif assumptions_flag = 2; cegar_iteration_number++; cegar_iteration_for_correction_index++; } } else { if(assumptions_flag == 0) { #ifdef DEBUG_SKOLEM cout << "\nAll skolem functions are NOT exact\n"; #endif cegar_iteration_number++; cegar_iteration_for_correction_index++; } else if(assumptions_flag == 1) { #ifdef DEBUG_SKOLEM cout << "\nSkolem function at location " << correction_index << " is INEXACT\n"; #endif cegar_iteration_number++; cegar_iteration_for_correction_index++; } else if(assumptions_flag == 2) { #ifdef DEBUG_SKOLEM cout << "\nGeneric check fails; Let's go back to specific check for Skolem function at location " << correction_index-1 << " \n"; #endif assumptions_flag = 1; cegar_iteration_number++; correction_index--; cegar_iteration_for_correction_index = 0; } } } else { if(skolem_function_is_exact) { if(assumptions_flag == 0)// no assumptions; skolem functions exact { #ifdef DEBUG_SKOLEM cout << "\nAll skolem functions are exact\n"; #endif break; } else if(assumptions_flag == 1)// with assumptions; this skolem function is exact { #ifdef DEBUG_SKOLEM cout << "\nSkolem function at location " << correction_index << " is exact\n"; #endif cegar_iteration_number++; correction_index--; cegar_iteration_for_correction_index = 0; } } else { if(assumptions_flag == 0) { #ifdef DEBUG_SKOLEM cout << "\nAll skolem functions are NOT exact\n"; #endif } else if(assumptions_flag == 1) { #ifdef DEBUG_SKOLEM cout << "\nSkolem function at location " << correction_index << " is INEXACT\n"; #endif } cegar_iteration_number++; cegar_iteration_for_correction_index++; } } if(checkTimeOut()) // check for time-out { cout << "\nWarning!!Time-out inside the function AIGBasedSkolem::factorizedSkolemFunctionGenerator\n"; timed_out = true; // timed_out flag set return; } Refinement_Hint_Of_CannotBe_One_To_Eliminate_This_CEX.clear(); Refinement_Hint_Of_CannotBe_Zero_To_Eliminate_This_CEX.clear(); if(!skolem_function_is_exact) { // from the model of exactness check, obtain the refinement hint to // eliminate this counterexample refineSkolemFunctions_using_Mu_Based_Scheme_With_Optimizations(correction_index, Model_of_ExactnessCheck, Refinement_Hint_Of_CannotBe_One_To_Eliminate_This_CEX, Refinement_Hint_Of_CannotBe_Zero_To_Eliminate_This_CEX); } }//while(correction_index >= 1) ends here sat_solver_delete(pSat_for_exactness_check); } else if(use_incremental_sat_solving_in_mu_based_scheme_with_optimizations_in_cegar) { initializeCEGAR_using_ABC(); cout << "\nCEGAR initialized\n"; pSat_for_exactness_check = sat_solver_new(); for(int correction_index = number_of_vars_to_elim; correction_index >= 1; correction_index--) { #ifdef DEBUG_SKOLEM cout << "\nCorrecting Skolem function for x_" << correction_index << endl; #endif if(checkTimeOut()) // check for time-out { cout << "\nWarning!!Time-out inside the function AIGBasedSkolem::factorizedSkolemFunctionGenerator\n"; timed_out = true; // timed_out flag set return; } cegar_iteration_for_correction_index = 0; #ifdef RECORD_KEEP record_fp = fopen(record_file.c_str(), "a+"); assert(record_fp != NULL); fprintf(record_fp, "\n\n%d\t%d", cegar_iteration_number, correction_index); fclose(record_fp); #endif map Model_of_ExactnessCheck; map Refinement_Hint_Of_CannotBe_One_To_Eliminate_This_CEX; map Refinement_Hint_Of_CannotBe_Zero_To_Eliminate_This_CEX; bool skolem_function_at_correction_index_is_exact; // refinement hints are empty in this call: we are checking if the skolem function at correction_index is exact // without any refinement hints skolem_function_at_correction_index_is_exact = checkIfSkolemFunctionAtGivenIndexIsExact_using_Mu_Based_Scheme_With_Optimizations_With_Incremental_Solving(correction_index, Model_of_ExactnessCheck, Refinement_Hint_Of_CannotBe_One_To_Eliminate_This_CEX, Refinement_Hint_Of_CannotBe_Zero_To_Eliminate_This_CEX, VariablesToEliminate); cout << "\ncegar_iteration_number = " << cegar_iteration_number << ", " << "\tcegar_iteration_for_correction_index = " << cegar_iteration_for_correction_index << " finished\n"; cegar_iteration_number++; cegar_iteration_for_correction_index++; #ifdef DEBUG_SKOLEM cout << "\nPress any key to continue..."; char c = getchar(); #endif while(!skolem_function_at_correction_index_is_exact) { cout << "\nSkolem function at location " << correction_index << " is inexact\n"; if(checkTimeOut()) // check for time-out { cout << "\nWarning!!Time-out inside the function AIGBasedSkolem::factorizedSkolemFunctionGenerator\n"; timed_out = true; // timed_out flag set return; } // from the model of exactness check, obtain the refinement hint to // eliminate this counterexample Refinement_Hint_Of_CannotBe_One_To_Eliminate_This_CEX.clear(); Refinement_Hint_Of_CannotBe_Zero_To_Eliminate_This_CEX.clear(); refineSkolemFunctions_using_Mu_Based_Scheme_With_Optimizations(correction_index, Model_of_ExactnessCheck, Refinement_Hint_Of_CannotBe_One_To_Eliminate_This_CEX, Refinement_Hint_Of_CannotBe_Zero_To_Eliminate_This_CEX); // check if the skolem function at correction_index is exact with the new refinement hint to // eliminate this counterexample Model_of_ExactnessCheck.clear(); #ifdef RECORD_KEEP record_fp = fopen(record_file.c_str(), "a+"); assert(record_fp != NULL); fprintf(record_fp, "\n\n%d\t%d", cegar_iteration_number, correction_index); fclose(record_fp); #endif // check if skolem function at correction_index is exact after adding the refinement hints skolem_function_at_correction_index_is_exact = checkIfSkolemFunctionAtGivenIndexIsExact_using_Mu_Based_Scheme_With_Optimizations_With_Incremental_Solving(correction_index, Model_of_ExactnessCheck, Refinement_Hint_Of_CannotBe_One_To_Eliminate_This_CEX, Refinement_Hint_Of_CannotBe_Zero_To_Eliminate_This_CEX, VariablesToEliminate); cout << "\ncegar_iteration_number = " << cegar_iteration_number << ", " << "\tcegar_iteration_for_correction_index = " << cegar_iteration_for_correction_index << " finished\n"; cegar_iteration_number++; cegar_iteration_for_correction_index++; #ifdef DEBUG_SKOLEM cout << "\nPress any key to continue..."; char c = getchar(); #endif }//while(!skolem_function_at_correction_index_is_exact) ends here cout << "\nSkolem function at location " << correction_index << " is exact\n"; }//for each correction_index ends here sat_solver_delete(pSat_for_exactness_check); } else { initializeCEGAR_using_ABC();// B_1, ..., B_n are created inside this function cout << "\nCEGAR initialized\n"; if(use_refinement_from_bottom_in_mu_based_scheme_with_optimizations_in_cegar && use_incremental_solving_for_generalization_in_mu_based_scheme_with_optimizations_in_cegar) { pSat_for_generalization_check = sat_solver_new(); // The only thing this sat solver has // is the set of clauses for conjunction_of_factors; hence it remains unchanged } for(int correction_index = number_of_vars_to_elim; correction_index >= 1; correction_index--) { #ifdef DEBUG_SKOLEM cout << "\nCorrecting Skolem function for x_" << correction_index << endl; #endif if(checkTimeOut()) // check for time-out { cout << "\nWarning!!Time-out inside the function AIGBasedSkolem::factorizedSkolemFunctionGenerator\n"; timed_out = true; // timed_out flag set return; } cegar_iteration_for_correction_index = 0; pSat_for_exactness_check = sat_solver_new(); #ifdef DEBUG_CEGAR cout << "\nsolver pSat_for_exactness_check is recreated\n"; #endif #ifdef RECORD_KEEP record_fp = fopen(record_file.c_str(), "a+"); assert(record_fp != NULL); fprintf(record_fp, "\n\n%d\t%d", cegar_iteration_number, correction_index); fclose(record_fp); #endif map Model_of_ExactnessCheck; map Refinement_Hint_Of_CannotBe_One_To_Eliminate_This_CEX; map Refinement_Hint_Of_CannotBe_Zero_To_Eliminate_This_CEX; bool skolem_function_at_correction_index_is_exact; // check if skolem function at correction_index is exact after adding the refinement hints // refinement hints are empty in this call: we are checking if the skolem function at correction_index is exact // without any refinement hints skolem_function_at_correction_index_is_exact = checkIfSkolemFunctionAtGivenIndexIsExact_using_Mu_Based_Scheme_With_Optimizations(correction_index, Model_of_ExactnessCheck, Refinement_Hint_Of_CannotBe_One_To_Eliminate_This_CEX, Refinement_Hint_Of_CannotBe_Zero_To_Eliminate_This_CEX, VariablesToEliminate); cout << "\ncegar_iteration_number = " << cegar_iteration_number << ", " << "\tcegar_iteration_for_correction_index = " << cegar_iteration_for_correction_index << " finished\n"; cegar_iteration_number++; cegar_iteration_for_correction_index++; #ifdef DEBUG_SKOLEM cout << "\nPress any key to continue..."; char c = getchar(); #endif while(!skolem_function_at_correction_index_is_exact) { cout << "\nSkolem function at location " << correction_index << " is inexact\n"; if(checkTimeOut()) // check for time-out { cout << "\nWarning!!Time-out inside the function AIGBasedSkolem::factorizedSkolemFunctionGenerator\n"; timed_out = true; // timed_out flag set return; } // from the model of exactness check, obtain the refinement hint to // eliminate this counterexample Refinement_Hint_Of_CannotBe_One_To_Eliminate_This_CEX.clear(); Refinement_Hint_Of_CannotBe_Zero_To_Eliminate_This_CEX.clear(); refineSkolemFunctions_using_Mu_Based_Scheme_With_Optimizations(correction_index, Model_of_ExactnessCheck, Refinement_Hint_Of_CannotBe_One_To_Eliminate_This_CEX, Refinement_Hint_Of_CannotBe_Zero_To_Eliminate_This_CEX); // check if the skolem function at correction_index is exact with the new refinement hint to // eliminate this counterexample Model_of_ExactnessCheck.clear(); #ifdef RECORD_KEEP record_fp = fopen(record_file.c_str(), "a+"); assert(record_fp != NULL); fprintf(record_fp, "\n\n%d\t%d", cegar_iteration_number, correction_index); fclose(record_fp); #endif // check if skolem function at correction_index is exact after adding the refinement hints skolem_function_at_correction_index_is_exact = checkIfSkolemFunctionAtGivenIndexIsExact_using_Mu_Based_Scheme_With_Optimizations(correction_index, Model_of_ExactnessCheck, Refinement_Hint_Of_CannotBe_One_To_Eliminate_This_CEX, Refinement_Hint_Of_CannotBe_Zero_To_Eliminate_This_CEX, VariablesToEliminate); cout << "\ncegar_iteration_number = " << cegar_iteration_number << ", " << "\tcegar_iteration_for_correction_index = " << cegar_iteration_for_correction_index << " finished\n"; cegar_iteration_number++; cegar_iteration_for_correction_index++; #ifdef DEBUG_SKOLEM cout << "\nPress any key to continue..."; char c = getchar(); #endif }//while(!skolem_function_at_correction_index_is_exact) ends here cout << "\nSkolem function at location " << correction_index << " is exact\n"; // clear the data structures for incremental solving sat_solver_delete(pSat_for_exactness_check); IncrementalLabelTableForExactnessCheck.clear(); IncrementalLabelCountForExactnessCheck = 1; Ci_name_to_Ci_label_mapForExactnessCheck.clear(); Ci_label_to_Ci_name_mapForExactnessCheck.clear(); D_variable_counter.clear(); S_variable_counter.clear(); Z_variable_counter.clear(); #ifdef DEBUG_CEGAR cout << "\ndata structures for incremental solving cleared\n"; #endif }//for each correction_index ends here if(use_refinement_from_bottom_in_mu_based_scheme_with_optimizations_in_cegar && use_incremental_solving_for_generalization_in_mu_based_scheme_with_optimizations_in_cegar) { sat_solver_delete(pSat_for_generalization_check); } }// else of if(use_incremental_sat_solving_in_mu_based_scheme_with_optimizations_in_cegar) ends here cout << "\nexact skolem functions are found\n"; // exact skolem functions are found gettimeofday (&cegar_step_finish_ms, NULL); total_time_in_cegar_loops_in_cegar = cegar_step_finish_ms.tv_sec * 1000 + cegar_step_finish_ms.tv_usec / 1000; total_time_in_cegar_loops_in_cegar -= cegar_step_start_ms.tv_sec * 1000 + cegar_step_start_ms.tv_usec / 1000; size_computation_time_in_cegar_loops_in_cegar = total_time_in_compute_size - size_computation_time_in_initialization - size_computation_time_in_initial_abstraction_generation_in_cegar; total_time_in_cegar_loops_in_cegar = total_time_in_cegar_loops_in_cegar - size_computation_time_in_cegar_loops_in_cegar; total_time_in_connection_substitution_in_cegar = 0; size_computation_time_in_connection_substitution_in_cegar = 0; }//if(enable_cegar && use_mu_based_scheme_with_optimizations_in_cegar) ends here else if(enable_cegar && use_mu_based_scheme_in_cegar) { assert(perform_cofactor_based_quantifier_elimination_along_with_skolem_function_generation); // Generate initial Skolem functions, cannot-be-1 and cannot-be-0 sets for(int var_to_elim_index = 1; var_to_elim_index <= number_of_vars_to_elim; var_to_elim_index++) { if(checkTimeOut()) // check for time-out { cout << "\nWarning!!Time-out inside the function AIGBasedSkolem::factorizedSkolemFunctionGenerator\n"; timed_out = true; // timed_out flag set return; } if(maximum_index_to_eliminate != -1) // to stop computation in between { if(var_to_elim_index > maximum_index_to_eliminate) { cout << "\nLet us stop here...\n"; return; } } #ifdef DEBUG_SKOLEM cout << "\ncomputing initial Skolem functions, cannot-be-1 and cannot-be-0 sets of x_" << var_to_elim_index << endl; #endif #ifdef PRINT_VERY_DETAILED_RECORDS_ON_SCREEN cout << "\ncomputing initial Skolem functions, cannot-be-1 and cannot-be-0 sets of x_" << var_to_elim_index << endl; #endif #ifdef RECORD_KEEP unsigned long long int duration_ms; struct timeval start_ms, finish_ms; gettimeofday (&start_ms, NULL); #endif #ifdef DETAILED_RECORD_KEEP gettimeofday (&step_start_ms, NULL); #endif findFactorsWithVariable(var_to_elim_index);// find the set of factors containing the variable if(checkTimeOut()) // check for time-out { cout << "\nWarning!!Time-out inside the function AIGBasedSkolem::factorizedSkolemFunctionGenerator\n"; timed_out = true; // timed_out flag set return; } #ifdef DETAILED_RECORD_KEEP gettimeofday (&step_finish_ms, NULL); step_ms = step_finish_ms.tv_sec * 1000 + step_finish_ms.tv_usec / 1000; step_ms -= step_start_ms.tv_sec * 1000 + step_start_ms.tv_usec / 1000; cout << "\nfindFactorsWithVariable finished in " << step_ms << " milliseconds\n"; cout << "\nnumber of factors containing the variable = " << FactorsWithVariable.size() << endl; NumberOfFactors = FactorsWithVariable.size(); FactorFindingTime = step_ms; #endif #ifdef DETAILED_RECORD_KEEP gettimeofday (&step_start_ms, NULL); #endif Aig_Obj_t* skolem_function = computeInitialSkolemFunctionsAndCannotBeSets(var_to_elim_index); if(checkTimeOut()) // check for time-out { cout << "\nWarning!!Time-out inside the function AIGBasedSkolem::computeInitialSkolemFunctionsAndCannotBeSets\n"; timed_out = true; // timed_out flag set return; } assert(skolem_function != NULL); #ifdef DETAILED_RECORD_KEEP gettimeofday (&step_finish_ms, NULL); step_ms = step_finish_ms.tv_sec * 1000 + step_finish_ms.tv_usec / 1000; step_ms -= step_start_ms.tv_sec * 1000 + step_start_ms.tv_usec / 1000; cout << "\ncomputeInitialSkolemFunctionsAndCannotBeSets finished in " << step_ms << " milliseconds\n"; #endif #ifdef DETAILED_RECORD_KEEP gettimeofday (&step_start_ms, NULL); #endif if(var_to_elim_index != number_of_vars_to_elim) // We need to update the factor matrix { #ifdef DEBUG_SKOLEM cout << "\nupdating factors\n"; #endif updateFactorsWithoutComposition(var_to_elim_index); } if(checkTimeOut()) // check for time-out { cout << "\nWarning!!Time-out inside the function AIGBasedSkolem::factorizedSkolemFunctionGenerator\n"; timed_out = true; // timed_out flag set return; } #ifdef DETAILED_RECORD_KEEP gettimeofday (&step_finish_ms, NULL); step_ms = step_finish_ms.tv_sec * 1000 + step_finish_ms.tv_usec / 1000; step_ms -= step_start_ms.tv_sec * 1000 + step_start_ms.tv_usec / 1000; cout << "\nupdateFactors finished in " << step_ms << " milliseconds\n"; NextFactorGenTime = step_ms; #endif #ifdef DEBUG_SKOLEM cout << "\nclearing variable-specific data-structures\n"; #endif #ifdef DETAILED_RECORD_KEEP gettimeofday (&step_start_ms, NULL); #endif clearVariableSpecificDataStructures(); #ifdef DETAILED_RECORD_KEEP gettimeofday (&step_finish_ms, NULL); step_ms = step_finish_ms.tv_sec * 1000 + step_finish_ms.tv_usec / 1000; step_ms -= step_start_ms.tv_sec * 1000 + step_start_ms.tv_usec / 1000; cout << "\nclearVariableSpecificDataStructures finished in " << step_ms << " milliseconds\n"; #endif #ifdef RECORD_KEEP gettimeofday (&finish_ms, NULL); duration_ms = finish_ms.tv_sec * 1000 + finish_ms.tv_usec / 1000; duration_ms -= start_ms.tv_sec * 1000 + start_ms.tv_usec / 1000; SkolemFunctionGenTime = duration_ms; SkolemFunctionSize = computeSize(skolem_function, pub_aig_manager); // AIG Manager API Call #endif string var_to_elim = searchVarIndexToVarNameMap(var_index_to_var_name_map, var_to_elim_index); cout << "\nabstract skolem_function_" << var_to_elim_index << ", i.e., abstract skolem function for " << var_to_elim << " computed\n"; #ifdef RECORD_KEEP string record_file; record_file = logfile_prefix; record_file += "skolem_function_generation_details.txt"; FILE* record_fp = fopen(record_file.c_str(), "a+"); assert(record_fp != NULL); total_of_skyline_sizes_in_least_cost_ordering = 0; sum_of_number_of_factors_containing_variable = sum_of_number_of_factors_containing_variable + NumberOfFactors; //sum_of_skolem_function_sizes = 0; // we will find this before reverse-substitution total_number_of_compose_operations = total_number_of_compose_operations + number_of_compose_operations_for_variable; total_time_in_compose_operations = total_time_in_compose_operations + ComposeTime; total_time_in_alpha_combined = total_time_in_alpha_combined + AlphaCombGenTime; total_time_in_delta_part = total_time_in_delta_part + DeltaPartGenTime; total_time_in_delta_combined = total_time_in_delta_combined + DeltaCombGenTime; total_time_in_next_factor = total_time_in_next_factor + NextFactorGenTime; total_time_in_correction_part = 0; number_of_variables_eliminated = var_to_elim_index; sum_of_numbers_of_affecting_factors = 0; //fprintf(record_fp, "%s\t%d\t%llu\t%d\t%d\t", var_to_elim.c_str(), NumberOfFactors, SkolemFunctionGenTime, SkolemFunctionSize, AlphaPartSize); // more detailed output fprintf(record_fp, "%d\t%s\t%d\t%llu\t%d\t", var_to_elim_index, var_to_elim.c_str(), NumberOfFactors, SkolemFunctionGenTime, SkolemFunctionSize); if(print_factor_graph) { string fg_file_name = benchmark_name_without_extension; if(disable_factorization || disable_factorization_inside_factorized_code) { fg_file_name += "_monolithic"; } else { fg_file_name += "_factorized"; } fg_file_name += "_factor_graph.dat"; FILE* fg_fp = fopen(fg_file_name.c_str(), "a+"); assert(fg_fp != NULL); for(list::iterator affect_it = FactorsAffectingSkolemFunction.begin(); affect_it != FactorsAffectingSkolemFunction.end(); affect_it++) { fprintf(fg_fp, "%d\t%d\n", *affect_it, var_to_elim_index); } fclose(fg_fp); } for(set::iterator factor_it = PreviousFactorsWithVariable.begin(); factor_it != PreviousFactorsWithVariable.end(); factor_it++) { fprintf(record_fp, "%d,", *factor_it); } fprintf(record_fp, "\t"); PreviousFactorsWithVariable.clear(); for(list::iterator size_it = sizes_of_factors_with_variable.begin(); size_it != sizes_of_factors_with_variable.end(); size_it++) { fprintf(record_fp, "%d,", *size_it); } fprintf(record_fp, "\t"); sizes_of_factors_with_variable.clear(); for(list::iterator size_it = sizes_of_cannot_be_one_elements_of_variable.begin(); size_it != sizes_of_cannot_be_one_elements_of_variable.end(); size_it++) { fprintf(record_fp, "%d,", *size_it); } fprintf(record_fp, "\t"); sizes_of_cannot_be_one_elements_of_variable.clear(); for(list::iterator size_it = sizes_of_cannot_be_zero_elements_of_variable.begin(); size_it != sizes_of_cannot_be_zero_elements_of_variable.end(); size_it++) { fprintf(record_fp, "%d,", *size_it); } fprintf(record_fp, "\t"); sizes_of_cannot_be_zero_elements_of_variable.clear(); fprintf(record_fp, "\n\n"); number_of_compose_operations_for_variable = 0; ComposeTime = 0; fclose(record_fp); #endif }//for ends here gettimeofday (&cegar_step_finish_ms, NULL); total_time_in_initial_abstraction_generation_in_cegar = cegar_step_finish_ms.tv_sec * 1000 + cegar_step_finish_ms.tv_usec / 1000; total_time_in_initial_abstraction_generation_in_cegar -= cegar_step_start_ms.tv_sec * 1000 + cegar_step_start_ms.tv_usec / 1000; size_computation_time_in_initial_abstraction_generation_in_cegar = total_time_in_compute_size - size_computation_time_in_initialization; total_time_in_initial_abstraction_generation_in_cegar = total_time_in_initial_abstraction_generation_in_cegar - size_computation_time_in_initial_abstraction_generation_in_cegar; // We have the initial abstract skolem functions and cannot-be sets here #ifdef DEBUG_CEGAR showCannotBeSets(); cout << "\nWe have the initial abstract skolem functions and cannot-be sets, starting CEGAR\n\n"; #endif #ifdef RECORD_KEEP string record_file; record_file = logfile_prefix; record_file += "skolem_function_generation_details.txt"; FILE* record_fp = fopen(record_file.c_str(), "a+"); assert(record_fp != NULL); fprintf(record_fp, "\nDetails of CEGAR\n"); assert(size_of_conjunction_of_factors != 0); fprintf(record_fp, "\nSize of F(X, Y) = %d\n\nIteration number\tRefinement steps\tTime details\n\nRefinement steps:(x@origin, number of elements in Cb1_origin that are true + number of elements in Cb0_origin that are true, size of initial mu) (x@location=value, size of new element added to Cb1/Cb0_location, number of elements in Cb1/Cb0_location that are true, size of disjunction of elements in Cb1/Cb0_location that are true, size of changed mu)...\nTime details: time to check satisfiability of exactness condition (time spent in cnf generation, time spent in simplification) (size of formula)", size_of_conjunction_of_factors); fprintf(record_fp, "\n\n%d", cegar_iteration_number); fclose(record_fp); #endif // CEGAR starting here gettimeofday (&cegar_step_start_ms, NULL); cout << "\nInitializing CEGAR\n"; initializeCEGAR_using_ABC();// F(X',Y) is created inside this function cout << "\nCEGAR initialized\n"; if(checkTimeOut()) // check for time-out { cout << "\nWarning!!Time-out inside the function AIGBasedSkolem::factorizedSkolemFunctionGenerator\n"; timed_out = true; // timed_out flag set return; } pSat_for_exactness_check = sat_solver_new(); #ifdef DEBUG_CEGAR cout << "\nsolver pSat_for_exactness_check is created\n"; #endif map Model_of_ExactnessCheck; map Refinement_Hint_Of_CannotBe_One_To_Eliminate_This_CEX; map Refinement_Hint_Of_CannotBe_Zero_To_Eliminate_This_CEX; // check if the initial abstract skolem functions are exact // Refinement_Hint_Of_... are just a place holders here bool skolem_functions_are_exact; skolem_functions_are_exact = checkIfSkolemFunctionsAreExact_using_Generic_Skolem_Functions(Model_of_ExactnessCheck, Refinement_Hint_Of_CannotBe_One_To_Eliminate_This_CEX, Refinement_Hint_Of_CannotBe_Zero_To_Eliminate_This_CEX, VariablesToEliminate); cout << "\ncegar_iteration_number = " << cegar_iteration_number << " finished\n"; #ifdef DEBUG_SKOLEM cout << "\nPress any key to continue..."; char c = getchar(); #endif while(!skolem_functions_are_exact) { cout << "\nskolem functions inexact\n"; if(checkTimeOut()) // check for time-out { cout << "\nWarning!!Time-out inside the function AIGBasedSkolem::factorizedSkolemFunctionGenerator\n"; timed_out = true; // timed_out flag set return; } cegar_iteration_number++; #ifdef RECORD_KEEP record_fp = fopen(record_file.c_str(), "a+"); assert(record_fp != NULL); fprintf(record_fp, "\n\n%d", cegar_iteration_number); fclose(record_fp); #endif // from the model of exactness check, obtain the refinement hint to // eliminate this counterexample Refinement_Hint_Of_CannotBe_One_To_Eliminate_This_CEX.clear(); Refinement_Hint_Of_CannotBe_Zero_To_Eliminate_This_CEX.clear(); refineSkolemFunctions_using_Generic_Skolem_Functions(Model_of_ExactnessCheck, Refinement_Hint_Of_CannotBe_One_To_Eliminate_This_CEX, Refinement_Hint_Of_CannotBe_Zero_To_Eliminate_This_CEX); // check if the skolem functions are exact with the new refinement hint to // eliminate this counterexample Model_of_ExactnessCheck.clear(); skolem_functions_are_exact = checkIfSkolemFunctionsAreExact_using_Generic_Skolem_Functions(Model_of_ExactnessCheck, Refinement_Hint_Of_CannotBe_One_To_Eliminate_This_CEX, Refinement_Hint_Of_CannotBe_Zero_To_Eliminate_This_CEX, VariablesToEliminate); // if exact, then skolem_functions_are_exact is true // else, we have the new model of exactness check cout << "\ncegar_iteration_number = " << cegar_iteration_number << " finished\n"; #ifdef DEBUG_SKOLEM cout << "\nPress any key to continue..."; c = getchar(); #endif } sat_solver_delete(pSat_for_exactness_check); #ifdef DEBUG_CEGAR cout << "\npSat_for_exactness_check is deleted\n"; #endif cout << "\nexact skolem functions are found\n"; // exact skolem functions are found gettimeofday (&cegar_step_finish_ms, NULL); total_time_in_cegar_loops_in_cegar = cegar_step_finish_ms.tv_sec * 1000 + cegar_step_finish_ms.tv_usec / 1000; total_time_in_cegar_loops_in_cegar -= cegar_step_start_ms.tv_sec * 1000 + cegar_step_start_ms.tv_usec / 1000; size_computation_time_in_cegar_loops_in_cegar = total_time_in_compute_size - size_computation_time_in_initialization - size_computation_time_in_initial_abstraction_generation_in_cegar; total_time_in_cegar_loops_in_cegar = total_time_in_cegar_loops_in_cegar - size_computation_time_in_cegar_loops_in_cegar; total_time_in_connection_substitution_in_cegar = 0; size_computation_time_in_connection_substitution_in_cegar = 0; }//if(enable_cegar && use_mu_based_scheme_in_cegar) ends here else if(enable_cegar) { assert(perform_cofactor_based_quantifier_elimination_along_with_skolem_function_generation); // Generate initial abstract SkolemFunctions and BadSets for(int var_to_elim_index = 1; var_to_elim_index <= number_of_vars_to_elim; var_to_elim_index++) { if(checkTimeOut()) // check for time-out { cout << "\nWarning!!Time-out inside the function AIGBasedSkolem::factorizedSkolemFunctionGenerator\n"; timed_out = true; // timed_out flag set return; } if(maximum_index_to_eliminate != -1) // to stop computation in between { if(var_to_elim_index > maximum_index_to_eliminate) { cout << "\nLet us stop here...\n"; return; } } #ifdef DEBUG_SKOLEM cout << "\ncomputing abstract skolem_function_" << var_to_elim_index << endl; #endif #ifdef PRINT_VERY_DETAILED_RECORDS_ON_SCREEN cout << "\ncomputing abstract skolem_function_" << var_to_elim_index << "\n"; #endif #ifdef RECORD_KEEP unsigned long long int duration_ms; struct timeval start_ms, finish_ms; gettimeofday (&start_ms, NULL); #endif #ifdef DETAILED_RECORD_KEEP gettimeofday (&step_start_ms, NULL); #endif findFactorsWithVariable(var_to_elim_index);// find the set of factors containing the variable if(checkTimeOut()) // check for time-out { cout << "\nWarning!!Time-out inside the function AIGBasedSkolem::factorizedSkolemFunctionGenerator\n"; timed_out = true; // timed_out flag set return; } #ifdef DETAILED_RECORD_KEEP gettimeofday (&step_finish_ms, NULL); step_ms = step_finish_ms.tv_sec * 1000 + step_finish_ms.tv_usec / 1000; step_ms -= step_start_ms.tv_sec * 1000 + step_start_ms.tv_usec / 1000; cout << "\nfindFactorsWithVariable finished in " << step_ms << " milliseconds\n"; cout << "\nnumber of factors containing the variable = " << FactorsWithVariable.size() << endl; FactorFindingTime = step_ms; #endif #ifdef DETAILED_RECORD_KEEP gettimeofday (&step_start_ms, NULL); #endif Aig_Obj_t* skolem_function = computeAbstractSkolemFunction(var_to_elim_index); if(checkTimeOut()) // check for time-out { cout << "\nWarning!!Time-out inside the function AIGBasedSkolem::factorizedSkolemFunctionGenerator\n"; timed_out = true; // timed_out flag set return; } assert(skolem_function != NULL); #ifdef DETAILED_RECORD_KEEP gettimeofday (&step_finish_ms, NULL); step_ms = step_finish_ms.tv_sec * 1000 + step_finish_ms.tv_usec / 1000; step_ms -= step_start_ms.tv_sec * 1000 + step_start_ms.tv_usec / 1000; cout << "\ncomputeAbstractSkolemFunction finished in " << step_ms << " milliseconds\n"; #endif // for debugging starts here //Aig_Obj_t* delta_disjunction_for_debug = computeDisjunctionOfDeltas(var_to_elim_index); //insertIntoOneDimensionalMatrix(DeltaDisjunctions, number_of_vars_to_elim, var_to_elim_index, delta_disjunction_for_debug, false); // for debugging ends here #ifdef DEBUG_SKOLEM //Aig_Obj_t* alpha_combined_or_gamma_combined_for_debug = computeAlphaCombinedOrGammaCombined(var_to_elim_index); //insertIntoOneDimensionalMatrix(AlphaOrGammaCombineds, number_of_vars_to_elim, var_to_elim_index, alpha_combined_or_gamma_combined_for_debug, false); //Aig_Obj_t* beta_combined_for_debug = computeBetaCombinedForDebugging(var_to_elim_index); //insertIntoOneDimensionalMatrix(BetaCombineds, number_of_vars_to_elim, var_to_elim_index, beta_combined_for_debug, false); //Aig_Obj_t* gamma_disjunction_for_debug = computeDisjunctionOfGammas(var_to_elim_index); //insertIntoOneDimensionalMatrix(GammaDisjunctions, number_of_vars_to_elim, var_to_elim_index, gamma_disjunction_for_debug, false); #endif #ifdef DETAILED_RECORD_KEEP gettimeofday (&step_start_ms, NULL); #endif computeAbstractBadSet(var_to_elim_index); if(checkTimeOut()) // check for time-out { cout << "\nWarning!!Time-out inside the function AIGBasedSkolem::factorizedSkolemFunctionGenerator\n"; timed_out = true; // timed_out flag set return; } #ifdef DETAILED_RECORD_KEEP gettimeofday (&step_finish_ms, NULL); step_ms = step_finish_ms.tv_sec * 1000 + step_finish_ms.tv_usec / 1000; step_ms -= step_start_ms.tv_sec * 1000 + step_start_ms.tv_usec / 1000; cout << "\ncomputeAbstractBadSet finished in " << step_ms << " milliseconds\n"; DeltaCombGenTime = step_ms; #endif #ifdef DETAILED_RECORD_KEEP gettimeofday (&step_start_ms, NULL); #endif if(var_to_elim_index != number_of_vars_to_elim) // We need to update the factor matrix { #ifdef DEBUG_SKOLEM cout << "\nupdating factors\n"; #endif updateFactorsWithoutComposition(var_to_elim_index); } if(checkTimeOut()) // check for time-out { cout << "\nWarning!!Time-out inside the function AIGBasedSkolem::factorizedSkolemFunctionGenerator\n"; timed_out = true; // timed_out flag set return; } #ifdef DETAILED_RECORD_KEEP gettimeofday (&step_finish_ms, NULL); step_ms = step_finish_ms.tv_sec * 1000 + step_finish_ms.tv_usec / 1000; step_ms -= step_start_ms.tv_sec * 1000 + step_start_ms.tv_usec / 1000; cout << "\nupdateFactors finished in " << step_ms << " milliseconds\n"; NextFactorGenTime = step_ms; #endif #ifdef DEBUG_SKOLEM cout << "\nclearing variable-specific data-structures\n"; #endif #ifdef DETAILED_RECORD_KEEP gettimeofday (&step_start_ms, NULL); #endif clearVariableSpecificDataStructures(); #ifdef DETAILED_RECORD_KEEP gettimeofday (&step_finish_ms, NULL); step_ms = step_finish_ms.tv_sec * 1000 + step_finish_ms.tv_usec / 1000; step_ms -= step_start_ms.tv_sec * 1000 + step_start_ms.tv_usec / 1000; cout << "\nclearVariableSpecificDataStructures finished in " << step_ms << " milliseconds\n"; #endif #ifdef RECORD_KEEP gettimeofday (&finish_ms, NULL); duration_ms = finish_ms.tv_sec * 1000 + finish_ms.tv_usec / 1000; duration_ms -= start_ms.tv_sec * 1000 + start_ms.tv_usec / 1000; SkolemFunctionGenTime = duration_ms; SkolemFunctionSize = computeSize(skolem_function, pub_aig_manager); // AIG Manager API Call #endif string var_to_elim = searchVarIndexToVarNameMap(var_index_to_var_name_map, var_to_elim_index); cout << "\nabstract skolem_function_" << var_to_elim_index << ", i.e., abstract skolem function for " << var_to_elim << " computed\n"; #ifdef RECORD_KEEP string record_file; record_file = logfile_prefix; record_file += "skolem_function_generation_details.txt"; FILE* record_fp = fopen(record_file.c_str(), "a+"); assert(record_fp != NULL); total_of_skyline_sizes_in_least_cost_ordering = 0; sum_of_number_of_factors_containing_variable = sum_of_number_of_factors_containing_variable + NumberOfFactors; //sum_of_skolem_function_sizes = 0; // we will find this before reverse-substitution total_number_of_compose_operations = total_number_of_compose_operations + number_of_compose_operations_for_variable; total_time_in_compose_operations = total_time_in_compose_operations + ComposeTime; total_time_in_alpha_combined = total_time_in_alpha_combined + AlphaCombGenTime; total_time_in_delta_part = total_time_in_delta_part + DeltaPartGenTime; total_time_in_delta_combined = total_time_in_delta_combined + DeltaCombGenTime; total_time_in_next_factor = total_time_in_next_factor + NextFactorGenTime; total_time_in_correction_part = 0; number_of_variables_eliminated = var_to_elim_index; sum_of_numbers_of_affecting_factors = 0; //fprintf(record_fp, "%s\t%d\t%llu\t%d\t%d\t", var_to_elim.c_str(), NumberOfFactors, SkolemFunctionGenTime, SkolemFunctionSize, AlphaPartSize); // more detailed output fprintf(record_fp, "(%d)%s\t%d\t%llu\t%d\t", var_to_elim_index, var_to_elim.c_str(), NumberOfFactors, SkolemFunctionGenTime, SkolemFunctionSize); if(print_factor_graph) { string fg_file_name = benchmark_name_without_extension; if(disable_factorization || disable_factorization_inside_factorized_code) { fg_file_name += "_monolithic"; } else { fg_file_name += "_factorized"; } fg_file_name += "_factor_graph.dat"; FILE* fg_fp = fopen(fg_file_name.c_str(), "a+"); assert(fg_fp != NULL); for(list::iterator affect_it = FactorsAffectingSkolemFunction.begin(); affect_it != FactorsAffectingSkolemFunction.end(); affect_it++) { fprintf(fg_fp, "%d\t%d\n", *affect_it, var_to_elim_index); } fclose(fg_fp); } //fprintf(record_fp, "%d\t%d\t%d\t%llu\t%llu\t%llu\t%llu\t%llu\t%llu", DeltaPartSize, DeltaCombinedSize, number_of_compose_operations_for_variable, ComposeTime, FactorFindingTime, AlphaCombGenTime, DeltaPartGenTime, DeltaCombGenTime, NextFactorGenTime); fprintf(record_fp, "%d\t%d\t%d\t%d", AlphaPartSize, DeltaPartSize, DeltaCombinedSize, CorrectionPartSize); // more detailed output //fprintf(record_fp, "%d", CorrectionPartSize); // shows size of Bad_{v+1} fprintf(record_fp, "\t"); for(set::iterator factor_it = PreviousFactorsWithVariable.begin(); factor_it != PreviousFactorsWithVariable.end(); factor_it++) { fprintf(record_fp, "%d,", *factor_it); } fprintf(record_fp, "\t"); PreviousFactorsWithVariable.clear(); for(list::iterator size_it = sizes_of_factors_with_variable.begin(); size_it != sizes_of_factors_with_variable.end(); size_it++) { fprintf(record_fp, "%d,", *size_it); } fprintf(record_fp, "\t"); sizes_of_factors_with_variable.clear(); fprintf(record_fp, "\n\n"); number_of_compose_operations_for_variable = 0; ComposeTime = 0; fclose(record_fp); #endif }//for ends here gettimeofday (&cegar_step_finish_ms, NULL); total_time_in_initial_abstraction_generation_in_cegar = cegar_step_finish_ms.tv_sec * 1000 + cegar_step_finish_ms.tv_usec / 1000; total_time_in_initial_abstraction_generation_in_cegar -= cegar_step_start_ms.tv_sec * 1000 + cegar_step_start_ms.tv_usec / 1000; size_computation_time_in_initial_abstraction_generation_in_cegar = total_time_in_compute_size - size_computation_time_in_initialization; total_time_in_initial_abstraction_generation_in_cegar = total_time_in_initial_abstraction_generation_in_cegar - size_computation_time_in_initial_abstraction_generation_in_cegar; // We have the initial abstract skolem functions and bad sets here #ifdef ANALYZE_CEGAR string cegar_file = "cegar_details.txt"; FILE* cegar_fp = fopen(cegar_file.c_str(), "a+"); assert(cegar_fp != NULL); fprintf(cegar_fp, "\n\n\n\n"); fprintf(cegar_fp, "Y = %s\n", benchmark_type.c_str()); fprintf(cegar_fp, "B = %s\n", benchmark_name.c_str()); fprintf(cegar_fp, "M = %s\n", machine.c_str()); set Final_VariablesToEliminate_Set(VariablesToEliminate.begin(), VariablesToEliminate.end()); for(int var_to_elim_index = 1; var_to_elim_index <= number_of_vars_to_elim; var_to_elim_index++) { string var_to_elim = searchVarIndexToVarNameMap(var_index_to_var_name_map, var_to_elim_index); Aig_Obj_t* skolem_function_i = searchOneDimensionalMatrix(SkolemFunctions, number_of_vars_to_elim, var_to_elim_index); assert(skolem_function_i != NULL); set support_skolem_function_i; computeSupport(skolem_function_i, support_skolem_function_i, pub_aig_manager); set inputs_skolem_function_i; set_intersection(support_skolem_function_i.begin(), support_skolem_function_i.end(), Final_VariablesToEliminate_Set.begin(), Final_VariablesToEliminate_Set.end(), inserter(inputs_skolem_function_i, inputs_skolem_function_i.begin())); set inputs_int_skolem_function_i; for(set::iterator inputs_skolem_function_i_it = inputs_skolem_function_i.begin(); inputs_skolem_function_i_it != inputs_skolem_function_i.end(); inputs_skolem_function_i_it++) { string input_string = *inputs_skolem_function_i_it; int input_int = searchVarNameToVarIndexMap(var_name_to_var_index_map, input_string); assert(input_int != -1); inputs_int_skolem_function_i.insert(input_int); } Aig_Obj_t* bad_set_i = searchOneDimensionalMatrix(BadSets, number_of_vars_to_elim+1, var_to_elim_index+1); assert(bad_set_i != NULL); set support_bad_set_i; computeSupport(bad_set_i, support_bad_set_i, pub_aig_manager); set inputs_bad_set_i; set_intersection(support_bad_set_i.begin(), support_bad_set_i.end(), Final_VariablesToEliminate_Set.begin(), Final_VariablesToEliminate_Set.end(), inserter(inputs_bad_set_i, inputs_bad_set_i.begin())); set inputs_int_bad_set_i; for(set::iterator inputs_bad_set_i_it = inputs_bad_set_i.begin(); inputs_bad_set_i_it != inputs_bad_set_i.end(); inputs_bad_set_i_it++) { string input_string = *inputs_bad_set_i_it; int input_int = searchVarNameToVarIndexMap(var_name_to_var_index_map, input_string); assert(input_int != -1); inputs_int_bad_set_i.insert(input_int); } fprintf(cegar_fp, "\n*****************************************\n"); fprintf(cegar_fp, "var_to_elim_index = %d, var_to_elim = %s\n", var_to_elim_index, var_to_elim.c_str()); printSet(inputs_int_skolem_function_i, "inputs_skolem_function_i", cegar_fp); printSet(inputs_int_bad_set_i, "inputs_bad_set_{i+1}", cegar_fp); } fclose(cegar_fp); #endif #ifdef DEBUG_CEGAR cout << "\nWe have the initial abstract skolem functions and bad sets, starting CEGAR\n"; #endif #ifdef RECORD_KEEP string record_file; record_file = logfile_prefix; record_file += "skolem_function_generation_details.txt"; FILE* record_fp = fopen(record_file.c_str(), "a+"); assert(record_fp != NULL); fprintf(record_fp, "\nDetails of CEGAR\n"); fprintf(record_fp, "\nit = Iteration number\nT_s(C_s)(X_s) = Time to check satisfiability of exactness condition (time spent in cnf generation, time spent in simplification) (size of formula)\nT_r(C_r)(X_r) = Times to check satisfiability of conditions while finding hints (times spent in cnf generation, times spent in simplification) (sizes of formulae)\nM = Mismatch locations\nH = Refinement hints\nL_c = maximum length of any connection encountered so far from iteration-0\nN_c = number of connections encountered so far from iteration-0\nN_c_i = number of connections updated in this iteration\nU_n = number of literals dropped in this iteration with the help of unsat core\n"); fprintf(record_fp, "\nit\tT_s(C_s,S_s)(X_s)\tT_r(C_r,S_r)(X_r)\tM\tH\tL_c\tN_c\tN_c_i\tU_n"); fclose(record_fp); #endif gettimeofday (&cegar_step_start_ms, NULL); if(solver == "abc") { cout << "\nInitializing CEGAR\n"; initializeCEGAR_using_ABC(); cout << "\nCEGAR initialized\n"; if(use_incremental_sat_solving) { pSat_for_exactness_check = sat_solver_new(); pSat_for_mismatch_check = sat_solver_new(); #ifdef DEBUG_CEGAR cout << "\npSat_for_exactness_check and pSat_for_mismatch_check are created\n"; #endif } map Model_of_ExactnessCheck; map Refinement_Hint_To_Eliminate_This_CEX; // check if the initial abstract skolem functions are exact // Refinement_Hint_To_Eliminate_This_CEX is just a place holder here bool skolem_functions_are_exact; if(use_generalized_value_based_scheme || use_explicit_values_in_refinement) { skolem_functions_are_exact = checkIfSkolemFunctionsAreExact_using_Value_Based_Scheme(Model_of_ExactnessCheck, Refinement_Hint_To_Eliminate_This_CEX, VariablesToEliminate); } else if(use_multi_point_connections) { skolem_functions_are_exact = checkIfSkolemFunctionsAreExact_using_ABC_with_Multi_Point_Connections(Model_of_ExactnessCheck, Refinement_Hint_To_Eliminate_This_CEX, VariablesToEliminate); } else if(use_composes_for_refinement) { skolem_functions_are_exact = checkIfSkolemFunctionsAreExact_using_ABC_with_Composes(Model_of_ExactnessCheck, Refinement_Hint_To_Eliminate_This_CEX, VariablesToEliminate); } else if(use_cyclic_two_point_connections) { skolem_functions_are_exact = checkIfSkolemFunctionsAreExact_using_ABC_with_Cyclic_Two_Point_Connections(Model_of_ExactnessCheck, Refinement_Hint_To_Eliminate_This_CEX); } else { cout << "\nRefinement scheme is unspecified\n"; assert(false); } cout << "\ncegar_iteration_number = " << cegar_iteration_number << " finished\n"; #ifdef DEBUG_SKOLEM cout << "\nPress any key to continue..."; char c = getchar(); #endif while(!skolem_functions_are_exact) { cout << "\nskolem functions inexact\n"; cegar_iteration_number++; // from the model of exactness check, obtain the refinement hint to // eliminate this counterexample Refinement_Hint_To_Eliminate_This_CEX.clear(); if(refinement_strategy == 0) //EvaluationBasedStrategy { refineSkolemFunctions_using_ABC_EvaluationBasedStrategy(Model_of_ExactnessCheck, Refinement_Hint_To_Eliminate_This_CEX); } else //DefaultStrategy { refineSkolemFunctions_using_ABC(Model_of_ExactnessCheck, Refinement_Hint_To_Eliminate_This_CEX); } // check if the skolem functions are exact with the new refinement hint to // eliminate this counterexample Model_of_ExactnessCheck.clear(); if(use_generalized_value_based_scheme || use_explicit_values_in_refinement) { skolem_functions_are_exact = checkIfSkolemFunctionsAreExact_using_Value_Based_Scheme(Model_of_ExactnessCheck, Refinement_Hint_To_Eliminate_This_CEX, VariablesToEliminate); } else if(use_multi_point_connections) { skolem_functions_are_exact = checkIfSkolemFunctionsAreExact_using_ABC_with_Multi_Point_Connections(Model_of_ExactnessCheck, Refinement_Hint_To_Eliminate_This_CEX, VariablesToEliminate); } else if(use_composes_for_refinement) { skolem_functions_are_exact = checkIfSkolemFunctionsAreExact_using_ABC_with_Composes(Model_of_ExactnessCheck, Refinement_Hint_To_Eliminate_This_CEX, VariablesToEliminate); } else if(use_cyclic_two_point_connections) { skolem_functions_are_exact = checkIfSkolemFunctionsAreExact_using_ABC_with_Cyclic_Two_Point_Connections(Model_of_ExactnessCheck, Refinement_Hint_To_Eliminate_This_CEX); } else { assert(false); } // if exact, then skolem_functions_are_exact is true // else, we have the new model of exactness check cout << "\ncegar_iteration_number = " << cegar_iteration_number << " finished\n"; #ifdef DEBUG_SKOLEM cout << "\nPress any key to continue..."; c = getchar(); #endif } if(use_incremental_sat_solving) { sat_solver_delete(pSat_for_exactness_check); sat_solver_delete(pSat_for_mismatch_check); #ifdef DEBUG_CEGAR cout << "\npSat_for_exactness_check and pSat_for_mismatch_check are deleted\n"; #endif } } else { initializeCEGAR(); map Model_of_ExactnessCheck; map Refinement_Hint_To_Eliminate_This_CEX; // check if the initial abstract skolem functions are exact // Refinement_Hint_To_Eliminate_This_CEX is just a place holder here bool skolem_functions_are_exact = checkIfSkolemFunctionsAreExact(Model_of_ExactnessCheck, Refinement_Hint_To_Eliminate_This_CEX); cout << "\ncegar_iteration_number = " << cegar_iteration_number << " finished\n"; #ifdef DEBUG_SKOLEM cout << "\nPress any key to continue..."; char c = getchar(); #endif while(!skolem_functions_are_exact) { cout << "\nskolem functions inexact\n"; cegar_iteration_number++; // from the model of exactness check, obtain the refinement hint to // eliminate this counterexample Refinement_Hint_To_Eliminate_This_CEX.clear(); refineSkolemFunctions(Model_of_ExactnessCheck, Refinement_Hint_To_Eliminate_This_CEX); // check if the skolem functions are exact with the new refinement hint to // eliminate this counterexample Model_of_ExactnessCheck.clear(); skolem_functions_are_exact = checkIfSkolemFunctionsAreExact(Model_of_ExactnessCheck, Refinement_Hint_To_Eliminate_This_CEX); // if exact, then skolem_functions_are_exact is true // else, we have the new model of exactness check cout << "\ncegar_iteration_number = " << cegar_iteration_number << " finished\n"; #ifdef DEBUG_SKOLEM cout << "\nPress any key to continue..."; c = getchar(); #endif } }// if(solver != "abc") cout << "\nexact skolem functions are found\n"; // exact skolem functions are found gettimeofday (&cegar_step_finish_ms, NULL); total_time_in_cegar_loops_in_cegar = cegar_step_finish_ms.tv_sec * 1000 + cegar_step_finish_ms.tv_usec / 1000; total_time_in_cegar_loops_in_cegar -= cegar_step_start_ms.tv_sec * 1000 + cegar_step_start_ms.tv_usec / 1000; size_computation_time_in_cegar_loops_in_cegar = total_time_in_compute_size - size_computation_time_in_initialization - size_computation_time_in_initial_abstraction_generation_in_cegar; total_time_in_cegar_loops_in_cegar = total_time_in_cegar_loops_in_cegar - size_computation_time_in_cegar_loops_in_cegar; gettimeofday (&cegar_step_start_ms, NULL); if(substitute_connections_by_dags && cegar_iteration_number > 0) { // substitution of connections by their dags is needed only // if cegar_iteration_number > 0 // if cegar_iteration_number == 0, no connections will be introduced if(use_multi_point_connections) { replaceConnectionsByFormulas_In_Multi_Point_Connections(); } else if(use_cyclic_two_point_connections) { replaceConnectionsByFormulas_In_Two_Point_Connections(); } else if(use_composes_for_refinement) { cout << "\nNo connection-replacement needed\n"; } else { assert(false); } } gettimeofday (&cegar_step_finish_ms, NULL); total_time_in_connection_substitution_in_cegar = cegar_step_finish_ms.tv_sec * 1000 + cegar_step_finish_ms.tv_usec / 1000; total_time_in_connection_substitution_in_cegar -= cegar_step_start_ms.tv_sec * 1000 + cegar_step_start_ms.tv_usec / 1000; size_computation_time_in_connection_substitution_in_cegar = total_time_in_compute_size - size_computation_time_in_initialization - size_computation_time_in_initial_abstraction_generation_in_cegar - size_computation_time_in_cegar_loops_in_cegar; total_time_in_connection_substitution_in_cegar = total_time_in_connection_substitution_in_cegar - size_computation_time_in_connection_substitution_in_cegar; } // if(enable_cegar) ends here else if(compute_generic_skolem_function_parameters) { assert(perform_cofactor_based_quantifier_elimination_along_with_skolem_function_generation); for(int var_to_elim_index = 1; var_to_elim_index <= number_of_vars_to_elim; var_to_elim_index++) { if(checkTimeOut()) // check for time-out { cout << "\nWarning!!Time-out inside the function AIGBasedSkolem::factorizedSkolemFunctionGenerator\n"; timed_out = true; // timed_out flag set return; } if(maximum_index_to_eliminate != -1) // to stop computation in between { if(var_to_elim_index > maximum_index_to_eliminate) { cout << "\nLet us stop here...\n"; return; } } #ifdef DEBUG_SKOLEM cout << "\ncomputing skolem_function_" << var_to_elim_index << endl; #endif #ifdef PRINT_VERY_DETAILED_RECORDS_ON_SCREEN cout << "\ncomputing skolem_function_" << var_to_elim_index << "\n"; #endif #ifdef RECORD_KEEP unsigned long long int duration_ms; struct timeval start_ms, finish_ms; gettimeofday (&start_ms, NULL); #endif #ifdef DETAILED_RECORD_KEEP gettimeofday (&step_start_ms, NULL); #endif findFactorsWithVariable(var_to_elim_index);// find the set of factors containing the variable if(checkTimeOut()) // check for time-out { cout << "\nWarning!!Time-out inside the function AIGBasedSkolem::factorizedSkolemFunctionGenerator\n"; timed_out = true; // timed_out flag set return; } #ifdef DETAILED_RECORD_KEEP gettimeofday (&step_finish_ms, NULL); step_ms = step_finish_ms.tv_sec * 1000 + step_finish_ms.tv_usec / 1000; step_ms -= step_start_ms.tv_sec * 1000 + step_start_ms.tv_usec / 1000; cout << "\nfindFactorsWithVariable finished in " << step_ms << " milliseconds\n"; cout << "\nnumber of factors containing the variable = " << FactorsWithVariable.size() << endl; FactorFindingTime = step_ms; #endif #ifdef DETAILED_RECORD_KEEP gettimeofday (&step_start_ms, NULL); #endif Aig_Obj_t* alpha_combined_in_bad_based = NULL; Aig_Obj_t* cofactor_one_in_bdd_based = NULL; Aig_Obj_t* cofactor_zero_in_bdd_based = NULL; if(use_bad_in_perform_cofactor_based_quantifier_elimination_along_with_skolem_function_generation) { computeGenericSkolemFunctionParametersInBadBased(var_to_elim_index, alpha_combined_in_bad_based); assert(alpha_combined_in_bad_based != NULL); } else { computeGenericSkolemFunctionParametersInBddBased(var_to_elim_index, cofactor_one_in_bdd_based, cofactor_zero_in_bdd_based); assert(cofactor_one_in_bdd_based != NULL); assert(cofactor_zero_in_bdd_based != NULL); } Aig_Obj_t* skolem_function = createTrue(pub_aig_manager); assert(skolem_function != NULL); insertIntoOneDimensionalMatrix(SkolemFunctions, number_of_vars_to_elim, var_to_elim_index, skolem_function, false); if(checkTimeOut()) // check for time-out { cout << "\nWarning!!Time-out inside the function AIGBasedSkolem::factorizedSkolemFunctionGenerator\n"; timed_out = true; // timed_out flag set return; } #ifdef DETAILED_RECORD_KEEP gettimeofday (&step_finish_ms, NULL); step_ms = step_finish_ms.tv_sec * 1000 + step_finish_ms.tv_usec / 1000; step_ms -= step_start_ms.tv_sec * 1000 + step_start_ms.tv_usec / 1000; cout << "\ncomputation of generic skolem function parameters finished in " << step_ms << " milliseconds\n"; AlphaCombGenTime = step_ms; AlphaPartSize = -1; DeltaPartGenTime = 0; DeltaPartSize = -1; #endif #ifdef DETAILED_RECORD_KEEP gettimeofday (&step_start_ms, NULL); #endif if(use_bad_in_perform_cofactor_based_quantifier_elimination_along_with_skolem_function_generation) { updateBadSetWithGivenAlphaCombined(var_to_elim_index, alpha_combined_in_bad_based); } else { #ifdef RECORD_KEEP DeltaCombinedSize = -1; #endif } if(checkTimeOut()) // check for time-out { cout << "\nWarning!!Time-out inside the function AIGBasedSkolem::factorizedSkolemFunctionGenerator\n"; timed_out = true; // timed_out flag set return; } #ifdef DETAILED_RECORD_KEEP gettimeofday (&step_finish_ms, NULL); step_ms = step_finish_ms.tv_sec * 1000 + step_finish_ms.tv_usec / 1000; step_ms -= step_start_ms.tv_sec * 1000 + step_start_ms.tv_usec / 1000; cout << "\nupdating bad finished in " << step_ms << " milliseconds\n"; DeltaCombGenTime = step_ms; #endif #ifdef DETAILED_RECORD_KEEP gettimeofday (&step_start_ms, NULL); #endif if(var_to_elim_index != number_of_vars_to_elim) // We need to update the factor matrix { #ifdef DEBUG_SKOLEM cout << "\nupdating factors\n"; #endif if(use_bad_in_perform_cofactor_based_quantifier_elimination_along_with_skolem_function_generation) { updateFactorsWithoutComposition(var_to_elim_index); } else { Aig_Obj_t* quantifier_eliminated_result = createOr(cofactor_one_in_bdd_based, cofactor_zero_in_bdd_based, pub_aig_manager); assert(quantifier_eliminated_result != NULL); updateFactorsUsingQuantifierEliminatedResult(var_to_elim_index, quantifier_eliminated_result); } } if(checkTimeOut()) // check for time-out { cout << "\nWarning!!Time-out inside the function AIGBasedSkolem::factorizedSkolemFunctionGenerator\n"; timed_out = true; // timed_out flag set return; } #ifdef DETAILED_RECORD_KEEP gettimeofday (&step_finish_ms, NULL); step_ms = step_finish_ms.tv_sec * 1000 + step_finish_ms.tv_usec / 1000; step_ms -= step_start_ms.tv_sec * 1000 + step_start_ms.tv_usec / 1000; cout << "\nupdateFactors finished in " << step_ms << " milliseconds\n"; NextFactorGenTime = step_ms; #endif #ifdef DEBUG_SKOLEM cout << "\nclearing variable-specific data-structures\n"; #endif #ifdef DETAILED_RECORD_KEEP gettimeofday (&step_start_ms, NULL); #endif clearVariableSpecificDataStructures(); #ifdef DETAILED_RECORD_KEEP gettimeofday (&step_finish_ms, NULL); step_ms = step_finish_ms.tv_sec * 1000 + step_finish_ms.tv_usec / 1000; step_ms -= step_start_ms.tv_sec * 1000 + step_start_ms.tv_usec / 1000; cout << "\nclearVariableSpecificDataStructures finished in " << step_ms << " milliseconds\n"; #endif #ifdef RECORD_KEEP gettimeofday (&finish_ms, NULL); duration_ms = finish_ms.tv_sec * 1000 + finish_ms.tv_usec / 1000; duration_ms -= start_ms.tv_sec * 1000 + start_ms.tv_usec / 1000; SkolemFunctionGenTime = duration_ms; SkolemFunctionSize = computeSize(skolem_function, pub_aig_manager); // AIG Manager API Call #endif string var_to_elim = searchVarIndexToVarNameMap(var_index_to_var_name_map, var_to_elim_index); cout << "\nskolem_function_" << var_to_elim_index << ", i.e., skolem function for " << var_to_elim << " computed\n"; #ifdef RECORD_KEEP string record_file; record_file = logfile_prefix; record_file += "skolem_function_generation_details.txt"; FILE* record_fp = fopen(record_file.c_str(), "a+"); assert(record_fp != NULL); total_of_skyline_sizes_in_least_cost_ordering = 0; sum_of_number_of_factors_containing_variable = sum_of_number_of_factors_containing_variable + NumberOfFactors; //sum_of_skolem_function_sizes = sum_of_skolem_function_sizes + SkolemFunctionSize; // we will find this before reverse-substitution total_number_of_compose_operations = total_number_of_compose_operations + number_of_compose_operations_for_variable; total_time_in_compose_operations = total_time_in_compose_operations + ComposeTime; total_time_in_alpha_combined = total_time_in_alpha_combined + AlphaCombGenTime; total_time_in_delta_part = total_time_in_delta_part + DeltaPartGenTime; total_time_in_delta_combined = total_time_in_delta_combined + DeltaCombGenTime; total_time_in_next_factor = total_time_in_next_factor + NextFactorGenTime; total_time_in_correction_part = 0; number_of_variables_eliminated = var_to_elim_index; sum_of_numbers_of_affecting_factors = 0; fprintf(record_fp, "%s\t%d\t%llu\t%d\t%d\t", var_to_elim.c_str(), NumberOfFactors, SkolemFunctionGenTime, SkolemFunctionSize, AlphaPartSize); if(print_factor_graph) { string fg_file_name = benchmark_name_without_extension; if(disable_factorization || disable_factorization_inside_factorized_code) { fg_file_name += "_monolithic"; } else { fg_file_name += "_factorized"; } fg_file_name += "_factor_graph.dat"; FILE* fg_fp = fopen(fg_file_name.c_str(), "a+"); assert(fg_fp != NULL); for(list::iterator affect_it = FactorsAffectingSkolemFunction.begin(); affect_it != FactorsAffectingSkolemFunction.end(); affect_it++) { fprintf(fg_fp, "%d\t%d\n", *affect_it, var_to_elim_index); } fclose(fg_fp); } fprintf(record_fp, "%d\t%d\t%d\t%llu\t%llu\t%llu\t%llu\t%llu\t%llu", DeltaPartSize, DeltaCombinedSize, number_of_compose_operations_for_variable, ComposeTime, FactorFindingTime, AlphaCombGenTime, DeltaPartGenTime, DeltaCombGenTime, NextFactorGenTime); fprintf(record_fp, "\n\n"); number_of_compose_operations_for_variable = 0; ComposeTime = 0; fclose(record_fp); #endif }//for ends here }// if(compute_generic_skolem_function_parameters) ends here else if(perform_cofactor_based_quantifier_elimination_along_with_skolem_function_generation) { for(int var_to_elim_index = 1; var_to_elim_index <= number_of_vars_to_elim; var_to_elim_index++) { if(checkTimeOut()) // check for time-out { cout << "\nWarning!!Time-out inside the function AIGBasedSkolem::factorizedSkolemFunctionGenerator\n"; timed_out = true; // timed_out flag set return; } if(maximum_index_to_eliminate != -1) // to stop computation in between { if(var_to_elim_index > maximum_index_to_eliminate) { cout << "\nLet us stop here...\n"; return; } } #ifdef DEBUG_SKOLEM cout << "\ncomputing skolem_function_" << var_to_elim_index << endl; #endif #ifdef PRINT_VERY_DETAILED_RECORDS_ON_SCREEN cout << "\ncomputing skolem_function_" << var_to_elim_index << "\n"; #endif #ifdef RECORD_KEEP unsigned long long int duration_ms; struct timeval start_ms, finish_ms; gettimeofday (&start_ms, NULL); #endif #ifdef DETAILED_RECORD_KEEP gettimeofday (&step_start_ms, NULL); #endif findFactorsWithVariable(var_to_elim_index);// find the set of factors containing the variable if(checkTimeOut()) // check for time-out { cout << "\nWarning!!Time-out inside the function AIGBasedSkolem::factorizedSkolemFunctionGenerator\n"; timed_out = true; // timed_out flag set return; } #ifdef DETAILED_RECORD_KEEP gettimeofday (&step_finish_ms, NULL); step_ms = step_finish_ms.tv_sec * 1000 + step_finish_ms.tv_usec / 1000; step_ms -= step_start_ms.tv_sec * 1000 + step_start_ms.tv_usec / 1000; cout << "\nfindFactorsWithVariable finished in " << step_ms << " milliseconds\n"; cout << "\nnumber of factors containing the variable = " << FactorsWithVariable.size() << endl; FactorFindingTime = step_ms; #endif #ifdef DETAILED_RECORD_KEEP gettimeofday (&step_start_ms, NULL); #endif Aig_Obj_t* cofactor_one_of_bad_set = NULL; Aig_Obj_t* skolem_function; if(!use_bad_in_perform_cofactor_based_quantifier_elimination_along_with_skolem_function_generation && use_interpolant_as_skolem_function) { skolem_function = computeSkolemFunctionAsInterpolant(var_to_elim_index); // connect to some output to avoid unwanted deletion Aig_Obj_t* skolem_function_CO = Aig_ObjCreateCo(pub_aig_manager, skolem_function ); assert(skolem_function_CO != NULL); insertIntoOneDimensionalMatrix(SkolemFunctions, number_of_vars_to_elim, var_to_elim_index, skolem_function, false); #ifdef PRINT_SKOLEM_FUNCTIONS string skolem_function_file_name = benchmark_name_without_extension; skolem_function_file_name += "_skolem_function"; writeFormulaToFile(pub_aig_manager, skolem_function, skolem_function_file_name, ".v", var_to_elim_index, 0); #endif } else { skolem_function = computeSkolemFunctionUsingBadSet(var_to_elim_index, cofactor_one_of_bad_set); // connect to some output to avoid unwanted deletion Aig_Obj_t* skolem_function_CO = Aig_ObjCreateCo(pub_aig_manager, skolem_function ); assert(skolem_function_CO != NULL); assert(cofactor_one_of_bad_set != NULL); } if(checkTimeOut()) // check for time-out { cout << "\nWarning!!Time-out inside the function AIGBasedSkolem::factorizedSkolemFunctionGenerator\n"; timed_out = true; // timed_out flag set return; } assert(skolem_function != NULL); #ifdef DETAILED_RECORD_KEEP gettimeofday (&step_finish_ms, NULL); step_ms = step_finish_ms.tv_sec * 1000 + step_finish_ms.tv_usec / 1000; step_ms -= step_start_ms.tv_sec * 1000 + step_start_ms.tv_usec / 1000; cout << "\ncomputeSkolemFunctionUsingBadSet finished in " << step_ms << " milliseconds\n"; #endif #ifdef DETAILED_RECORD_KEEP gettimeofday (&step_start_ms, NULL); #endif if(use_bad_in_perform_cofactor_based_quantifier_elimination_along_with_skolem_function_generation) { updateBadSet(var_to_elim_index, cofactor_one_of_bad_set); } else { #ifdef RECORD_KEEP DeltaCombinedSize = -1; #endif } if(checkTimeOut()) // check for time-out { cout << "\nWarning!!Time-out inside the function AIGBasedSkolem::factorizedSkolemFunctionGenerator\n"; timed_out = true; // timed_out flag set return; } #ifdef DETAILED_RECORD_KEEP gettimeofday (&step_finish_ms, NULL); step_ms = step_finish_ms.tv_sec * 1000 + step_finish_ms.tv_usec / 1000; step_ms -= step_start_ms.tv_sec * 1000 + step_start_ms.tv_usec / 1000; cout << "\nupdateBadSet finished in " << step_ms << " milliseconds\n"; DeltaCombGenTime = step_ms; #endif #ifdef DETAILED_RECORD_KEEP gettimeofday (&step_start_ms, NULL); #endif if(var_to_elim_index != number_of_vars_to_elim) // We need to update the factor matrix { #ifdef DEBUG_SKOLEM cout << "\nupdating factors\n"; #endif if(use_bad_in_perform_cofactor_based_quantifier_elimination_along_with_skolem_function_generation) { updateFactorsWithoutComposition(var_to_elim_index); } else { Aig_Obj_t* quantifier_eliminated_result; if(compute_quantifier_eliminated_result_using_skolem_functions) { quantifier_eliminated_result = computeQuantifierEliminatedResultUsingSkolemFunction(var_to_elim_index, skolem_function); } else { quantifier_eliminated_result = computeQuantifierEliminatedResultUsingCofactors(var_to_elim_index); } assert(quantifier_eliminated_result != NULL); // connect to some output to avoid unwanted deletion Aig_Obj_t* quantifier_eliminated_result_CO = Aig_ObjCreateCo(pub_aig_manager, quantifier_eliminated_result ); assert(quantifier_eliminated_result_CO != NULL); updateFactorsUsingQuantifierEliminatedResult(var_to_elim_index, quantifier_eliminated_result); } } if(checkTimeOut()) // check for time-out { cout << "\nWarning!!Time-out inside the function AIGBasedSkolem::factorizedSkolemFunctionGenerator\n"; timed_out = true; // timed_out flag set return; } #ifdef DETAILED_RECORD_KEEP gettimeofday (&step_finish_ms, NULL); step_ms = step_finish_ms.tv_sec * 1000 + step_finish_ms.tv_usec / 1000; step_ms -= step_start_ms.tv_sec * 1000 + step_start_ms.tv_usec / 1000; cout << "\nupdateFactors finished in " << step_ms << " milliseconds\n"; NextFactorGenTime = step_ms; #endif #ifdef DEBUG_SKOLEM cout << "\nclearing variable-specific data-structures\n"; #endif #ifdef DETAILED_RECORD_KEEP gettimeofday (&step_start_ms, NULL); #endif clearVariableSpecificDataStructures(); #ifdef DETAILED_RECORD_KEEP gettimeofday (&step_finish_ms, NULL); step_ms = step_finish_ms.tv_sec * 1000 + step_finish_ms.tv_usec / 1000; step_ms -= step_start_ms.tv_sec * 1000 + step_start_ms.tv_usec / 1000; cout << "\nclearVariableSpecificDataStructures finished in " << step_ms << " milliseconds\n"; #endif #ifdef RECORD_KEEP gettimeofday (&finish_ms, NULL); duration_ms = finish_ms.tv_sec * 1000 + finish_ms.tv_usec / 1000; duration_ms -= start_ms.tv_sec * 1000 + start_ms.tv_usec / 1000; SkolemFunctionGenTime = duration_ms; SkolemFunctionSize = computeSize(skolem_function, pub_aig_manager); // AIG Manager API Call #endif string var_to_elim = searchVarIndexToVarNameMap(var_index_to_var_name_map, var_to_elim_index); cout << "\nskolem_function_" << var_to_elim_index << ", i.e., skolem function for " << var_to_elim << " computed\n"; #ifdef RECORD_KEEP string record_file; record_file = logfile_prefix; record_file += "skolem_function_generation_details.txt"; FILE* record_fp = fopen(record_file.c_str(), "a+"); assert(record_fp != NULL); total_of_skyline_sizes_in_least_cost_ordering = 0; sum_of_number_of_factors_containing_variable = sum_of_number_of_factors_containing_variable + NumberOfFactors; //sum_of_skolem_function_sizes = sum_of_skolem_function_sizes + SkolemFunctionSize; // we will find this before reverse-substitution total_number_of_compose_operations = total_number_of_compose_operations + number_of_compose_operations_for_variable; total_time_in_compose_operations = total_time_in_compose_operations + ComposeTime; total_time_in_alpha_combined = total_time_in_alpha_combined + AlphaCombGenTime; total_time_in_delta_part = total_time_in_delta_part + DeltaPartGenTime; total_time_in_delta_combined = total_time_in_delta_combined + DeltaCombGenTime; total_time_in_next_factor = total_time_in_next_factor + NextFactorGenTime; total_time_in_correction_part = 0; number_of_variables_eliminated = var_to_elim_index; sum_of_numbers_of_affecting_factors = 0; total_number_of_boolean_operations_in_initial_skolem_function_generation = total_number_of_boolean_operations_in_initial_skolem_function_generation + number_of_boolean_operations_for_variable; total_BooleanOpTime_in_initial_skolem_function_generation = total_BooleanOpTime_in_initial_skolem_function_generation + BooleanOpTime; total_number_of_support_operations_in_initial_skolem_function_generation = total_number_of_support_operations_in_initial_skolem_function_generation + number_of_support_operations_for_variable; total_FactorFindingTime_in_initial_skolem_function_generation = total_FactorFindingTime_in_initial_skolem_function_generation + FactorFindingTime; if(use_bad_in_perform_cofactor_based_quantifier_elimination_along_with_skolem_function_generation) { fprintf(record_fp, "%s\t%d\t%llu\t%d\t%d\t", var_to_elim.c_str(), NumberOfFactors, SkolemFunctionGenTime, SkolemFunctionSize, AlphaPartSize); } else if(compute_quantifier_eliminated_result_using_skolem_functions && use_interpolant_as_skolem_function) { fprintf(record_fp, "%d\t%s\t%d\t%llu\t%d\t%d\t%d\t%llu\t%d\t", var_to_elim_index, var_to_elim.c_str(), NumberOfFactors, SkolemFunctionGenTime, SkolemFunctionSize, size_of_alpha_in_interpolant_computation_for_variable, size_of_beta_in_interpolant_computation_for_variable, time_in_interpolant_computation_for_variable, size_of_quantified_result_in_bdd_like_scheme); } else { fprintf(record_fp, "%d\t%s\t%d\t%llu\t%d\t%d\t", var_to_elim_index, var_to_elim.c_str(), NumberOfFactors, SkolemFunctionGenTime, SkolemFunctionSize, size_of_quantified_result_in_bdd_like_scheme); } if(print_factor_graph) { string fg_file_name = benchmark_name_without_extension; if(disable_factorization || disable_factorization_inside_factorized_code) { fg_file_name += "_monolithic"; } else { fg_file_name += "_factorized"; } fg_file_name += "_factor_graph.dat"; FILE* fg_fp = fopen(fg_file_name.c_str(), "a+"); assert(fg_fp != NULL); for(list::iterator affect_it = FactorsAffectingSkolemFunction.begin(); affect_it != FactorsAffectingSkolemFunction.end(); affect_it++) { fprintf(fg_fp, "%d\t%d\n", *affect_it, var_to_elim_index); } fclose(fg_fp); } if(use_bad_in_perform_cofactor_based_quantifier_elimination_along_with_skolem_function_generation) { fprintf(record_fp, "%d\t%d\t%d\t%llu\t%llu\t%llu\t%llu\t%llu\t%llu", DeltaPartSize, DeltaCombinedSize, number_of_compose_operations_for_variable, ComposeTime, FactorFindingTime, AlphaCombGenTime, DeltaPartGenTime, DeltaCombGenTime, NextFactorGenTime); } else { fprintf(record_fp, "%d\t%llu\t%d\t%llu\t%d\t%llu", number_of_compose_operations_for_variable, ComposeTime, number_of_boolean_operations_for_variable, BooleanOpTime, number_of_support_operations_for_variable, FactorFindingTime); } fprintf(record_fp, "\t"); for(set::iterator factor_it = PreviousFactorsWithVariable.begin(); factor_it != PreviousFactorsWithVariable.end(); factor_it++) { fprintf(record_fp, "%d,", *factor_it); } fprintf(record_fp, "\t"); PreviousFactorsWithVariable.clear(); for(list::iterator size_it = sizes_of_factors_with_variable.begin(); size_it != sizes_of_factors_with_variable.end(); size_it++) { fprintf(record_fp, "%d,", *size_it); } fprintf(record_fp, "\t"); sizes_of_factors_with_variable.clear(); fprintf(record_fp, "\n\n"); number_of_compose_operations_for_variable = 0; ComposeTime = 0; number_of_boolean_operations_for_variable = 0; BooleanOpTime = 0; number_of_support_operations_for_variable = 0; fclose(record_fp); #endif }//for ends here gettimeofday (&cegar_step_finish_ms, NULL); total_time_in_initial_abstraction_generation_in_cegar = cegar_step_finish_ms.tv_sec * 1000 + cegar_step_finish_ms.tv_usec / 1000; total_time_in_initial_abstraction_generation_in_cegar -= cegar_step_start_ms.tv_sec * 1000 + cegar_step_start_ms.tv_usec / 1000; total_time_in_cegar_loops_in_cegar = 0; total_time_in_connection_substitution_in_cegar = 0; size_computation_time_in_initial_abstraction_generation_in_cegar = total_time_in_compute_size - size_computation_time_in_initialization; total_time_in_initial_abstraction_generation_in_cegar = total_time_in_initial_abstraction_generation_in_cegar - size_computation_time_in_initial_abstraction_generation_in_cegar; size_computation_time_in_cegar_loops_in_cegar = 0; size_computation_time_in_connection_substitution_in_cegar = 0; } // if(perform_cofactor_based_quantifier_elimination_along_with_skolem_function_generation) ends here else { cout << "!enable_cegar and !compute_generic_skolem_function_parameters and !perform_cofactor_based_quantifier_elimination_along_with_skolem_function_generation not supported with AIG Manager" << endl; assert(false); } total_number_of_compose_operations_in_initial_skolem_function_generation = total_number_of_compose_operations; total_ComposeTime_in_initial_skolem_function_generation = total_time_in_compose_operations; if(perform_cofactor_based_quantifier_elimination_along_with_skolem_function_generation && !enable_cegar && !compute_generic_skolem_function_parameters) { string record_file; record_file = logfile_prefix; record_file += "skolem_function_generation_details.txt"; FILE* record_fp = fopen(record_file.c_str(), "a+"); assert(record_fp != NULL); fprintf(record_fp, "\n\ntotal_number_of_compose_operations_in_initial_skolem_function_generation = %d\ntotal_ComposeTime_in_initial_skolem_function_generation = %llu milliseconds\ntotal_number_of_boolean_operations_in_initial_skolem_function_generation = %d\ntotal_BooleanOpTime_in_initial_skolem_function_generation = %llu milliseconds\ntotal_number_of_support_operations_in_initial_skolem_function_generation = %d\ntotal_FactorFindingTime_in_initial_skolem_function_generation = %llu milliseconds", total_number_of_compose_operations_in_initial_skolem_function_generation, total_ComposeTime_in_initial_skolem_function_generation, total_number_of_boolean_operations_in_initial_skolem_function_generation, total_BooleanOpTime_in_initial_skolem_function_generation, total_number_of_support_operations_in_initial_skolem_function_generation, total_FactorFindingTime_in_initial_skolem_function_generation); fprintf(record_fp, "\n\ntotal-time-in-initial-skolem-function-generation-without-size-computation-time = %llu milliseconds\ntotal time in initialization of skolem function generator-without-size-computation-time = %llu\n", total_time_in_initial_abstraction_generation_in_cegar, total_time_in_generator_initialization); fclose(record_fp); } gettimeofday (&cegar_step_start_ms, NULL); if(perform_reverse_substitution) { for(int var_to_elim_index = 1; var_to_elim_index <= number_of_vars_to_elim; var_to_elim_index++) { Aig_Obj_t* final_skolem_function; final_skolem_function = searchOneDimensionalMatrix(SkolemFunctions, number_of_vars_to_elim, var_to_elim_index); assert(final_skolem_function != NULL); #ifdef RECORD_KEEP int final_skolem_function_size = computeSize(final_skolem_function, pub_aig_manager); // AIG Manager API Call sum_of_skolem_function_sizes = sum_of_skolem_function_sizes + final_skolem_function_size; #endif } performReverseSubstitutionOfSkolemFunctions(); if(checkTimeOut()) // check for time-out { cout << "\nWarning!!Time-out inside the function AIGBasedSkolem::factorizedSkolemFunctionGenerator\n"; timed_out = true; // timed_out flag set return; } for(int var_to_elim_index = 1; var_to_elim_index <= number_of_vars_to_elim; var_to_elim_index++) { Aig_Obj_t* final_skolem_function; final_skolem_function = searchOneDimensionalMatrix(SkolemFunctions, number_of_vars_to_elim, var_to_elim_index); assert(final_skolem_function != NULL); #ifdef RECORD_KEEP int final_skolem_function_size = computeSize(final_skolem_function, pub_aig_manager); // AIG Manager API Call skolem_function_sizes_after_reverse_substitution.push_back(final_skolem_function_size); sum_of_skolem_function_sizes_after_reverse_substitution = sum_of_skolem_function_sizes_after_reverse_substitution + final_skolem_function_size; #endif #ifdef PRINT_SKOLEM_FUNCTIONS string skolem_function_file_name = benchmark_name_without_extension; skolem_function_file_name += "_skolem_function_after_reverse_substitution"; writeFormulaToFile(pub_aig_manager, final_skolem_function, skolem_function_file_name, ".v", var_to_elim_index, 0); #endif } } gettimeofday (&cegar_step_finish_ms, NULL); total_time_in_reverse_substitution_in_cegar = cegar_step_finish_ms.tv_sec * 1000 + cegar_step_finish_ms.tv_usec / 1000; total_time_in_reverse_substitution_in_cegar -= cegar_step_start_ms.tv_sec * 1000 + cegar_step_start_ms.tv_usec / 1000; size_computation_time_in_reverse_substitution_in_cegar = total_time_in_compute_size - size_computation_time_in_initial_abstraction_generation_in_cegar - size_computation_time_in_initialization - size_computation_time_in_cegar_loops_in_cegar - size_computation_time_in_connection_substitution_in_cegar; total_time_in_reverse_substitution_in_cegar = total_time_in_reverse_substitution_in_cegar - size_computation_time_in_reverse_substitution_in_cegar; if(prove_correctness_of_skolem_functions || prove_correctness_of_skolem_functions_in_only_easy_direction) { if(conjunction_of_factors == NULL) { conjunction_of_factors = createAnd(Factors, pub_aig_manager); } assert(conjunction_of_factors != NULL); map skolem_function_replacement_map; for(int var_to_elim_index = 1; var_to_elim_index <= number_of_vars_to_elim; var_to_elim_index++) { Aig_Obj_t* skolem_function_at_var_to_elim_index; skolem_function_at_var_to_elim_index = searchOneDimensionalMatrix(SkolemFunctions, number_of_vars_to_elim, var_to_elim_index); assert(skolem_function_at_var_to_elim_index != NULL); skolem_function_replacement_map.insert(make_pair(var_to_elim_index, skolem_function_at_var_to_elim_index)); } assert(skolem_function_replacement_map.size() > 0); Aig_Obj_t* result_of_qe_using_skolem_functions; result_of_qe_using_skolem_functions = replaceVariablesByFormulas(conjunction_of_factors, skolem_function_replacement_map); assert(result_of_qe_using_skolem_functions != NULL); bool formulas_equivalent = checkEquivalenceUsingQBFSolver(result_of_qe_using_skolem_functions, conjunction_of_factors, VariablesToEliminate, pub_aig_manager); string record_file; record_file = logfile_prefix; record_file += "skolem_function_generation_details.txt"; FILE* record_fp = fopen(record_file.c_str(), "a+"); assert(record_fp != NULL); if(formulas_equivalent) { if(prove_correctness_of_skolem_functions_in_only_easy_direction) { cout << "\nSkolem functions are exact in one(easy) direction\n"; fprintf(record_fp, "\n\nexists X.f(X,Y) => f'(psi,Y) is valid; Skolem functions are exact\n"); } else { cout << "\nSkolem functions are exact\n"; fprintf(record_fp, "\n\nexists X.f(X,Y) = f'(psi,Y) is valid; Skolem functions are exact\n"); } } else { cout << "\nSkolem functions are NOT exact\n"; if(prove_correctness_of_skolem_functions_in_only_easy_direction) { fprintf(record_fp, "\n\nexists X.f(X,Y) => f'(psi,Y) is NOT valid; Skolem functions are NOT exact\n"); } else { fprintf(record_fp, "\n\nexists X.f(X,Y) = f'(psi,Y) is NOT valid; Skolem functions are NOT exact\n"); } } fclose(record_fp); }//if(prove_correctness_of_skolem_functions) ends here } void AIGBasedSkolem::findFactorsWithVariable(int var_to_elim_index) { #ifdef DEBUG_SKOLEM cout << "\nfinding factors with variable_" << var_to_elim_index << endl; #endif #ifdef DEBUG_CEGAR cout << "\nFactors\n"; #endif FactorsWithVariable.clear(); for(int factor_index = 1; factor_index <= number_of_factors; factor_index++) { Aig_Obj_t* factor = searchOneDimensionalMatrix(FactorMatrix, number_of_factors, factor_index); assert(factor != NULL); #ifdef DEBUG_SKOLEM writeFormulaToFile(pub_aig_manager, factor, "factor", ".v", var_to_elim_index, factor_index); #endif if(!formulaFreeOfVariable(factor, var_to_elim_index)) { FactorsWithVariable.insert(factor_index); #ifdef DETAILED_RECORD_KEEP int factor_size = computeSize(factor, pub_aig_manager); // AIG Manager API call sizes_of_factors_with_variable.push_back(factor_size); #endif #ifdef PRINT_VERY_DETAILED_RECORDS_ON_SCREEN cout << "\nfactor_ " << factor_index << " of size " << factor_size << " encountered with variable_" << var_to_elim_index << endl; #endif } #ifdef DEBUG_CEGAR int factor_size = computeSize(factor, pub_aig_manager); // AIG Manager API call cout << "(" << factor_index << ")" << factor_size << "\t"; #endif } #ifdef DEBUG_CEGAR cout << "\nIndices of factors with variable\n"; showSet(FactorsWithVariable, "FactorsWithVariable"); #endif #ifdef DEBUG_SKOLEM showSet(FactorsWithVariable, "FactorsWithVariable"); #endif } Aig_Obj_t* AIGBasedSkolem::computeAlpha(int var_to_elim_index, int factor_index) { // check if entry already exists in the matrix Aig_Obj_t* alpha; alpha = searchOneDimensionalMatrix(AlphaMatrix, number_of_factors, factor_index); if(alpha != NULL) { return alpha; } else { // hash table miss #ifdef PRINT_VERY_DETAILED_RECORDS_ON_SCREEN cout << "\nhash table miss in AIGBasedSkolem::computeAlpha(" << var_to_elim_index <<", "<< factor_index <<")\n"; #endif // alpha_i_j = (factor_i_j with var_i = true) \wedge (\neg factor_i_j with var_i = false) // compute cofactor_1 = factor_i_j with var_i = true Aig_Obj_t* cofactor_1 = computeCofactorOne(var_to_elim_index, factor_index); assert(cofactor_1 != NULL); // compute neg_cofactor_0 = not(factor_i_j with var_i = false) Aig_Obj_t* neg_cofactor_0 = computeNegatedCofactorZero(var_to_elim_index, factor_index); assert(neg_cofactor_0 != NULL); alpha = createAnd(cofactor_1, neg_cofactor_0, pub_aig_manager); // AIG Manager API Call assert(alpha != NULL); // Enter into matrix insertIntoOneDimensionalMatrix(AlphaMatrix, number_of_factors, factor_index, alpha, false); return alpha; } } Aig_Obj_t* AIGBasedSkolem::computeBeta(int var_to_elim_index, int factor_index) { // check if entry already exists in the matrix Aig_Obj_t* beta; beta = searchOneDimensionalMatrix(BetaMatrix, number_of_factors, factor_index); if(beta != NULL) { return beta; } else { // hash table miss #ifdef PRINT_VERY_DETAILED_RECORDS_ON_SCREEN cout << "\nhash table miss in AIGBasedSkolem::computeBeta(" << var_to_elim_index <<", "<< factor_index <<")\n"; #endif // beta_i_j = (factor_i_j with var_i = false) \wedge (\neg factor_i_j with var_i = true) // compute cofactor_0 = factor_i_j with var_i = false Aig_Obj_t* cofactor_0 = computeCofactorZero(var_to_elim_index, factor_index); assert(cofactor_0 != NULL); // compute neg_cofactor_1 = not(factor_i_j with var_i = true) Aig_Obj_t* neg_cofactor_1 = computeNegatedCofactorOne(var_to_elim_index, factor_index); assert(neg_cofactor_1 != NULL); beta = createAnd(cofactor_0, neg_cofactor_1, pub_aig_manager); // AIG Manager API Call assert(beta != NULL); // Enter into matrix insertIntoOneDimensionalMatrix(BetaMatrix, number_of_factors, factor_index, beta, false); return beta; } } Aig_Obj_t* AIGBasedSkolem::computeGamma(int var_to_elim_index, int factor_index) { // check if entry already exists in the matrix Aig_Obj_t* gamma; gamma = searchOneDimensionalMatrix(GammaMatrix, number_of_factors, factor_index); if(gamma != NULL) { return gamma; } else { // hash table miss #ifdef PRINT_VERY_DETAILED_RECORDS_ON_SCREEN cout << "\nhash table miss in AIGBasedSkolem::computeGamma(" << var_to_elim_index <<", "<< factor_index <<")\n"; #endif // gamma_i_j = (factor_i_j with var_i = false) \wedge (factor_i_j with var_i = true) // compute cofactor_0 = factor_i_j with var_i = false Aig_Obj_t* cofactor_0 = computeCofactorZero(var_to_elim_index, factor_index); assert(cofactor_0 != NULL); // compute cofactor_1 = factor_i_j with var_i = true Aig_Obj_t* cofactor_1 = computeCofactorOne(var_to_elim_index, factor_index); assert(cofactor_1 != NULL); gamma = createAnd(cofactor_0, cofactor_1, pub_aig_manager); // AIG Manager API Call assert(gamma != NULL); // Enter into matrix insertIntoOneDimensionalMatrix(GammaMatrix, number_of_factors, factor_index, gamma, false); return gamma; } } Aig_Obj_t* AIGBasedSkolem::computeDelta(int var_to_elim_index, int factor_index) { // check if entry already exists in the matrix Aig_Obj_t* delta; delta = searchOneDimensionalMatrix(DeltaMatrix, number_of_factors, factor_index); if(delta != NULL) { return delta; } else { // hash table miss #ifdef PRINT_VERY_DETAILED_RECORDS_ON_SCREEN cout << "\nhash table miss in AIGBasedSkolem::computeDelta(" << var_to_elim_index <<", "<< factor_index <<")\n"; #endif // delta_i_j = (\neg factor_i_j with var_i = false) \wedge (\neg factor_i_j with var_i = true) // compute negated_cofactor_0 = not(factor_i_j with var_i = false) Aig_Obj_t* negated_cofactor_0 = computeNegatedCofactorZero(var_to_elim_index, factor_index); assert(negated_cofactor_0 != NULL); // compute negated_cofactor_1 = not(factor_i_j with var_i = true) Aig_Obj_t* negated_cofactor_1 = computeNegatedCofactorOne(var_to_elim_index, factor_index); assert(negated_cofactor_1 != NULL); delta = createAnd(negated_cofactor_0, negated_cofactor_1, pub_aig_manager); // AIG Manager API Call assert(delta != NULL); // Enter into matrix insertIntoOneDimensionalMatrix(DeltaMatrix, number_of_factors, factor_index, delta, false); return delta; } } Aig_Obj_t* AIGBasedSkolem::computeCofactorOne(int var_to_elim_index, int factor_index) { // check if entry already exists in the matrix Aig_Obj_t* cofactor_1; cofactor_1 = searchOneDimensionalMatrix(CofactorOneMatrix, number_of_factors, factor_index); if(cofactor_1 != NULL) { return cofactor_1; } else { // hash table miss #ifdef PRINT_VERY_DETAILED_RECORDS_ON_SCREEN cout << "\nhash table miss in AIGBasedSkolem::computeCofactorOne(" << var_to_elim_index <<", "<< factor_index <<")\n"; #endif // compute cofactor_1 = factor_i_j with var_i = true Aig_Obj_t* factor = searchOneDimensionalMatrix(FactorMatrix, number_of_factors, factor_index); assert(factor != NULL); cofactor_1 = replaceVariableByConstant(factor, var_to_elim_index, 1); assert(cofactor_1 != NULL); // Enter into matrix insertIntoOneDimensionalMatrix(CofactorOneMatrix, number_of_factors, factor_index, cofactor_1, false); return cofactor_1; } } Aig_Obj_t* AIGBasedSkolem::computeNegatedCofactorOne(int var_to_elim_index, int factor_index) { // compute cofactor_1 Aig_Obj_t* cofactor_1 = computeCofactorOne(var_to_elim_index, factor_index); assert(cofactor_1 != NULL); Aig_Obj_t* neg_cofactor_1 = createNot(cofactor_1, pub_aig_manager); // AIG Manager API Call assert(neg_cofactor_1 != NULL); return neg_cofactor_1; } Aig_Obj_t* AIGBasedSkolem::computeCofactorZero(int var_to_elim_index, int factor_index) { // check if entry already exists in the matrix Aig_Obj_t* cofactor_0; cofactor_0 = searchOneDimensionalMatrix(CofactorZeroMatrix, number_of_factors, factor_index); if(cofactor_0 != NULL) { return cofactor_0; } else { // hash table miss #ifdef PRINT_VERY_DETAILED_RECORDS_ON_SCREEN cout << "\nhash table miss in AIGBasedSkolem::computeCofactorZero(" << var_to_elim_index <<", "<< factor_index <<")\n"; #endif // compute cofactor_0 = factor_i_j with var_i = false Aig_Obj_t* factor = searchOneDimensionalMatrix(FactorMatrix, number_of_factors, factor_index); assert(factor != NULL); cofactor_0 = replaceVariableByConstant(factor, var_to_elim_index, 0); assert(cofactor_0 != NULL); // Enter into matrix insertIntoOneDimensionalMatrix(CofactorZeroMatrix, number_of_factors, factor_index, cofactor_0, false); return cofactor_0; } } Aig_Obj_t* AIGBasedSkolem::computeNegatedCofactorZero(int var_to_elim_index, int factor_index) { // compute cofactor_0 Aig_Obj_t* cofactor_0 = computeCofactorZero(var_to_elim_index, factor_index); assert(cofactor_0 != NULL); Aig_Obj_t* neg_cofactor_0 = createNot(cofactor_0, pub_aig_manager); // AIG Manager API Call assert(neg_cofactor_0 != NULL); return neg_cofactor_0; } bool AIGBasedSkolem::formulaFreeOfVariable(Aig_Obj_t* formula, int var_index) { #ifdef DEBUG_SKOLEM cout << "\nchecking if formula is free of variable_" << var_index << endl; #endif // sanity checks assert(formula != NULL); assert(var_index >= 1); // obtain the adress of the variable object string var_string = searchVarIndexToVarNameMap(var_index_to_var_name_map, var_index); number_of_support_operations_for_variable++; set support; computeSupport(formula, support, pub_aig_manager); // AIG Manager API Call if(support.find(var_string) == support.end()) // formula is free of var_string { return true; } else { return false; } } Aig_Obj_t* AIGBasedSkolem::replaceVariableByConstant(Aig_Obj_t* OriginalFormula, int var_index_to_replace, int constant_to_substitute) { #ifdef RECORD_KEEP number_of_compose_operations_for_variable++; #endif #ifdef DETAILED_RECORD_KEEP unsigned long long int step_ms; struct timeval step_start_ms, step_finish_ms; gettimeofday (&step_start_ms, NULL); #endif // sanity checks assert(OriginalFormula != NULL); assert(var_index_to_replace >= 1); assert(constant_to_substitute == 0 || constant_to_substitute == 1); Aig_Obj_t* FormulaToSubstitute; if(constant_to_substitute == 0) // replace by zero { FormulaToSubstitute = createFalse(pub_aig_manager); // AIG Manager API Call } else // replace by one { FormulaToSubstitute = createTrue(pub_aig_manager); // AIG Manager API Call } assert(FormulaToSubstitute != NULL); string var_to_replace = searchVarIndexToVarNameMap(var_index_to_var_name_map, var_index_to_replace); Aig_Obj_t* ReplacedFormula = ReplaceLeafByExpression(OriginalFormula, var_to_replace, FormulaToSubstitute, pub_aig_manager); // AIG Manager API Call assert(ReplacedFormula != NULL); #ifdef DETAILED_RECORD_KEEP gettimeofday (&step_finish_ms, NULL); step_ms = step_finish_ms.tv_sec * 1000 + step_finish_ms.tv_usec / 1000; step_ms -= step_start_ms.tv_sec * 1000 + step_start_ms.tv_usec / 1000; ComposeTime += step_ms; #endif #ifdef PRINT_VERY_DETAILED_RECORDS_ON_SCREEN cout << "\nreplaceVariableByConstant finished in " << step_ms << " milliseconds\n"; #endif return ReplacedFormula; } Aig_Obj_t* AIGBasedSkolem::replaceVariableByFormula(Aig_Obj_t* OriginalFormula, int var_index_to_replace, Aig_Obj_t* FormulaToSubstitute) { #ifdef RECORD_KEEP number_of_compose_operations_for_variable++; #endif #ifdef DETAILED_RECORD_KEEP unsigned long long int step_ms; struct timeval step_start_ms, step_finish_ms; gettimeofday (&step_start_ms, NULL); #endif // sanity checks assert(OriginalFormula != NULL); assert(var_index_to_replace >= 1); assert(FormulaToSubstitute != NULL); string var_to_replace = searchVarIndexToVarNameMap(var_index_to_var_name_map, var_index_to_replace); Aig_Obj_t* ReplacedFormula = ReplaceLeafByExpression(OriginalFormula, var_to_replace, FormulaToSubstitute, pub_aig_manager); // AIG Manager API Call assert(ReplacedFormula != NULL); #ifdef DETAILED_RECORD_KEEP gettimeofday (&step_finish_ms, NULL); step_ms = step_finish_ms.tv_sec * 1000 + step_finish_ms.tv_usec / 1000; step_ms -= step_start_ms.tv_sec * 1000 + step_start_ms.tv_usec / 1000; ComposeTime += step_ms; #endif #ifdef PRINT_VERY_DETAILED_RECORDS_ON_SCREEN cout << "\nreplaceVariableByFormula finished in " << step_ms << " milliseconds\n"; #endif return ReplacedFormula; } Aig_Obj_t* AIGBasedSkolem::replaceVariablesByFormulas(Aig_Obj_t* OriginalFormula, map &replacement_map) { Aig_Obj_t* original_formula = OriginalFormula; for(map::iterator map_it = replacement_map.begin(); map_it != replacement_map.end(); map_it++) { int var_index_to_replace = map_it->first; Aig_Obj_t* formula_to_substitute = map_it->second; assert(original_formula != NULL); assert(formula_to_substitute != NULL); Aig_Obj_t* replaced_formula = replaceVariableByFormula(original_formula, var_index_to_replace, formula_to_substitute); original_formula = replaced_formula; } return original_formula; } void AIGBasedSkolem::clearVariableSpecificDataStructures() { #ifdef DETAILED_RECORD_KEEP for(set::iterator factor_it = FactorsWithVariable.begin(); factor_it != FactorsWithVariable.end(); factor_it++) { PreviousFactorsWithVariable.insert(*factor_it); } #endif FactorsWithVariable.clear(); CofactorOneMatrix.clear(); CofactorZeroMatrix.clear(); AlphaMatrix.clear(); BetaMatrix.clear(); GammaMatrix.clear(); DeltaMatrix.clear(); } void AIGBasedSkolem::performReverseSubstitutionOfSkolemFunctions() { for(int i = number_of_vars_to_elim; i >= 2; i--) { if(checkTimeOut()) // check for time-out { cout << "\nWarning!!Time-out inside the function AIGBasedSkolem::performReverseSubstitutionOfSkolemFunctions()\n"; timed_out = true; // timed_out flag set return; } Aig_Obj_t* skolem_function_to_substitute; skolem_function_to_substitute = searchOneDimensionalMatrix(SkolemFunctions, number_of_vars_to_elim, i); assert(skolem_function_to_substitute != NULL); cout << "\nReplacing variable_" << i << " by its skolem function in the skolem function for preceding variables" << endl; for(int j = i-1; j >= 1; j--) { if(checkTimeOut()) // check for time-out { cout << "\nWarning!!Time-out inside the function AIGBasedSkolem::performReverseSubstitutionOfSkolemFunctions()\n"; timed_out = true; // timed_out flag set return; } Aig_Obj_t* destination_skolem_function; destination_skolem_function = searchOneDimensionalMatrix(SkolemFunctions, number_of_vars_to_elim, j); assert(destination_skolem_function != NULL); #ifdef PRINT_VERY_DETAILED_RECORDS_ON_SCREEN cout << "\nReplacing variable_" << i << " by its skolem function in the skolem function for variable_" << j << endl; #endif #ifdef DEBUG_SKOLEM writeFormulaToFile(pub_aig_manager, destination_skolem_function, "dest_sk_function", ".v", i, j); #endif destination_skolem_function = replaceVariableByFormula(destination_skolem_function, i, skolem_function_to_substitute); assert(destination_skolem_function != NULL); #ifdef DEBUG_SKOLEM writeFormulaToFile(pub_aig_manager, destination_skolem_function, "dest_sk_function_rev_subst", ".v", i, j); #endif insertIntoOneDimensionalMatrix(SkolemFunctions, number_of_vars_to_elim, j, destination_skolem_function, true); }//for ends here }// for ends here #ifdef RECORD_KEEP total_time_in_compose_operations = total_time_in_compose_operations + ComposeTime; total_number_of_compose_operations = total_number_of_compose_operations + number_of_compose_operations_for_variable; #endif }// function ends here Aig_Obj_t* AIGBasedSkolem::computeAlphaCombinedOrGammaCombined(int var_to_elim_index) { // Let us compute alpha_combined_{var_to_elim_index}\vee gamma_combined_{var_to_elim_index} // Suppose i = var_to_elim_index // i.e. we need to compute alpha_combined_{i}\vee gamma_combined_{i} // i.e., conjunction of alpha_combined_or_gamma_combined_components // Each alpha_combined_or_gamma_combined_component_i_j = co-factor-1_i_j set alpha_combined_or_gamma_combined_components; #ifdef DEBUG_SKOLEM cout << "\ncomputing components of alpha_combined_or_gamma_combined\n"; #endif #ifdef PRINT_VERY_DETAILED_RECORDS_ON_SCREEN cout << "\ncomputing components of alpha_combined_or_gamma_combined\n"; #endif #ifdef RECORD_KEEP int number_of_factors_containing_var_to_elim_index = FactorsWithVariable.size(); #endif for(set::iterator factor_it = FactorsWithVariable.begin(); factor_it != FactorsWithVariable.end(); factor_it++) { int factor_index = *factor_it; #ifdef DEBUG_SKOLEM cout << "\nfactor_index = " << factor_index << endl; #endif // Suppose j = factor_index // Each alpha_combined_or_gamma_combined_component_i_j = co-factor-1_i_j Aig_Obj_t* cofactor_1_i_j; cofactor_1_i_j = computeCofactorOne(var_to_elim_index, factor_index); assert(cofactor_1_i_j != NULL); Aig_Obj_t* alpha_combined_or_gamma_combined_component = cofactor_1_i_j; #ifdef DEBUG_SKOLEM writeFormulaToFile(pub_aig_manager, alpha_combined_or_gamma_combined_component, "alpha_combined_or_gamma_combined_component", ".v", var_to_elim_index, factor_index); cout << "\nalpha_combined_or_gamma_combined_component[" << var_to_elim_index << ", " << factor_index << "] obtained\n"; #endif #ifdef PRINT_VERY_DETAILED_RECORDS_ON_SCREEN cout << "\nalpha_combined_or_gamma_combined_component[" << var_to_elim_index << ", " << factor_index << "] obtained\n"; cout << "\nsize of alpha_combined_or_gamma_combined_component[" << var_to_elim_index << ", " << factor_index << "] is: " << computeSize(alpha_combined_or_gamma_combined_component, pub_aig_manager) << endl; #endif alpha_combined_or_gamma_combined_components.insert(alpha_combined_or_gamma_combined_component); FactorsAffectingSkolemFunction.push_back(factor_index); }// for each factor ends here // recall that alpha_combined_or_gamma_combined = conjunction of alpha_combined_or_gamma_combined_components Aig_Obj_t* alpha_combined_or_gamma_combined; if(alpha_combined_or_gamma_combined_components.size() == 0) // we should return true in this case as per the defn. of alpha_combined_or_gamma_combined { alpha_combined_or_gamma_combined = createTrue(pub_aig_manager); assert(alpha_combined_or_gamma_combined != NULL); } else { alpha_combined_or_gamma_combined = createAnd(alpha_combined_or_gamma_combined_components, pub_aig_manager); assert(alpha_combined_or_gamma_combined != NULL); } #ifdef DEBUG_SKOLEM writeFormulaToFile(pub_aig_manager, alpha_combined_or_gamma_combined, "alpha_combined_or_gamma_combined", ".v", var_to_elim_index, 0); #endif #ifdef RECORD_KEEP NumberOfFactors = number_of_factors_containing_var_to_elim_index; #endif return alpha_combined_or_gamma_combined; } // function ends here void AIGBasedSkolem::printFactorGraph(set &Final_VariablesToEliminate_Set) { string dot_file_name = benchmark_name_without_extension; dot_file_name += "_factor_graph.dot"; fstream file_op(dot_file_name.c_str(),ios::out); file_op << "digraph G {" << endl; set PrintedVariables; for(int factor_index = 1; factor_index <= number_of_factors; factor_index++) { // Suppose j = factor_index // first let us obtain factor_1_j Aig_Obj_t* factor_1_j = searchOneDimensionalMatrix(FactorMatrix, number_of_factors, factor_index); assert(factor_1_j != NULL); set support; computeSupport(factor_1_j, support, pub_aig_manager); file_op << "f" << factor_index <<"[shape=square, color=red, label=\""<< "f_"<< factor_index <<"\"];"<::iterator support_it = support.begin(); support_it != support.end(); support_it++) { string variable = *support_it; if(Final_VariablesToEliminate_Set.find(variable) != Final_VariablesToEliminate_Set.end()) // this is a variable to be eliminated { if(PrintedVariables.find(variable) == PrintedVariables.end()) //not already printed { file_op << variable <<"[color=green, label=\""<< variable <<"\"];"<" << variable << "[dir=none];" << endl; } else // this is a variable to remain { // do not do anything } } }//for each factor ends here file_op << "}" << endl; file_op.close(); }// function ends here void AIGBasedSkolem::printFactorGraphAsData(set &Final_VariablesToEliminate_Set) { string dat_file_name = benchmark_name_without_extension; dat_file_name += "_factor_graph.dat"; fstream file_op(dat_file_name.c_str(),ios::out); for(int factor_index = 1; factor_index <= number_of_factors; factor_index++) { // Suppose j = factor_index // first let us obtain factor_1_j Aig_Obj_t* factor_1_j = searchOneDimensionalMatrix(FactorMatrix, number_of_factors, factor_index); assert(factor_1_j != NULL); set support; computeSupport(factor_1_j, support, pub_aig_manager); for(set::iterator support_it = support.begin(); support_it != support.end(); support_it++) { string variable = *support_it; if(Final_VariablesToEliminate_Set.find(variable) != Final_VariablesToEliminate_Set.end()) // this is a variable to be eliminated { int variable_index = searchVarNameToVarIndexMap(var_name_to_var_index_map, variable); file_op << factor_index <<"\t"<< variable_index << endl; } else // this is a variable to remain { // do not do anything } } }//for each factor ends here file_op.close(); }// function ends here Aig_Obj_t* AIGBasedSkolem::computeSkolemFunctionUsingBadSet(int var_to_elim_index, Aig_Obj_t* &cofactor_one_of_bad_set) { // skolem function = (conjunction of co-factor-1's of factors with var_to_elim_index) \wedge (cofactor-1 of \neg bad_set) #ifdef RECORD_KEEP unsigned long long int alpha_duration_ms, delta_duration_ms; struct timeval start_ms, finish_ms; #endif #ifdef RECORD_KEEP gettimeofday (&start_ms, NULL); #endif // computing alpha_combined_or_gamma_combined{var_to_elim_index} #ifdef DEBUG_SKOLEM cout << "\ncomputing alpha_combined_or_gamma_combined_" << var_to_elim_index << "\n"; #endif Aig_Obj_t* alpha_combined_or_gamma_combined; if(!use_bad_in_perform_cofactor_based_quantifier_elimination_along_with_skolem_function_generation && skolem_function_type_in_jiang == "cofactorone_or_negcofactorzero") { alpha_combined_or_gamma_combined = computeCofactorOneOrNegCofactorZero(var_to_elim_index); } else { alpha_combined_or_gamma_combined = computeAlphaCombinedOrGammaCombined(var_to_elim_index); } assert(alpha_combined_or_gamma_combined != NULL); if(checkTimeOut()) // check for time-out { cout << "\nWarning!!Time-out inside the function AIGBasedSkolem::computeSkolemFunction\n"; timed_out = true; // timed_out flag set return NULL; } #ifdef DEBUG_SKOLEM cout << "\nalpha_combined_or_gamma_combined_" << var_to_elim_index << " computed\n"; #endif #ifdef RECORD_KEEP gettimeofday (&finish_ms, NULL); alpha_duration_ms = finish_ms.tv_sec * 1000 + finish_ms.tv_usec / 1000; alpha_duration_ms -= start_ms.tv_sec * 1000 + start_ms.tv_usec / 1000; AlphaCombGenTime = alpha_duration_ms; #endif #ifdef DETAILED_RECORD_KEEP cout << "\ncomputeAlphaCombinedOrGammaCombined finished in " << alpha_duration_ms << "milli seconds\n"; #endif #ifdef PRINT_VERY_DETAILED_RECORDS_ON_SCREEN cout << "\nsize of alpha_combined_or_gamma_combined is " << computeSize(alpha_combined_or_gamma_combined, pub_aig_manager) << endl; #endif #ifdef RECORD_KEEP AlphaPartSize = computeSize(alpha_combined_or_gamma_combined, pub_aig_manager); #endif // computing cofactor-1 of bad part #ifdef RECORD_KEEP gettimeofday (&start_ms, NULL); #endif // computing bad_part_{var_to_elim_index} #ifdef DEBUG_SKOLEM cout << "\ncomputing bad_part_" << var_to_elim_index << "\n"; #endif Aig_Obj_t* bad_part; if(use_bad_in_perform_cofactor_based_quantifier_elimination_along_with_skolem_function_generation && !formulaFreeOfVariable(aig_bad_set, var_to_elim_index)) { // replace var_to_elim_index in aig_bad_set by one Aig_Obj_t* cofactor_one = replaceVariableByConstant(aig_bad_set, var_to_elim_index, 1); assert(cofactor_one != NULL); cofactor_one_of_bad_set = cofactor_one; bad_part = createNot(cofactor_one, pub_aig_manager); assert(bad_part != NULL); } else { cofactor_one_of_bad_set = aig_bad_set; bad_part = createTrue(pub_aig_manager); assert(bad_part != NULL); } #ifdef DEBUG_SKOLEM cout << "\nbad_part computed\n"; writeFormulaToFile(pub_aig_manager, bad_part, "bad_part", ".v", var_to_elim_index, 0); #endif #ifdef RECORD_KEEP gettimeofday (&finish_ms, NULL); delta_duration_ms = finish_ms.tv_sec * 1000 + finish_ms.tv_usec / 1000; delta_duration_ms -= start_ms.tv_sec * 1000 + start_ms.tv_usec / 1000; DeltaPartGenTime = delta_duration_ms; #endif #ifdef DETAILED_RECORD_KEEP cout << "\ncomputing delta part finished in " << delta_duration_ms << "milli seconds\n"; #endif #ifdef PRINT_VERY_DETAILED_RECORDS_ON_SCREEN cout << "\nsize of bad_part is " << computeSize(bad_part, pub_aig_manager) << endl; #endif #ifdef RECORD_KEEP DeltaPartSize = computeSize(bad_part, pub_aig_manager); #endif //computing skolem_function Aig_Obj_t* skolem_function; // skolem_function = alpha_combined_or_gamma_combined \wedge bad_part skolem_function = createAnd(alpha_combined_or_gamma_combined, bad_part, pub_aig_manager); assert(skolem_function != NULL); #ifdef DEBUG_SKOLEM cout << "\nskolem_function computed\n"; #endif #ifdef PRINT_SKOLEM_FUNCTIONS string skolem_function_file_name = benchmark_name_without_extension; skolem_function_file_name += "_skolem_function"; writeFormulaToFile(pub_aig_manager, skolem_function, skolem_function_file_name, ".v", var_to_elim_index, 0); #endif // Enter into matrix insertIntoOneDimensionalMatrix(SkolemFunctions, number_of_vars_to_elim, var_to_elim_index, skolem_function, false); return skolem_function; } void AIGBasedSkolem::updateBadSet(int var_to_elim_index, Aig_Obj_t* cofactor_one_of_bad_set) { // bad_set = (disjunction of alpha's of factors with var_to_elim_index \vee co-factor-0 of bad_set)\wedge // (disjunction of beta's of factors with var_to_elim_index \vee co-factor-1 of bad_set) #ifdef DEBUG_SKOLEM cout << "\nupdating aig_bad_set\n"; #endif set alpha_components; set beta_components; for(set::iterator factor_it = FactorsWithVariable.begin(); factor_it != FactorsWithVariable.end(); factor_it++) { int factor_index = *factor_it; #ifdef DEBUG_SKOLEM cout << "\nfactor_index = " << factor_index << endl; #endif // Suppose j = factor_index // Get alpha_i_j and beta_i_j Aig_Obj_t* alpha_i_j; alpha_i_j = computeAlpha(var_to_elim_index, factor_index); assert(alpha_i_j != NULL); #ifdef DEBUG_SKOLEM writeFormulaToFile(pub_aig_manager, alpha_i_j, "alpha", ".v", var_to_elim_index, factor_index); cout << "\nalpha_" << var_to_elim_index << "_" << factor_index << " obtained\n"; #endif Aig_Obj_t* beta_i_j; beta_i_j = computeBeta(var_to_elim_index, factor_index); assert(beta_i_j != NULL); #ifdef DEBUG_SKOLEM writeFormulaToFile(pub_aig_manager, beta_i_j, "beta", ".v", var_to_elim_index, factor_index); cout << "\nbeta_" << var_to_elim_index << "_" << factor_index << " obtained\n"; #endif alpha_components.insert(alpha_i_j); beta_components.insert(beta_i_j); }// for each factor ends here if(checkTimeOut()) // check for time-out { cout << "\nWarning!!Time-out inside the function AIGBasedSkolem::updateBadSet\n"; timed_out = true; // timed_out flag set return; } if(!formulaFreeOfVariable(aig_bad_set, var_to_elim_index)) { // replace var_to_elim_index in bad_set by zero // we already have cofactor_one Aig_Obj_t* cofactor_zero = replaceVariableByConstant(aig_bad_set, var_to_elim_index, 0); assert(cofactor_zero != NULL); alpha_components.insert(cofactor_zero); beta_components.insert(cofactor_one_of_bad_set); } else { alpha_components.insert(aig_bad_set); beta_components.insert(aig_bad_set); } Aig_Obj_t* alpha_part; alpha_part = createOr(alpha_components, pub_aig_manager); assert(alpha_part != NULL); Aig_Obj_t* beta_part; beta_part = createOr(beta_components, pub_aig_manager); assert(beta_part != NULL); aig_bad_set = createAnd(alpha_part, beta_part, pub_aig_manager); assert(aig_bad_set != NULL); #ifdef DEBUG_SKOLEM cout << "\nbad_set computed\n"; writeFormulaToFile(pub_aig_manager, aig_bad_set, "bad_set", ".v", var_to_elim_index, 0); #endif #ifdef RECORD_KEEP DeltaCombinedSize = computeSize(aig_bad_set, pub_aig_manager); #endif #ifdef PRINT_VERY_DETAILED_RECORDS_ON_SCREEN cout << "\nsize of bad_set is " << DeltaCombinedSize << endl; #endif if(checkTimeOut()) // check for time-out { cout << "\nWarning!!Time-out inside the function AIGBasedSkolem::updateBadSet\n"; timed_out = true; // timed_out flag set return; } } void AIGBasedSkolem::updateFactorsWithoutComposition(int var_to_elim_index) { assert(var_to_elim_index < number_of_vars_to_elim); for(set::iterator factor_it = FactorsWithVariable.begin(); factor_it != FactorsWithVariable.end(); factor_it++) { int factor_index = *factor_it; #ifdef DEBUG_SKOLEM cout << "\nfactor_index = " << factor_index << endl; #endif // obtain the existing factor Aig_Obj_t* previous_factor; previous_factor = searchOneDimensionalMatrix(FactorMatrix, number_of_factors, factor_index); assert(previous_factor != NULL); #ifdef DEBUG_SKOLEM writeFormulaToFile(pub_aig_manager, previous_factor, "factor", ".v", var_to_elim_index, factor_index); #endif Aig_Obj_t* delta; delta = computeDelta(var_to_elim_index, factor_index); assert(delta != NULL); Aig_Obj_t* factor = createNot(delta, pub_aig_manager); assert(factor != NULL); #ifdef DEBUG_SKOLEM writeFormulaToFile(pub_aig_manager, factor, "factor", ".v", var_to_elim_index+1, factor_index); #endif insertIntoOneDimensionalMatrix(FactorMatrix, number_of_factors, factor_index, factor, true); } } void AIGBasedSkolem::updateFactorsUsingQuantifierEliminatedResult(int var_to_elim_index, Aig_Obj_t* quantifier_eliminated_result) { assert(var_to_elim_index < number_of_vars_to_elim); int factor_count = 1; for(set::iterator factor_it = FactorsWithVariable.begin(); factor_it != FactorsWithVariable.end(); factor_it++) { int factor_index = *factor_it; #ifdef DEBUG_SKOLEM cout << "\nfactor_index = " << factor_index << endl; #endif Aig_Obj_t* factor; if(factor_count == FactorsWithVariable.size()) { factor = quantifier_eliminated_result; } else { factor = createTrue(pub_aig_manager); } assert(factor != NULL); #ifdef DEBUG_SKOLEM writeFormulaToFile(pub_aig_manager, factor, "factor", ".v", var_to_elim_index+1, factor_index); #endif insertIntoOneDimensionalMatrix(FactorMatrix, number_of_factors, factor_index, factor, true); factor_count++; } } Aig_Obj_t* AIGBasedSkolem::computeQuantifierEliminatedResultUsingCofactors(int var_to_elim_index) { // We need to compute (conjunction of co-factor-1_i_j's) \vee (conjunction of co-factor-0_i_j's) set cofactor_one_components; set cofactor_zero_components; #ifdef DEBUG_SKOLEM cout << "\ncomputing components of QuantifierEliminatedResult\n"; #endif #ifdef PRINT_VERY_DETAILED_RECORDS_ON_SCREEN cout << "\ncomputing components of QuantifierEliminatedResult\n"; #endif for(set::iterator factor_it = FactorsWithVariable.begin(); factor_it != FactorsWithVariable.end(); factor_it++) { int factor_index = *factor_it; #ifdef DEBUG_SKOLEM cout << "\nfactor_index = " << factor_index << endl; #endif // Suppose j = factor_index Aig_Obj_t* cofactor_1_i_j; cofactor_1_i_j = computeCofactorOne(var_to_elim_index, factor_index); assert(cofactor_1_i_j != NULL); cofactor_one_components.insert(cofactor_1_i_j); Aig_Obj_t* cofactor_0_i_j; cofactor_0_i_j = computeCofactorZero(var_to_elim_index, factor_index); assert(cofactor_0_i_j != NULL); cofactor_zero_components.insert(cofactor_0_i_j); }// for each factor ends here Aig_Obj_t* cofactor_one; if(cofactor_one_components.size() == 0) { cofactor_one = createTrue(pub_aig_manager); assert(cofactor_one != NULL); } else { cofactor_one = createAnd(cofactor_one_components, pub_aig_manager); assert(cofactor_one != NULL); } Aig_Obj_t* cofactor_zero; if(cofactor_zero_components.size() == 0) { cofactor_zero = createTrue(pub_aig_manager); assert(cofactor_zero != NULL); } else { cofactor_zero = createAnd(cofactor_zero_components, pub_aig_manager); assert(cofactor_zero != NULL); } Aig_Obj_t* QuantifierEliminatedResult = createOr(cofactor_one, cofactor_zero, pub_aig_manager); assert(QuantifierEliminatedResult != NULL); #ifdef DETAILED_RECORD_KEEP size_of_quantified_result_in_bdd_like_scheme = computeSize(QuantifierEliminatedResult, pub_aig_manager); cout << "\nSize of QuantifierEliminatedResult is " << size_of_quantified_result_in_bdd_like_scheme << endl; #endif #ifdef DEBUG_SKOLEM writeFormulaToFile(pub_aig_manager, QuantifierEliminatedResult, "QuantifierEliminatedResult", ".v", var_to_elim_index, 0); #endif return QuantifierEliminatedResult; } void AIGBasedSkolem::monolithicSkolemFunctionGeneratorWithScopeReduction(set &Factors, list &VariablesToEliminate) { #ifdef DETAILED_RECORD_KEEP unsigned long long int step_ms; struct timeval step_start_ms, step_finish_ms; gettimeofday (&step_start_ms, NULL); #endif initializeFactorizedSkolemFunctionGenerator(Factors, VariablesToEliminate); #ifdef DETAILED_RECORD_KEEP gettimeofday (&step_finish_ms, NULL); step_ms = step_finish_ms.tv_sec * 1000 + step_finish_ms.tv_usec / 1000; step_ms -= step_start_ms.tv_sec * 1000 + step_start_ms.tv_usec / 1000; cout << "\ninitializeFactorizedSkolemFunctionGenerator finished in " << step_ms << " milliseconds\n"; total_time_in_generator_initialization = step_ms; #endif cout << "\n#factors = " << number_of_factors << "\t#variables_to_eliminate = " << number_of_vars_to_elim << endl; // compute the skolem functions, i.e. fill the SkolemFunctions matrix for(int var_to_elim_index = 1; var_to_elim_index <= number_of_vars_to_elim; var_to_elim_index++) { if(checkTimeOut()) // check for time-out { cout << "\nWarning!!Time-out inside the function AIGBasedSkolem::monolithicSkolemFunctionGeneratorWithScopeReduction\n"; timed_out = true; // timed_out flag set return; } if(maximum_index_to_eliminate != -1) // to stop computation in between { if(var_to_elim_index > maximum_index_to_eliminate) { cout << "\nLet us stop here...\n"; break; } } #ifdef DEBUG_SKOLEM cout << "\ncomputing skolem_function_" << var_to_elim_index << endl; #endif #ifdef PRINT_VERY_DETAILED_RECORDS_ON_SCREEN cout << "\ncomputing skolem_function_" << var_to_elim_index << "\n"; #endif #ifdef RECORD_KEEP unsigned long long int duration_ms; struct timeval start_ms, finish_ms; gettimeofday (&start_ms, NULL); #endif #ifdef DETAILED_RECORD_KEEP gettimeofday (&step_start_ms, NULL); #endif findFactorsWithVariable(var_to_elim_index);// find the set of factors containing the variable if(checkTimeOut()) // check for time-out { cout << "\nWarning!!Time-out inside the function AIGBasedSkolem::monolithicSkolemFunctionGeneratorWithScopeReduction\n"; timed_out = true; // timed_out flag set return; } #ifdef DETAILED_RECORD_KEEP gettimeofday (&step_finish_ms, NULL); step_ms = step_finish_ms.tv_sec * 1000 + step_finish_ms.tv_usec / 1000; step_ms -= step_start_ms.tv_sec * 1000 + step_start_ms.tv_usec / 1000; cout << "\nfindFactorsWithVariable finished in " << step_ms << " milliseconds\n"; cout << "\nnumber of factors containing the variable = " << FactorsWithVariable.size() << endl; FactorFindingTime = step_ms; #endif #ifdef RECORD_KEEP NumberOfFactors = FactorsWithVariable.size(); #endif #ifdef DETAILED_RECORD_KEEP gettimeofday (&step_start_ms, NULL); #endif #ifdef PRINT_VERY_DETAILED_RECORDS_ON_SCREEN cout << "\nnumber of factors containing the variable = " << FactorsWithVariable.size() <<"\n"; #endif Aig_Obj_t* skolem_function; if(use_interpolant_as_skolem_function) { skolem_function = computeSkolemFunctionAsInterpolant(var_to_elim_index); } else { skolem_function = computeAlphaCombinedOrGammaCombined(var_to_elim_index); } if(checkTimeOut()) // check for time-out { cout << "\nWarning!!Time-out inside the function AIGBasedSkolem::monolithicSkolemFunctionGeneratorWithScopeReduction\n"; timed_out = true; // timed_out flag set return; } assert(skolem_function != NULL); #ifdef DETAILED_RECORD_KEEP gettimeofday (&step_finish_ms, NULL); step_ms = step_finish_ms.tv_sec * 1000 + step_finish_ms.tv_usec / 1000; step_ms -= step_start_ms.tv_sec * 1000 + step_start_ms.tv_usec / 1000; cout << "\ncomputing skolem function finished in " << step_ms << " milliseconds\n"; #endif #ifdef DETAILED_RECORD_KEEP gettimeofday (&step_start_ms, NULL); #endif if(var_to_elim_index != number_of_vars_to_elim) // We need to update the factor matrix { #ifdef DEBUG_SKOLEM cout << "\nupdating factors\n"; #endif updateFactorsUsingGlobalSkolemFunction(var_to_elim_index, skolem_function); } if(checkTimeOut()) // check for time-out { cout << "\nWarning!!Time-out inside the function AIGBasedSkolem::monolithicSkolemFunctionGeneratorWithScopeReduction\n"; timed_out = true; // timed_out flag set return; } #ifdef DETAILED_RECORD_KEEP gettimeofday (&step_finish_ms, NULL); step_ms = step_finish_ms.tv_sec * 1000 + step_finish_ms.tv_usec / 1000; step_ms -= step_start_ms.tv_sec * 1000 + step_start_ms.tv_usec / 1000; cout << "\ncomputing next factors finished in " << step_ms << " milliseconds\n"; #endif #ifdef PRINT_SKOLEM_FUNCTIONS string skolem_function_file_name = benchmark_name_without_extension; skolem_function_file_name += "_skolem_function"; writeFormulaToFile(pub_aig_manager, skolem_function, skolem_function_file_name, ".v", var_to_elim_index, 0); #endif // Enter into matrix insertIntoOneDimensionalMatrix(SkolemFunctions, number_of_vars_to_elim, var_to_elim_index, skolem_function, false); #ifdef DEBUG_SKOLEM cout << "\nclearing variable-specific data-structures\n"; #endif #ifdef DETAILED_RECORD_KEEP gettimeofday (&step_start_ms, NULL); #endif clearVariableSpecificDataStructures(); #ifdef DETAILED_RECORD_KEEP gettimeofday (&step_finish_ms, NULL); step_ms = step_finish_ms.tv_sec * 1000 + step_finish_ms.tv_usec / 1000; step_ms -= step_start_ms.tv_sec * 1000 + step_start_ms.tv_usec / 1000; cout << "\nclearVariableSpecificDataStructures finished in " << step_ms << " milliseconds\n"; #endif #ifdef RECORD_KEEP gettimeofday (&finish_ms, NULL); duration_ms = finish_ms.tv_sec * 1000 + finish_ms.tv_usec / 1000; duration_ms -= start_ms.tv_sec * 1000 + start_ms.tv_usec / 1000; SkolemFunctionGenTime = duration_ms; int skolem_function_size = computeSize(skolem_function, pub_aig_manager); SkolemFunctionSize = skolem_function_size; #endif string var_to_elim_name = searchVarIndexToVarNameMap(var_index_to_var_name_map, var_to_elim_index); cout << "\nskolem_function_" << var_to_elim_index << ", i.e., skolem function for " << var_to_elim_name << " computed\n"; #ifdef RECORD_KEEP string record_file; record_file = logfile_prefix; record_file += "skolem_function_generation_details.txt"; FILE* record_fp = fopen(record_file.c_str(), "a+"); assert(record_fp != NULL); sum_of_number_of_factors_containing_variable = sum_of_number_of_factors_containing_variable + NumberOfFactors; sum_of_skolem_function_sizes = sum_of_skolem_function_sizes + SkolemFunctionSize; total_number_of_compose_operations = total_number_of_compose_operations + number_of_compose_operations_for_variable; total_time_in_compose_operations = total_time_in_compose_operations + ComposeTime; number_of_variables_eliminated = var_to_elim_index; sum_of_numbers_of_affecting_factors = sum_of_numbers_of_affecting_factors + FactorsAffectingSkolemFunction.size(); #ifdef DETAILED_RECORD_KEEP if(print_factor_graph) { string fg_file_name = benchmark_name_without_extension; if(disable_factorization || disable_factorization_inside_factorized_code) { fg_file_name += "_monolithic"; } else { fg_file_name += "_factorized"; } fg_file_name += "_factor_graph.dat"; FILE* fg_fp = fopen(fg_file_name.c_str(), "a+"); assert(fg_fp != NULL); for(list::iterator affect_it = FactorsAffectingSkolemFunction.begin(); affect_it != FactorsAffectingSkolemFunction.end(); affect_it++) { fprintf(fg_fp, "%d\t%d\n", *affect_it, var_to_elim_index); } fclose(fg_fp); } fprintf(record_fp, "%d\t%s\t%d\t%llu\t%d\t%d\t%d\t%llu\t%d\t%llu\t%llu\t", var_to_elim_index, var_to_elim_name.c_str(), NumberOfFactors, SkolemFunctionGenTime, SkolemFunctionSize, size_of_alpha_in_interpolant_computation_for_variable, size_of_beta_in_interpolant_computation_for_variable, time_in_interpolant_computation_for_variable, number_of_compose_operations_for_variable, ComposeTime, FactorFindingTime); for(set::iterator factor_it = PreviousFactorsWithVariable.begin(); factor_it != PreviousFactorsWithVariable.end(); factor_it++) { fprintf(record_fp, "%d,", *factor_it); } fprintf(record_fp, "\t"); PreviousFactorsWithVariable.clear(); for(list::iterator size_it = sizes_of_factors_with_variable.begin(); size_it != sizes_of_factors_with_variable.end(); size_it++) { fprintf(record_fp, "%d,", *size_it); } //fprintf(record_fp, "\t"); sizes_of_factors_with_variable.clear(); //for(list::iterator affect_it = FactorsAffectingSkolemFunction.begin(); affect_it != FactorsAffectingSkolemFunction.end(); affect_it++) //{ // fprintf(record_fp, "%d,", *affect_it); //} //fprintf(record_fp, "\t"); //fprintf(record_fp, "%d", FactorsAffectingSkolemFunction.size()); // //FactorsAffectingSkolemFunction.clear(); fprintf(record_fp, "\n\n"); #else fprintf(record_fp, "%s\t%d\t%llu\t%d\t%d\n\n", var_to_elim_name.c_str(), NumberOfFactors, SkolemFunctionGenTime, SkolemFunctionSize, number_of_compose_operations_for_variable); #endif number_of_compose_operations_for_variable = 0; ComposeTime = 0; fclose(record_fp); #endif } if(perform_reverse_substitution) { gettimeofday (&step_start_ms, NULL); performReverseSubstitutionOfSkolemFunctions(); gettimeofday (&step_finish_ms, NULL); total_time_in_reverse_substitution_in_cegar = step_finish_ms.tv_sec * 1000 + step_finish_ms.tv_usec / 1000; total_time_in_reverse_substitution_in_cegar -= step_start_ms.tv_sec * 1000 + step_start_ms.tv_usec / 1000; for(int var_to_elim_index = 1; var_to_elim_index <= number_of_vars_to_elim; var_to_elim_index++) { Aig_Obj_t* final_skolem_function; final_skolem_function = searchOneDimensionalMatrix(SkolemFunctions, number_of_vars_to_elim, var_to_elim_index); assert(final_skolem_function != NULL); #ifdef RECORD_KEEP int final_skolem_function_size = computeSize(final_skolem_function, pub_aig_manager); skolem_function_sizes_after_reverse_substitution.push_back(final_skolem_function_size); sum_of_skolem_function_sizes_after_reverse_substitution = sum_of_skolem_function_sizes_after_reverse_substitution + final_skolem_function_size; #endif #ifdef PRINT_SKOLEM_FUNCTIONS string skolem_function_file_name = benchmark_name_without_extension; skolem_function_file_name += "_skolem_function_after_reverse_substitution"; writeFormulaToFile(pub_aig_manager, final_skolem_function, skolem_function_file_name, ".v", var_to_elim_index, 0); #endif } } } void AIGBasedSkolem::updateFactorsUsingGlobalSkolemFunction(int var_to_elim_index, Aig_Obj_t* skolem_function) { assert(var_to_elim_index < number_of_vars_to_elim); assert(skolem_function != NULL); for(set::iterator factor_it = FactorsWithVariable.begin(); factor_it != FactorsWithVariable.end(); factor_it++) { int factor_index = *factor_it; #ifdef DEBUG_SKOLEM cout << "\nfactor_index = " << factor_index << endl; #endif // obtain the existing factor Aig_Obj_t* previous_factor; previous_factor = searchOneDimensionalMatrix(FactorMatrix, number_of_factors, factor_index); assert(previous_factor != NULL); #ifdef DEBUG_SKOLEM writeFormulaToFile(pub_aig_manager, previous_factor, "factor", ".v", var_to_elim_index, factor_index); #endif Aig_Obj_t* factor; factor = replaceVariableByFormula(previous_factor, var_to_elim_index, skolem_function); assert(factor != NULL); #ifdef DEBUG_SKOLEM writeFormulaToFile(pub_aig_manager, factor, "factor", ".v", var_to_elim_index+1, factor_index); #endif insertIntoOneDimensionalMatrix(FactorMatrix, number_of_factors, factor_index, factor, true); #ifdef PRINT_VERY_DETAILED_RECORDS_ON_SCREEN int size_of_new_factor = computeSize(factor, pub_aig_manager); cout << "\nfactor_" << factor_index << " updated to formula of size " << size_of_new_factor << endl; #endif } } void AIGBasedSkolem::computeAbstractBadSet(int var_to_elim_index) { // BadSets[var_to_elim_index+1] = (disjunction of alpha's of factors with var_to_elim_index)\wedge // (disjunction of beta's of factors with var_to_elim_index) #ifdef DEBUG_SKOLEM cout << "\ncomputing bad_set_" << var_to_elim_index+1 << "\n"; #endif Aig_Obj_t* bad_set_for_next_var; bool alpha_combined_already_computed = true; if(alpha_combined_already_computed) { set beta_components; for(set::iterator factor_it = FactorsWithVariable.begin(); factor_it != FactorsWithVariable.end(); factor_it++) { int factor_index = *factor_it; #ifdef DEBUG_SKOLEM cout << "\nfactor_index = " << factor_index << endl; #endif // Suppose j = factor_index // Get beta_i_j Aig_Obj_t* beta_i_j; beta_i_j = computeBeta(var_to_elim_index, factor_index); assert(beta_i_j != NULL); #ifdef DEBUG_SKOLEM writeFormulaToFile(pub_aig_manager, beta_i_j, "beta", ".v", var_to_elim_index, factor_index); cout << "\nbeta_" << var_to_elim_index << "_" << factor_index << " obtained\n"; #endif beta_components.insert(beta_i_j); }// for each factor ends here if(checkTimeOut()) // check for time-out { cout << "\nWarning!!Time-out inside the function AIGBasedSkolem::computeAbstractBadSet\n"; timed_out = true; // timed_out flag set return; } Aig_Obj_t* alpha_part; alpha_part = searchOneDimensionalMatrix(AlphaCombineds, number_of_vars_to_elim, var_to_elim_index); assert(alpha_part != NULL); Aig_Obj_t* beta_part; if(beta_components.size() == 0) // we should return false in this case (as per defn. of beta) { beta_part = createFalse(pub_aig_manager); assert(beta_part != NULL); } else { beta_part = createOr(beta_components, pub_aig_manager); assert(beta_part != NULL); } bad_set_for_next_var = createAnd(alpha_part, beta_part, pub_aig_manager); assert(bad_set_for_next_var != NULL); Aig_Obj_t* bad_set_for_next_var_CO = Aig_ObjCreateCo( pub_aig_manager, bad_set_for_next_var ); // to aviod // unwanted cleanup of bad_set_for_next_var assert(bad_set_for_next_var_CO != NULL); } else { set alpha_components; set beta_components; for(set::iterator factor_it = FactorsWithVariable.begin(); factor_it != FactorsWithVariable.end(); factor_it++) { int factor_index = *factor_it; #ifdef DEBUG_SKOLEM cout << "\nfactor_index = " << factor_index << endl; #endif // Suppose j = factor_index // Get alpha_i_j and beta_i_j Aig_Obj_t* alpha_i_j; alpha_i_j = computeAlpha(var_to_elim_index, factor_index); assert(alpha_i_j != NULL); #ifdef DEBUG_SKOLEM writeFormulaToFile(pub_aig_manager, alpha_i_j, "alpha", ".v", var_to_elim_index, factor_index); cout << "\nalpha_" << var_to_elim_index << "_" << factor_index << " obtained\n"; #endif Aig_Obj_t* beta_i_j; beta_i_j = computeBeta(var_to_elim_index, factor_index); assert(beta_i_j != NULL); #ifdef DEBUG_SKOLEM writeFormulaToFile(pub_aig_manager, beta_i_j, "beta", ".v", var_to_elim_index, factor_index); cout << "\nbeta_" << var_to_elim_index << "_" << factor_index << " obtained\n"; #endif alpha_components.insert(alpha_i_j); beta_components.insert(beta_i_j); }// for each factor ends here if(checkTimeOut()) // check for time-out { cout << "\nWarning!!Time-out inside the function AIGBasedSkolem::computeAbstractBadSet\n"; timed_out = true; // timed_out flag set return; } Aig_Obj_t* alpha_part; alpha_part = createOr(alpha_components, pub_aig_manager); assert(alpha_part != NULL); Aig_Obj_t* beta_part; if(beta_components.size() == 0) // we should return false in this case (as per defn. of beta) { beta_part = createFalse(pub_aig_manager); assert(beta_part != NULL); } else { beta_part = createOr(beta_components, pub_aig_manager); assert(beta_part != NULL); } bad_set_for_next_var = createAnd(alpha_part, beta_part, pub_aig_manager); assert(bad_set_for_next_var != NULL); } #ifdef DEBUG_SKOLEM cout << "\nbad_set_" << var_to_elim_index+1 << " computed\n"; writeFormulaToFile(pub_aig_manager, bad_set_for_next_var, "bad_set", ".v", var_to_elim_index+1, cegar_iteration_number); #endif // Enter into matrix insertIntoOneDimensionalMatrix(BadSets, number_of_vars_to_elim+1, var_to_elim_index+1, bad_set_for_next_var, false); CorrectionPartSize = computeSize(bad_set_for_next_var, pub_aig_manager); #ifdef PRINT_VERY_DETAILED_RECORDS_ON_SCREEN cout << "\nsize of bad_set_" << var_to_elim_index+1 << " is " << CorrectionPartSize << endl; #endif if(checkTimeOut()) // check for time-out { cout << "\nWarning!!Time-out inside the function AIGBasedSkolem::computeAbstractBadSet\n"; timed_out = true; // timed_out flag set return; } } bool AIGBasedSkolem::checkIfSkolemFunctionsAreExact(map &Model_of_ExactnessCheck, map &Refinement_Hint_To_Eliminate_This_CEX) { if(apply_global_simplifications_before_each_iteration) { #ifdef DEBUG cout << "\nCalling Aig_ManCleanup\n"; #endif int nodes_removed = Aig_ManCleanup(pub_aig_manager); cout << "\nAig_ManCleanup removed " << nodes_removed << " nodes\n"; } vector< vector > LocalCNF; if(cegar_iteration_number == 0) { // Append the CNFs for skolem functions and bad_sets into FixedCNF for(int var_to_elim_index = 1; var_to_elim_index <= number_of_vars_to_elim; var_to_elim_index++) { // get the skolem function for var_to_elim_index Aig_Obj_t* skolem_function; skolem_function = searchOneDimensionalMatrix(SkolemFunctions, number_of_vars_to_elim, var_to_elim_index); assert(skolem_function != NULL); // \psi_i obtained // get the CNF for the skolem function int top_label_of_skolem_function = getCNF(pub_aig_manager, skolem_function, FixedCNF); top_labels_of_skolem_functions.push_back(top_label_of_skolem_function); #ifdef DEBUG_SKOLEM cout << "\nvar_to_elim_index = " << var_to_elim_index << "\ttop_label_of its skolem_function = " << top_label_of_skolem_function << endl; showCNF(FixedCNF); #endif } #ifdef DEBUG_SKOLEM cout << "\nCNFs for skolem functions appended\n"; #endif vector top_labels_of_bad_sets; for(int bad_location_index = 1; bad_location_index <= number_of_vars_to_elim+1; bad_location_index++) { // get the bad set for bad_location_index Aig_Obj_t* bad_set_obj; bad_set_obj = searchOneDimensionalMatrix(BadSets, number_of_vars_to_elim+1, bad_location_index); assert(bad_set_obj != NULL); // bad_set_i obtained // get the CNF for bad_set_i int top_label_of_bad_set = getCNF(pub_aig_manager, bad_set_obj, FixedCNF); top_labels_of_bad_sets.push_back(top_label_of_bad_set); #ifdef DEBUG_SKOLEM cout << "\nbad_location_index = " << bad_location_index << "\ttop_label_of its bad_set = " << top_label_of_bad_set << endl; showCNF(FixedCNF); #endif } #ifdef DEBUG_SKOLEM cout << "\nCNFs for bad_sets appended\n"; #endif // Insert x_1, ..., x_n into LabelTable for(int var_to_elim_index = 1; var_to_elim_index <= number_of_vars_to_elim; var_to_elim_index++) { string var_to_elim = searchVarIndexToVarNameMap(var_index_to_var_name_map, var_to_elim_index); map::iterator Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it = Ci_to_eliminate_name_to_Ci_to_eliminate_object_map.find(var_to_elim); assert(Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it != Ci_to_eliminate_name_to_Ci_to_eliminate_object_map.end()); Aig_Obj_t* var_to_elim_obj = Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it->second; insertCIIntoLabelTable(var_to_elim_obj); } #ifdef DEBUG_SKOLEM cout << "\nx_1,...,x_n inserted into LabelTable\n"; #endif // Append CNFs for (B_1 = bad_set_1), ..., (B_n = bad_set_n), (B_{n+1} = bad_set_{n+1}) into FixedCNF for(int bad_location_index = 1; bad_location_index <= number_of_vars_to_elim+1; bad_location_index++) { string B_i = "B_"; char bad_count_char[100]; sprintf(bad_count_char, "%d", bad_location_index); string bad_count_string(bad_count_char); B_i += bad_count_string; int label_of_B_i; map::iterator Ci_name_to_Ci_label_map_it = Ci_name_to_Ci_label_mapForGetCNF.find(B_i); assert(Ci_name_to_Ci_label_map_it != Ci_name_to_Ci_label_mapForGetCNF.end()); label_of_B_i = Ci_name_to_Ci_label_map_it->second; int top_label_of_bad_set_i = top_labels_of_bad_sets[bad_location_index-1]; vector clause_1; clause_1.push_back(label_of_B_i); clause_1.push_back(-1*top_label_of_bad_set_i); FixedCNF.push_back(clause_1); vector clause_2; clause_2.push_back(-1*label_of_B_i); clause_2.push_back(top_label_of_bad_set_i); FixedCNF.push_back(clause_2); #ifdef DEBUG_SKOLEM cout << "\nbad_location_index = " << bad_location_index << "\tlabel_of_B_i = " << label_of_B_i << "\ttop_label_of_bad_set_i = " << top_label_of_bad_set_i << endl; showCNF(FixedCNF); #endif } #ifdef DEBUG_SKOLEM cout << "\nCNFs for (B_1 = bad_set_1), ..., (B_n = bad_set_n), (B_{n+1} = bad_set_{n+1}) appended\n"; #endif // Append CNFs for (x_1 = \psi_1), ..., (x_n = \psi_n) into LocalCNF for(int var_to_elim_index = 1; var_to_elim_index <= number_of_vars_to_elim; var_to_elim_index++) { string var_to_elim = searchVarIndexToVarNameMap(var_index_to_var_name_map, var_to_elim_index); int label_of_var_to_elim; map::iterator Ci_name_to_Ci_label_map_it = Ci_name_to_Ci_label_mapForGetCNF.find(var_to_elim); assert(Ci_name_to_Ci_label_map_it != Ci_name_to_Ci_label_mapForGetCNF.end()); label_of_var_to_elim = Ci_name_to_Ci_label_map_it->second; int top_label_of_skolem_function_i = top_labels_of_skolem_functions[var_to_elim_index-1]; vector clause_1; clause_1.push_back(label_of_var_to_elim); clause_1.push_back(-1*top_label_of_skolem_function_i); LocalCNF.push_back(clause_1); vector clause_2; clause_2.push_back(-1*label_of_var_to_elim); clause_2.push_back(top_label_of_skolem_function_i); LocalCNF.push_back(clause_2); #ifdef DEBUG_SKOLEM cout << "\nvar_to_elim_index = " << var_to_elim_index << "\tlabel_of_var_to_elim = " << label_of_var_to_elim << "\ttop_label_of_skolem_function_i = " << top_label_of_skolem_function_i << endl; showCNF(LocalCNF); #endif } #ifdef DEBUG_SKOLEM cout << "\nCNFs for (x_1 = psi_1), ..., (x_n = psi_n) appended\n"; #endif } // if(cegar_iteration_number == 0) ends here else // if(cegar_iteration_number > 0) { // copy the Refinement_Hint_To_Eliminate_This_CEX to refinement_hints for(map::iterator hint_it = Refinement_Hint_To_Eliminate_This_CEX.begin(); hint_it != Refinement_Hint_To_Eliminate_This_CEX.end(); hint_it++) { int variable_index = hint_it->first; int bad_index = hint_it->second; map >::iterator refinement_hint_it = refinement_hints.find(variable_index); if(refinement_hint_it == refinement_hints.end()) // entry does not exist for variable_index { set bad_indices; bad_indices.insert(bad_index); refinement_hints.insert(make_pair(variable_index, bad_indices)); } else // entry exists for variable_index { (refinement_hint_it->second).insert(bad_index); } } #ifdef DEBUG_SKOLEM cout << "\nThe refinement hint to eliminate this counterexample is copied into refinement hints\n"; #endif // take each hint in Refinement_Hint_To_Eliminate_This_CEX to refinement_hints for(map::iterator hint_it = Refinement_Hint_To_Eliminate_This_CEX.begin(); hint_it != Refinement_Hint_To_Eliminate_This_CEX.end(); hint_it++) { int variable_index = hint_it->first; int bad_index = hint_it->second; #ifdef DEBUG_SKOLEM cout << "\nvariable_index = " << variable_index << "\tbad_index = " << bad_index << endl; #endif assert(bad_index < variable_index); #ifdef DEBUG_SKOLEM cout << "\ncreating replacement_map" << endl; #endif map replacement_map; for(int subst_index = bad_index; subst_index <= variable_index-1; subst_index++) { // we need to replace occurences of x_subst_index by C_subst_index_variable_index // Getting the object for C_subst_index_variable_index string connection_string = "C_"; char subst_char[100]; sprintf(subst_char, "%d", subst_index); string subst_string(subst_char); connection_string += subst_string; connection_string += "_"; char variable_char[100]; sprintf(variable_char, "%d", variable_index); string variable_string(variable_char); connection_string += variable_string; #ifdef DEBUG_SKOLEM cout << "\nconnection_string = " << connection_string << endl; #endif Aig_Obj_t* connection_object; map::iterator connection_string_to_connection_object_map_it = connection_string_to_connection_object_map.find(connection_string); if(connection_string_to_connection_object_map_it != connection_string_to_connection_object_map.end()) // object for connection_string exists { #ifdef DEBUG_SKOLEM cout << "\nconnection_object exists for this connection_string" << endl; #endif connection_object = connection_string_to_connection_object_map_it->second; assert(connection_object != NULL); } else { // creating new connection #ifdef DEBUG_SKOLEM cout << "\ncreating connection_object for this connection_string" << endl; #endif connection_object = Aig_ObjCreateCi(pub_aig_manager); assert(connection_object != NULL); int connection_id = Aig_ObjId(connection_object); // no need to apply Aig_Regular() as connection_object is CI Ci_id_to_Ci_name_map.insert(make_pair(connection_id, connection_string)); Ci_name_to_Ci_number_map.insert(make_pair(connection_string, number_of_Cis)); connection_string_to_connection_object_map.insert(make_pair(connection_string, connection_object)); number_of_Cis++; } replacement_map.insert(make_pair(subst_index, connection_object)); map >::iterator end_locations_it = end_locations_of_connections_sensitive_to_skolem_function.find(subst_index); if(end_locations_it == end_locations_of_connections_sensitive_to_skolem_function.end()) { set end_locations; end_locations.insert(variable_index); end_locations_of_connections_sensitive_to_skolem_function.insert(make_pair(subst_index, end_locations)); } else { (end_locations_it->second).insert(variable_index); } map >::iterator start_locations_it = start_locations_of_connections_skolem_function_is_sensitive_to.find(variable_index); if(start_locations_it == start_locations_of_connections_skolem_function_is_sensitive_to.end()) { set start_locations; start_locations.insert(subst_index); start_locations_of_connections_skolem_function_is_sensitive_to.insert(make_pair(variable_index, start_locations)); } else { (start_locations_it->second).insert(subst_index); } }// for subst_index from bad_index to variable_index-1 ends here #ifdef DEBUG_SKOLEM cout << "\nreplacement_map created" << endl; #endif // recomputing skolem function for variable at variable_index // new skolem function for variable at variable_index is // old_skolem_function \wedge (~bad_set at bad_index with replacements as per replacement_map // and x_variable_index replaced by 1) #ifdef DEBUG_SKOLEM cout << "\nrecomputing skolem function for variable at " << variable_index << endl; #endif Aig_Obj_t* bad_set_obj_at_bad_index; bad_set_obj_at_bad_index = searchOneDimensionalMatrix(BadSets, number_of_vars_to_elim, bad_index); assert(bad_set_obj_at_bad_index != NULL); Aig_Obj_t* bad_set_obj_after_replacements; if(replacement_map.size() > 0) { bad_set_obj_after_replacements = replaceVariablesByFormulas(bad_set_obj_at_bad_index, replacement_map); assert(bad_set_obj_after_replacements != NULL); } else { bad_set_obj_after_replacements = bad_set_obj_at_bad_index; } // we need to replace occurences of x_variable_index by true bad_set_obj_after_replacements = replaceVariableByConstant(bad_set_obj_after_replacements, variable_index, 1); assert(bad_set_obj_after_replacements != NULL); Aig_Obj_t* current_skolem_function; current_skolem_function = searchOneDimensionalMatrix(SkolemFunctions, number_of_vars_to_elim, variable_index); assert(current_skolem_function != NULL); Aig_Obj_t* new_skolem_function; // The new part in the skolem function is // (alpha_i \vee ~Bad after substitutions) Aig_Obj_t* alpha_combined; alpha_combined = searchOneDimensionalMatrix(AlphaCombineds, number_of_vars_to_elim, variable_index); assert(alpha_combined != NULL); Aig_Obj_t* new_component_in_skolem_function; new_component_in_skolem_function = createOr(alpha_combined, createNot(bad_set_obj_after_replacements, pub_aig_manager), pub_aig_manager); assert(new_component_in_skolem_function != NULL); new_skolem_function = createAnd(current_skolem_function, new_component_in_skolem_function, pub_aig_manager); assert(new_skolem_function != NULL); if(new_skolem_function != current_skolem_function) // skolem function is changed { #ifdef DEBUG_SKOLEM cout << "\nSkolem function for " << variable_index << " is changed\n"; #endif // insert the new skolem function insertIntoOneDimensionalMatrix(SkolemFunctions, number_of_vars_to_elim, variable_index, new_skolem_function, true); // get the CNF for the new skolem function in FixedCNF int top_label_of_new_skolem_function = getCNF(pub_aig_manager, new_skolem_function, FixedCNF); top_labels_of_skolem_functions[variable_index-1] = top_label_of_new_skolem_function; #ifdef DEBUG_SKOLEM cout << "\ntop_label_of_new_skolem_function = " << top_label_of_new_skolem_function << endl; #endif #ifdef PRINT_SKOLEM_FUNCTIONS string skolem_function_file_name = benchmark_name_without_extension; skolem_function_file_name += "_skolem_function"; writeFormulaToFile(pub_aig_manager, new_skolem_function, skolem_function_file_name, ".v", variable_index, cegar_iteration_number); #endif } else { #ifdef DEBUG_SKOLEM cout << "\nSkolem function for " << variable_index << " is not changed\n"; #endif #ifdef PRINT_SKOLEM_FUNCTIONS string skolem_function_file_name = benchmark_name_without_extension; skolem_function_file_name += "_skolem_function"; writeFormulaToFile(pub_aig_manager, new_skolem_function, skolem_function_file_name, ".v", variable_index, cegar_iteration_number); #endif } // skolem function of variable_index and its CNF are regenerated // Recomputing expressions for C_subst_index_variable_index and recomputing their CNFs #ifdef DEBUG_SKOLEM cout << "\nRecomputing expressions for C_subst_index_variable_index and recomputing their CNFs\n"; #endif for(int subst_index = bad_index; subst_index <= variable_index-1; subst_index++) { // we need to obtain expression and CNF for C_subst_index_variable_index // Getting the name of C_subst_index_variable_index string connection_string = "C_"; char subst_char[100]; sprintf(subst_char, "%d", subst_index); string subst_string(subst_char); connection_string += subst_string; connection_string += "_"; char variable_char[100]; sprintf(variable_char, "%d", variable_index); string variable_string(variable_char); connection_string += variable_string; #ifdef DEBUG_SKOLEM cout << "\nconnection_string = " << connection_string << endl; #endif // expression for C_subst_index_variable_index is obtained as // skolem_function for subst_index with replacements as per replacement_map from subst_index+1 // and x_variable_index replaced by 1 map local_replacement_map; for(int local_subst_index = subst_index+1; local_subst_index <= variable_index-1; local_subst_index++) { map::iterator replacement_map_it = replacement_map.find(local_subst_index); assert(replacement_map_it != replacement_map.end()); Aig_Obj_t* object_to_replace = replacement_map_it->second; local_replacement_map.insert(make_pair(local_subst_index, object_to_replace)); } Aig_Obj_t* skolem_function_at_subst_index; skolem_function_at_subst_index = searchOneDimensionalMatrix(SkolemFunctions, number_of_vars_to_elim, subst_index); assert(skolem_function_at_subst_index != NULL); Aig_Obj_t* skolem_function_after_replacements; if(local_replacement_map.size() > 0) { skolem_function_after_replacements = replaceVariablesByFormulas(skolem_function_at_subst_index, local_replacement_map); assert(skolem_function_after_replacements != NULL); } else { skolem_function_after_replacements = skolem_function_at_subst_index; } // we need to replace occurences of x_variable_index by true skolem_function_after_replacements = replaceVariableByConstant(skolem_function_after_replacements, variable_index, 1); assert(skolem_function_after_replacements != NULL); Aig_Obj_t* new_connection_dag = skolem_function_after_replacements; Aig_Obj_t* current_connection_dag; map::iterator Connections_it = Connections.find(connection_string); if(Connections_it == Connections.end()) // dag does not exist for connection_string { current_connection_dag = NULL; } else { current_connection_dag = Connections_it->second; assert(current_connection_dag != NULL); } if(current_connection_dag != new_connection_dag) // connection_dag has changed { #ifdef DEBUG_SKOLEM cout << "\nConnection dag for " << connection_string << " is changed\n"; #endif // insert it first Connections[connection_string] = new_connection_dag; // get the CNF for new_connection_dag int top_label_of_new_connection_dag = getCNF(pub_aig_manager, new_connection_dag, FixedCNF); top_labels_of_connections[connection_string] = top_label_of_new_connection_dag; #ifdef DEBUG_SKOLEM cout << "\ntop_label_of_new_connection_dag = " << top_label_of_new_connection_dag << endl; #endif #ifdef PRINT_SKOLEM_FUNCTIONS string connection_file_name = benchmark_name_without_extension; connection_file_name += "_connection"; writeFormulaToFile(pub_aig_manager, new_connection_dag, connection_file_name, ".v", subst_index, variable_index); #endif } else { #ifdef DEBUG_SKOLEM cout << "\nConnection dag for " << connection_string << " is not changed\n"; #endif } }// for subst_index from bad_index to variable_index-1 ends here // We have changed the skolem function for variable_index // There may be connections sensitive to this. They should be recreated. // Finding the connections sensitive to skolem function for variable_index #ifdef DEBUG_SKOLEM cout << "\nRecomputing the connections sensitive to skolem function for " << variable_index << endl; #endif map >::iterator end_locations_it = end_locations_of_connections_sensitive_to_skolem_function.find(variable_index); if(end_locations_it != end_locations_of_connections_sensitive_to_skolem_function.end()) { set end_locations = end_locations_it->second; for(set::iterator end_locations_it = end_locations.begin(); end_locations_it != end_locations.end(); end_locations_it++) { int end_index = *end_locations_it; // we need to obtain expression and CNF for C_variable_index_end_index // Getting the name of C_variable_index_end_index string connection_string = "C_"; char variable_char[100]; sprintf(variable_char, "%d", variable_index); string variable_string(variable_char); connection_string += variable_string; connection_string += "_"; char end_char[100]; sprintf(end_char, "%d", end_index); string end_string(end_char); connection_string += end_string; #ifdef DEBUG_SKOLEM cout << "\nend_index = " << end_index<< "\tconnection_string = " << connection_string << endl; #endif // expression for C_variable_index_end_index is obtained as // skolem_function for variable_index with replacements variable_index+1 with C_(variable_index+1)_end_index // .......... // end_index-1 with C_(end_index-1)_end_index // and end_index replaced by 1 #ifdef DEBUG_SKOLEM cout << "\ncreating local_replacement_map\n"; #endif map local_replacement_map; for(int local_subst_index = variable_index+1; local_subst_index <= end_index-1; local_subst_index++) { // Getting the object for C_local_subst_index_end_index string local_connection_string = "C_"; char local_subst_char[100]; sprintf(local_subst_char, "%d", local_subst_index); string local_subst_string(local_subst_char); local_connection_string += local_subst_string; local_connection_string += "_"; local_connection_string += end_string; map::iterator connection_map_it = connection_string_to_connection_object_map.find(local_connection_string); assert(connection_map_it != connection_string_to_connection_object_map.end()); Aig_Obj_t* object_to_replace = connection_map_it->second; local_replacement_map.insert(make_pair(local_subst_index, object_to_replace)); #ifdef DEBUG_SKOLEM cout << "\nlocal_connection_string = " << local_connection_string << endl; #endif } Aig_Obj_t* skolem_function_at_variable_index; skolem_function_at_variable_index = searchOneDimensionalMatrix(SkolemFunctions, number_of_vars_to_elim, variable_index); assert(skolem_function_at_variable_index != NULL); Aig_Obj_t* skolem_function_after_replacements; if(local_replacement_map.size() > 0) { skolem_function_after_replacements = replaceVariablesByFormulas(skolem_function_at_variable_index, local_replacement_map); assert(skolem_function_after_replacements != NULL); } else { skolem_function_after_replacements = skolem_function_at_variable_index; } // we need to replace occurences of x_end_index by true skolem_function_after_replacements = replaceVariableByConstant(skolem_function_after_replacements, end_index, 1); assert(skolem_function_after_replacements != NULL); Aig_Obj_t* new_connection_dag = skolem_function_after_replacements; Aig_Obj_t* current_connection_dag; map::iterator Connections_it = Connections.find(connection_string); if(Connections_it == Connections.end()) // dag does not exist for connection_string { current_connection_dag = NULL; } else { current_connection_dag = Connections_it->second; assert(current_connection_dag != NULL); } if(current_connection_dag != new_connection_dag) // connection_dag has changed { #ifdef DEBUG_SKOLEM cout << "\nConnection dag for " << connection_string << " is changed\n"; #endif // insert it first Connections[connection_string] = new_connection_dag; // get the CNF for new_connection_dag int top_label_of_new_connection_dag = getCNF(pub_aig_manager, new_connection_dag, FixedCNF); top_labels_of_connections[connection_string] = top_label_of_new_connection_dag; #ifdef DEBUG_SKOLEM cout << "\ntop_label_of_new_connection_dag = " << top_label_of_new_connection_dag << endl; #endif #ifdef PRINT_SKOLEM_FUNCTIONS string connection_file_name = benchmark_name_without_extension; connection_file_name += "_connection"; writeFormulaToFile(pub_aig_manager, new_connection_dag, connection_file_name, ".v", variable_index, end_index); #endif } else { #ifdef DEBUG_SKOLEM cout << "\nConnection dag for " << connection_string << " is not changed\n"; #endif } }// for each end location } else { #ifdef DEBUG_SKOLEM cout << "\nNo end locations for " << variable_index << "\n"; #endif } } // take each hint ends here // Append equalities between the x's and top-labels of latest skolem functions and // equalities between the Cij's and top-labels of latest dags of Cij's into LocalCNF // Insert Cij's into LabelTable for(map::iterator map_it = top_labels_of_connections.begin(); map_it != top_labels_of_connections.end(); map_it++) { string connection_string = map_it->first; map::iterator connection_string_to_connection_object_map_it = connection_string_to_connection_object_map.find(connection_string); assert(connection_string_to_connection_object_map_it != connection_string_to_connection_object_map.end()); Aig_Obj_t* connection_obj = connection_string_to_connection_object_map_it->second; insertCIIntoLabelTable(connection_obj); } #ifdef DEBUG_SKOLEM cout << "\nCij's inserted into LabelTable\n"; #endif // Append equalities between the Cij's and top-labels of latest dags of Cij's into LocalCNF for(map::iterator map_it = top_labels_of_connections.begin(); map_it != top_labels_of_connections.end(); map_it++) { string connection_string = map_it->first; #ifdef DEBUG_SKOLEM cout << "\nconnection_string = " << connection_string << endl; #endif int label_of_connection_string; map::iterator Ci_name_to_Ci_label_map_it = Ci_name_to_Ci_label_mapForGetCNF.find(connection_string); assert(Ci_name_to_Ci_label_map_it != Ci_name_to_Ci_label_mapForGetCNF.end()); label_of_connection_string = Ci_name_to_Ci_label_map_it->second; int top_label_of_connection_string = map_it->second; vector clause_1; clause_1.push_back(label_of_connection_string); clause_1.push_back(-1*top_label_of_connection_string); LocalCNF.push_back(clause_1); vector clause_2; clause_2.push_back(-1*label_of_connection_string); clause_2.push_back(top_label_of_connection_string); LocalCNF.push_back(clause_2); #ifdef DEBUG_SKOLEM cout << "\nlabel_of_connection_string = " << label_of_connection_string << "\ttop_label_of_connection_string = " << top_label_of_connection_string << endl; showCNF(LocalCNF); #endif } #ifdef DEBUG_SKOLEM cout << "\nEqualities between the Cij's and top-labels of latest dags of Cij's appended into LocalCNF\n"; #endif // Append CNFs for (x_1 = \psi_1), ..., (x_n = \psi_n) into LocalCNF for(int var_to_elim_index = 1; var_to_elim_index <= number_of_vars_to_elim; var_to_elim_index++) { string var_to_elim = searchVarIndexToVarNameMap(var_index_to_var_name_map, var_to_elim_index); int label_of_var_to_elim; map::iterator Ci_name_to_Ci_label_map_it = Ci_name_to_Ci_label_mapForGetCNF.find(var_to_elim); assert(Ci_name_to_Ci_label_map_it != Ci_name_to_Ci_label_mapForGetCNF.end()); label_of_var_to_elim = Ci_name_to_Ci_label_map_it->second; int top_label_of_skolem_function_i = top_labels_of_skolem_functions[var_to_elim_index-1]; vector clause_1; clause_1.push_back(label_of_var_to_elim); clause_1.push_back(-1*top_label_of_skolem_function_i); LocalCNF.push_back(clause_1); vector clause_2; clause_2.push_back(-1*label_of_var_to_elim); clause_2.push_back(top_label_of_skolem_function_i); LocalCNF.push_back(clause_2); #ifdef DEBUG_SKOLEM cout << "\nvar_to_elim_index = " << var_to_elim_index << "\tlabel_of_var_to_elim = " << label_of_var_to_elim << "\ttop_label_of_skolem_function_i = " << top_label_of_skolem_function_i << endl; showCNF(LocalCNF); #endif } #ifdef DEBUG_SKOLEM cout << "\nCNFs for (x_1 = psi_1), ..., (x_n = psi_n) appended\n"; #endif } // if(cegar_iteration_number > 0) ends here // Give ExactnessCheck = FixedCNF appended with LocalCNF to SAT-Solver // Write the CNFs into exactnesscheck.cnf file int number_of_variables = LabelCount-1; int number_of_clauses = FixedCNF.size() + LocalCNF.size(); string cnf_filename = "exactnesscheck.cnf"; writeCNFToFile(FixedCNF, LocalCNF, number_of_variables, number_of_clauses, cnf_filename); #ifdef DEBUG_SKOLEM cout << endl << cnf_filename << " written\n"; #endif #ifdef DETAILED_RECORD_KEEP unsigned long long int solver_ms; struct timeval solver_start_ms, solver_finish_ms; gettimeofday (&solver_start_ms, NULL); #endif // Give exactnesscheck.cnf to SAT-Solver and get unsat / sat with model bool result_of_exactnesscheck = giveCNFFiletoSATSolverAndQueryForSatisfiability(cnf_filename, Model_of_ExactnessCheck); #ifdef DETAILED_RECORD_KEEP gettimeofday (&solver_finish_ms, NULL); solver_ms = solver_finish_ms.tv_sec * 1000 + solver_finish_ms.tv_usec / 1000; solver_ms -= solver_start_ms.tv_sec * 1000 + solver_start_ms.tv_usec / 1000; cout << "\nsolver finished in " << solver_ms << " milliseconds\n"; total_time_in_smt_solver = total_time_in_smt_solver + solver_ms; times_in_sat_solving_in_cegar.push_back(solver_ms); #endif //#ifdef DEBUG_SKOLEM displayModelFromSATSolver(Model_of_ExactnessCheck); cout << endl << "result_of_exactnesscheck = " << result_of_exactnesscheck << endl; //#endif if(!result_of_exactnesscheck) // ExactnessCheck unsat i.e. skolem functions exact { return true; } else // skolem functions inexact { return false; } } void AIGBasedSkolem::refineSkolemFunctions(map &Model_of_ExactnessCheck, map &Refinement_Hint_To_Eliminate_This_CEX) { // For easy of processing let's create vector BadLabels; // BadLabels[i-1] gives CNF label of Bad_i vector BadValues; // BadValues[i-1] gives value of Bad_i vector XLabels; // XLabels[i-1] gives CNF label of x_i vector XValues; // XValues[i-1] gives value of x_i vector XNewLabels; // XNewLabels[i-1] gives CNF label of x'_i vector XNewValues; // XNewValues[i-1] gives value of x'_i map YValues; // YValues[yvariable] gives value of yvariable map YLabelsToYValuesMap; // Map from label of a y variable to its value set NonYVariables_In_Model; for(int var_to_elim_index = 1; var_to_elim_index <= number_of_vars_to_elim; var_to_elim_index++) { string var_to_elim = searchVarIndexToVarNameMap(var_index_to_var_name_map, var_to_elim_index); string var_to_elim_renamed = var_to_elim; var_to_elim_renamed += "_new"; string B_i = "B_"; char bad_count_char[100]; sprintf(bad_count_char, "%d", var_to_elim_index); string bad_count_string(bad_count_char); B_i += bad_count_string; NonYVariables_In_Model.insert(var_to_elim); NonYVariables_In_Model.insert(var_to_elim_renamed); NonYVariables_In_Model.insert(B_i); map::iterator Ci_name_to_Ci_label_map_it; map::iterator Model_of_ExactnessCheck_it; Ci_name_to_Ci_label_map_it = Ci_name_to_Ci_label_mapForGetCNF.find(var_to_elim); assert(Ci_name_to_Ci_label_map_it != Ci_name_to_Ci_label_mapForGetCNF.end()); Model_of_ExactnessCheck_it = Model_of_ExactnessCheck.find(var_to_elim); assert(Model_of_ExactnessCheck_it != Model_of_ExactnessCheck.end()); XLabels.push_back(Ci_name_to_Ci_label_map_it->second); XValues.push_back(Model_of_ExactnessCheck_it->second); Ci_name_to_Ci_label_map_it = Ci_name_to_Ci_label_mapForGetCNF.find(var_to_elim_renamed); assert(Ci_name_to_Ci_label_map_it != Ci_name_to_Ci_label_mapForGetCNF.end()); Model_of_ExactnessCheck_it = Model_of_ExactnessCheck.find(var_to_elim_renamed); assert(Model_of_ExactnessCheck_it != Model_of_ExactnessCheck.end()); XNewLabels.push_back(Ci_name_to_Ci_label_map_it->second); XNewValues.push_back(Model_of_ExactnessCheck_it->second); Ci_name_to_Ci_label_map_it = Ci_name_to_Ci_label_mapForGetCNF.find(B_i); assert(Ci_name_to_Ci_label_map_it != Ci_name_to_Ci_label_mapForGetCNF.end()); Model_of_ExactnessCheck_it = Model_of_ExactnessCheck.find(B_i); assert(Model_of_ExactnessCheck_it != Model_of_ExactnessCheck.end()); BadLabels.push_back(Ci_name_to_Ci_label_map_it->second); BadValues.push_back(Model_of_ExactnessCheck_it->second); } string B_i = "B_"; char bad_count_char[100]; sprintf(bad_count_char, "%d", number_of_vars_to_elim+1); string bad_count_string(bad_count_char); B_i += bad_count_string; NonYVariables_In_Model.insert(B_i); map::iterator Ci_name_to_Ci_label_map_it; map::iterator Model_of_ExactnessCheck_it; Ci_name_to_Ci_label_map_it = Ci_name_to_Ci_label_mapForGetCNF.find(B_i); assert(Ci_name_to_Ci_label_map_it != Ci_name_to_Ci_label_mapForGetCNF.end()); Model_of_ExactnessCheck_it = Model_of_ExactnessCheck.find(B_i); assert(Model_of_ExactnessCheck_it != Model_of_ExactnessCheck.end()); BadLabels.push_back(Ci_name_to_Ci_label_map_it->second); BadValues.push_back(Model_of_ExactnessCheck_it->second); for(map::iterator model_it = Model_of_ExactnessCheck.begin(); model_it != Model_of_ExactnessCheck.end(); model_it++) { string variable_name = model_it->first; int variable_value = model_it->second; if(NonYVariables_In_Model.find(variable_name) == NonYVariables_In_Model.end() && connection_string_to_connection_object_map.find(variable_name) == connection_string_to_connection_object_map.end()) // variable is a Y variable { map::iterator Ci_name_to_Ci_label_map_it; Ci_name_to_Ci_label_map_it = Ci_name_to_Ci_label_mapForGetCNF.find(variable_name); assert(Ci_name_to_Ci_label_map_it != Ci_name_to_Ci_label_mapForGetCNF.end()); int variable_label = Ci_name_to_Ci_label_map_it->second; YLabelsToYValuesMap.insert(make_pair(variable_label, variable_value)); YValues.insert(make_pair(variable_name, variable_value)); } } #ifdef DEBUG_SKOLEM for(int i = 0; i < BadLabels.size(); i++) { cout << endl << "BadLabels[" << i << "] = " << BadLabels[i]; } for(int i = 0; i < BadValues.size(); i++) { cout << endl << "BadValues[" << i << "] = " << BadValues[i]; } for(int i = 0; i < XLabels.size(); i++) { cout << endl << "XLabels[" << i << "] = " << XLabels[i]; } for(int i = 0; i < XValues.size(); i++) { cout << endl << "XValues[" << i << "] = " << XValues[i]; } for(int i = 0; i < XNewLabels.size(); i++) { cout << endl << "XNewLabels[" << i << "] = " << XNewLabels[i]; } for(int i = 0; i < XNewValues.size(); i++) { cout << endl << "XNewValues[" << i << "] = " << XNewValues[i]; } for(map::iterator yvalues_it = YLabelsToYValuesMap.begin(); yvalues_it != YLabelsToYValuesMap.end(); yvalues_it++) { cout << endl << "YLabelsToYValuesMap->first = " << yvalues_it->first << "\t" << "YLabelsToYValuesMap->second = " << yvalues_it->second; } #endif if(false) { for(int i = 0; i < XValues.size(); i++) { if(XValues[i] == 0 && XNewValues[i] == 1) { string var_to_elim_i = searchVarIndexToVarNameMap(var_index_to_var_name_map, i+1); cout << "\nSkolem function for x_" << i+1 << " i.e. " << var_to_elim_i << " no more over-approximation\n"; analyzeReasonBehindUnderApproximation(i+1, XValues, XNewValues, YValues); assert(false); } } } // Note that locations in the ...Values, ...Lables vectors // are 0...number_of_vars_to_elim-1 vector BadLocations; for(int location = 0; location < BadValues.size(); location++) { if(BadValues[location] == 1) { BadLocations.push_back(location); } } int minimum_bad_location = BadLocations[0]; int maximum_bad_location = BadLocations[BadLocations.size()-1]; if(maximum_bad_location == minimum_bad_location && maximum_bad_location == number_of_vars_to_elim+1) { // Bad at number_of_vars_to_elim+1 is the only Bad; how to refine this? cout << "\nError in AIGBasedSkolem::refineSkolemFunctions!! Bad at " << number_of_vars_to_elim+1 << " is the only Bad; how to refine this?\n"; assert(false); } #ifdef DEBUG_SKOLEM for(int i = 0; i < BadLocations.size(); i++) { cout << endl << "BadLocations[" << i << "] = " << BadLocations[i]; } cout << "\nminimum_bad_location = " << minimum_bad_location; #endif for(int var_to_elim_index = number_of_vars_to_elim; var_to_elim_index >= 1; var_to_elim_index--) { #ifdef DEBUG_SKOLEM cout << "\nvar_to_elim_index = " << var_to_elim_index; #endif int location = var_to_elim_index-1; if(location <= minimum_bad_location) // we have reached locations below min. bad; let's stop { #ifdef DEBUG_SKOLEM cout << "\nwe have reached locations below min. bad; let's stop"; #endif break; } else if(XValues[location] != XNewValues[location]) // mismatch found { #ifdef DEBUG_SKOLEM cout << "\nmismatch found"; #endif assert(XValues[location] == 1 && XNewValues[location] == 0); // over-approximation bool mismatch_genuine = checkIfMismatchIsGenuine(location, XNewValues, XNewLabels, YLabelsToYValuesMap); if(!mismatch_genuine) // For XNewValues s.t. XValuesNew[location] == 0 // and XNewValues[i] = XValues[i] for i from number_of_vars_to_elim-1 to location+1, mismatch avoidable // But XNewValues[j] for j from location to 0 are changed { #ifdef DEBUG_SKOLEM cout << "\nmismatch is not genuine"; for(int i = 0; i < XNewLabels.size(); i++) { cout << endl << "XNewLabels[" << i << "] = " << XNewLabels[i]; } for(int i = 0; i < XNewValues.size(); i++) { cout << endl << "XNewValues[" << i << "] = " << XNewValues[i]; } #endif continue; } else { #ifdef DEBUG_SKOLEM cout << "\nmismatch is genuine"; #endif vector bad_locations_to_refine_mismatch_at_location; findBadLocationsToRefineMismatchAtLocation(location, BadLocations, bad_locations_to_refine_mismatch_at_location); vector bads_to_refine_mismatch_at_location; // actual bads are locations + 1 for(int bad_location_it = 0; bad_location_it < bad_locations_to_refine_mismatch_at_location.size(); bad_location_it++) { bads_to_refine_mismatch_at_location.push_back(bad_locations_to_refine_mismatch_at_location[bad_location_it] + 1); } #ifdef DEBUG_SKOLEM cout << "\nbads_to_refine_mismatch_at_location"; for(int i = 0; i < bads_to_refine_mismatch_at_location.size(); i++) { cout << endl << "bads_to_refine_mismatch_at_location[" << i << "] = " << bads_to_refine_mismatch_at_location[i]; } #endif #ifdef DEBUG_SKOLEM cout << "\nLet's insert " << var_to_elim_index << " --> " << bads_to_refine_mismatch_at_location[0] << " in refinement hint\n"; #endif assert(bads_to_refine_mismatch_at_location.size() > 0); // there must be at least one bad location Refinement_Hint_To_Eliminate_This_CEX.insert(make_pair(var_to_elim_index, bads_to_refine_mismatch_at_location[0])); }// refinement hint addition ends here } // mismatch found ends here }// loop ends here } bool AIGBasedSkolem::checkIfMismatchIsGenuine(int mismatch_location, vector &XNewValues, vector &XNewLabels, map &YLabelsToYValuesMap) { vector< vector > LocalCNF; // assert that all y variables keep their values in the existing model for(map::iterator yvalues_it = YLabelsToYValuesMap.begin(); yvalues_it != YLabelsToYValuesMap.end(); yvalues_it++) { int ylabel; if(yvalues_it->second == 1) // y is true { ylabel = yvalues_it->first; } else // y is false { ylabel = -1*(yvalues_it->first); } vector clause; clause.push_back(ylabel); LocalCNF.push_back(clause); } // assert that all x_new variables upto mismatch_location keep their values in the existing model for(int var_to_elim_index = number_of_vars_to_elim; var_to_elim_index >= 1; var_to_elim_index--) { int location = var_to_elim_index-1; if(location <= mismatch_location) { break; } else { int xnewlabel; if(XNewValues[location] == 1) // xnew is true { xnewlabel = XNewLabels[location]; } else // xnew is false { xnewlabel = -1*(XNewLabels[location]); } vector clause; clause.push_back(xnewlabel); LocalCNF.push_back(clause); } } // assert that x_new variable at mismatch_location is true int xnewlabel; xnewlabel = XNewLabels[mismatch_location]; // assert that xnewlabel is true vector clause; clause.push_back(xnewlabel); LocalCNF.push_back(clause); // Let's call the SAT-Solver to see if CNFForRenamedConjunctionOfFactors with // these assertions is still satisfiable int number_of_clauses = CNFForRenamedConjunctionOfFactors.size() + LocalCNF.size(); string cnf_filename = "renamedconjunction.cnf"; writeCNFToFile(CNFForRenamedConjunctionOfFactors, LocalCNF, number_of_variables_in_renamed_conjunction_of_factors, number_of_clauses, cnf_filename); #ifdef DEBUG_SKOLEM cout << endl << cnf_filename << " written\n"; #endif // Give exactnesscheck.cnf to SAT-Solver and get unsat / sat with model map Model_of_RenamedConjunctionOfFactors; bool result_of_renamed_conjunction_of_factors = giveCNFFiletoSATSolverAndQueryForSatisfiability(cnf_filename, Model_of_RenamedConjunctionOfFactors); #ifdef DEBUG_SKOLEM displayModelFromSATSolver(Model_of_RenamedConjunctionOfFactors); cout << endl << "result_of_renamed_conjunction_of_factors = " << result_of_renamed_conjunction_of_factors << endl; #endif if(!result_of_renamed_conjunction_of_factors) // RenamedConjunctionOfFactors with assertions is unsat // mismatch unavoidable/genuine { return true; } else // mismatch avoidable { // Get the changed XNewValues for(int var_to_elim_index = 1; var_to_elim_index <= number_of_vars_to_elim; var_to_elim_index++) { int location = var_to_elim_index-1; string var_to_elim = searchVarIndexToVarNameMap(var_index_to_var_name_map, var_to_elim_index); string var_to_elim_renamed = var_to_elim; var_to_elim_renamed += "_new"; map::iterator Ci_name_to_Ci_label_map_it; map::iterator Model_of_RenamedConjunctionOfFactors_it; Ci_name_to_Ci_label_map_it = Ci_name_to_Ci_label_mapForGetCNF.find(var_to_elim_renamed); assert(Ci_name_to_Ci_label_map_it != Ci_name_to_Ci_label_mapForGetCNF.end()); Model_of_RenamedConjunctionOfFactors_it = Model_of_RenamedConjunctionOfFactors.find(var_to_elim_renamed); assert(Model_of_RenamedConjunctionOfFactors_it != Model_of_RenamedConjunctionOfFactors.end()); int changed_xnew_value = Model_of_RenamedConjunctionOfFactors_it->second; if(location < mismatch_location) { XNewValues[location] = changed_xnew_value; } else if(location > mismatch_location) { assert(XNewValues[location] == changed_xnew_value); } else //location == mismatch_location { assert(changed_xnew_value == 1); XNewValues[location] = 1; } } return false; } // avoidable mismatch found ends here }// function ends here void AIGBasedSkolem::findBadLocationsToRefineMismatchAtLocation(int mismatch_location, vector &BadLocations, vector & bad_locations_to_refine_mismatch_at_mismatch_location) { // Initial refinement strategy: Pull all the bads above mismatch_location // to the mismatch_location to correct the mismatch at mismatch_location for(int location_it = 0; location_it < BadLocations.size(); location_it++) { int bad_location = BadLocations[location_it]; if(bad_location < mismatch_location) { bad_locations_to_refine_mismatch_at_mismatch_location.push_back(bad_location); } } } void AIGBasedSkolem::initializeCEGAR() { if(apply_global_simplifications_before_each_iteration) { #ifdef DEBUG_SKOLEM cout << "\nCalling Aig_ManCleanup\n"; #endif int nodes_removed = Aig_ManCleanup(pub_aig_manager); cout << "\nAig_ManCleanup removed " << nodes_removed << " nodes\n"; } // We need to obtain CNF for F(X', Y) and (B1\vee ... \vee B_n \vee B_{n+1}) // Creating F(X', Y) and (B1\vee ... \vee B_n \vee B_{n+1}) #ifdef DEBUG_SKOLEM cout << "\nObtaining Ci's for X'\n"; #endif vector var_to_elim_renamed_objects; for(int var_to_elim_index = 1; var_to_elim_index <= number_of_vars_to_elim; var_to_elim_index++) { string var_to_elim = searchVarIndexToVarNameMap(var_index_to_var_name_map, var_to_elim_index); string var_to_elim_renamed = var_to_elim; var_to_elim_renamed += "_new"; Aig_Obj_t* var_to_elim_renamed_obj = Aig_ObjCreateCi(pub_aig_manager); int var_to_elim_renamed_id = Aig_ObjId(var_to_elim_renamed_obj); // no need to apply Aig_Regular() as var_to_elim_renamed_obj is CI Ci_id_to_Ci_name_map.insert(make_pair(var_to_elim_renamed_id, var_to_elim_renamed)); Ci_name_to_Ci_number_map.insert(make_pair(var_to_elim_renamed, number_of_Cis)); var_to_elim_renamed_objects.push_back(var_to_elim_renamed_obj); number_of_Cis++; } #ifdef DEBUG_SKOLEM cout << "\nCi's for X' obtained\n"; #endif #ifdef DEBUG_SKOLEM cout << "\nObtaining Ci's for Bad's\n"; #endif set B_i_objects; for(int bad_location_index = 1; bad_location_index <= number_of_vars_to_elim+1; bad_location_index++) { string B_i = "B_"; char bad_count_char[100]; sprintf(bad_count_char, "%d", bad_location_index); string bad_count_string(bad_count_char); B_i += bad_count_string; Aig_Obj_t* B_i_obj = Aig_ObjCreateCi(pub_aig_manager); int B_i_id = Aig_ObjId(B_i_obj); // no need to apply Aig_Regular() as B_i_obj is CI Ci_id_to_Ci_name_map.insert(make_pair(B_i_id, B_i)); Ci_name_to_Ci_number_map.insert(make_pair(B_i, number_of_Cis)); B_i_index_to_B_i_object_map.insert(make_pair(bad_location_index, B_i_obj)); B_i_objects.insert(B_i_obj); number_of_Cis++; } #ifdef DEBUG_SKOLEM cout << "\nCi's for Bad's obtained\n"; #endif #ifdef DEBUG_SKOLEM cout << "\nObtaining F(X', Y)\n"; #endif renamed_conjunction_of_factors = conjunction_of_factors; for(int var_to_elim_index = 1; var_to_elim_index <= number_of_vars_to_elim; var_to_elim_index++) { #ifdef DEBUG_SKOLEM cout << "\nvar_to_elim_index = " << var_to_elim_index << endl; #endif string var_to_elim = searchVarIndexToVarNameMap(var_index_to_var_name_map, var_to_elim_index); #ifdef DEBUG_SKOLEM cout << "\nvar_to_elim = " << var_to_elim << endl; #endif Aig_Obj_t* var_to_elim_renamed_obj = var_to_elim_renamed_objects[var_to_elim_index-1]; #ifdef DEBUG_SKOLEM cout << "\nReplacing "<< var_to_elim << " by renamed object for it\n"; #endif renamed_conjunction_of_factors = ReplaceLeafByExpression(renamed_conjunction_of_factors, var_to_elim, var_to_elim_renamed_obj, pub_aig_manager); } #ifdef DEBUG_SKOLEM cout << "\nF(X', Y) obtained\n"; #endif #ifdef DEBUG_SKOLEM cout << "\nObtaining disjunction_of_bad_symbols\n"; #endif if(B_i_objects.empty()) { disjunction_of_bad_symbols = createFalse(pub_aig_manager); } else { disjunction_of_bad_symbols = createOr(B_i_objects, pub_aig_manager); } #ifdef DEBUG_SKOLEM cout << "\ndisjunction_of_bad_symbols obtained\n"; #endif #ifdef DEBUG_SKOLEM string renamed_conjunction_of_factors_file_name = benchmark_name_without_extension; renamed_conjunction_of_factors_file_name += "_renamed_conjunction_of_factors"; string disjunction_of_bad_symbols_file_name = benchmark_name_without_extension; disjunction_of_bad_symbols_file_name += "_disjunction_of_bad_symbols"; cout << "\nrenamed_conjunction_of_factors computed\n"; cout << "\ndisjunction_of_bad_symbols computed\n"; writeFormulaToFile(pub_aig_manager, renamed_conjunction_of_factors, renamed_conjunction_of_factors_file_name, ".v", 0, 0); writeFormulaToFile(pub_aig_manager, disjunction_of_bad_symbols, disjunction_of_bad_symbols_file_name, ".v", 0, 0); #endif // Creating the CNFs int top_label_of_renamed_conjunction_of_factors = getCNF(pub_aig_manager, renamed_conjunction_of_factors, FixedCNF); // copy FixedCNF into CNFForRenamedConjunctionOfFactors for(int cnf_it = 0; cnf_it < FixedCNF.size(); cnf_it++) { vector clause_it = FixedCNF[cnf_it]; CNFForRenamedConjunctionOfFactors.push_back(clause_it); } number_of_variables_in_renamed_conjunction_of_factors = LabelCount-1; #ifdef DEBUG_SKOLEM cout << "\ntop_label_of_renamed_conjunction_of_factors = " << top_label_of_renamed_conjunction_of_factors << endl; showCNF(FixedCNF); #endif int top_label_of_disjunction_of_bad_symbols = getCNF(pub_aig_manager, disjunction_of_bad_symbols, FixedCNF); #ifdef DEBUG_SKOLEM cout << "\ntop_label_of_disjunction_of_bad_symbols = " << top_label_of_disjunction_of_bad_symbols << endl; showCNF(FixedCNF); #endif vector clause_1; clause_1.push_back(top_label_of_renamed_conjunction_of_factors); FixedCNF.push_back(clause_1); CNFForRenamedConjunctionOfFactors.push_back(clause_1); vector clause_2; clause_2.push_back(top_label_of_disjunction_of_bad_symbols); FixedCNF.push_back(clause_2); #ifdef DEBUG_SKOLEM cout << "\nCNFs of renamed_conjunction_of_factors and disjunction_of_bad_symbols computed\n"; showCNF(FixedCNF); #endif } void AIGBasedSkolem::computeGenericSkolemFunctionParametersInBadBased(int var_to_elim_index, Aig_Obj_t* &alpha_combined_in_bad_based) { // alpha_combined = (disjunction of alpha's of factors with var_to_elim_index) // gamma_combined = (conjunction of gamma's of factors with var_to_elim_index) // delta_combined = (disjunction of delta's of factors with var_to_elim_index) #ifdef DEBUG_SKOLEM cout << "\ncomputing generic skolem function parameters\n"; #endif set alpha_components; set gamma_components; set delta_components; for(set::iterator factor_it = FactorsWithVariable.begin(); factor_it != FactorsWithVariable.end(); factor_it++) { int factor_index = *factor_it; #ifdef DEBUG_SKOLEM cout << "\nfactor_index = " << factor_index << endl; #endif // Suppose j = factor_index // Get alpha_i_j, gamma_i_j and delta_i_j Aig_Obj_t* alpha_i_j; alpha_i_j = computeAlpha(var_to_elim_index, factor_index); assert(alpha_i_j != NULL); #ifdef DEBUG_SKOLEM writeFormulaToFile(pub_aig_manager, alpha_i_j, "alpha", ".v", var_to_elim_index, factor_index); cout << "\nalpha_" << var_to_elim_index << "_" << factor_index << " obtained\n"; #endif Aig_Obj_t* gamma_i_j; gamma_i_j = computeGamma(var_to_elim_index, factor_index); assert(gamma_i_j != NULL); #ifdef DEBUG_SKOLEM writeFormulaToFile(pub_aig_manager, gamma_i_j, "gamma", ".v", var_to_elim_index, factor_index); cout << "\ngamma_" << var_to_elim_index << "_" << factor_index << " obtained\n"; #endif Aig_Obj_t* delta_i_j; delta_i_j = computeDelta(var_to_elim_index, factor_index); assert(delta_i_j != NULL); #ifdef DEBUG_SKOLEM writeFormulaToFile(pub_aig_manager, delta_i_j, "delta", ".v", var_to_elim_index, factor_index); cout << "\ndelta_" << var_to_elim_index << "_" << factor_index << " obtained\n"; #endif alpha_components.insert(alpha_i_j); gamma_components.insert(gamma_i_j); delta_components.insert(delta_i_j); }// for each factor ends here if(checkTimeOut()) // check for time-out { cout << "\nWarning!!Time-out inside the function AIGBasedSkolem::computeGenericSkolemFunctionParametersInBadBased\n"; timed_out = true; // timed_out flag set return; } Aig_Obj_t* gamma_combined_in_bad_based; Aig_Obj_t* delta_combined_in_bad_based; if(alpha_components.empty()) // this means that gamma_combined_in_bad_based and delta_combined_in_bad_based are also empty { // following the basic definitions... alpha_combined_in_bad_based = createFalse(pub_aig_manager); gamma_combined_in_bad_based = createTrue(pub_aig_manager); delta_combined_in_bad_based = createFalse(pub_aig_manager); } else { alpha_combined_in_bad_based = createOr(alpha_components, pub_aig_manager); gamma_combined_in_bad_based = createAnd(gamma_components, pub_aig_manager); delta_combined_in_bad_based = createOr(delta_components, pub_aig_manager); } assert(alpha_combined_in_bad_based != NULL); assert(gamma_combined_in_bad_based != NULL); assert(delta_combined_in_bad_based != NULL); #ifdef DEBUG_SKOLEM cout << "\nalpha_combined computed\n"; writeFormulaToFile(pub_aig_manager, alpha_combined_in_bad_based, "alpha_combined", ".v", var_to_elim_index, 0); cout << "\ngamma_combined computed\n"; writeFormulaToFile(pub_aig_manager, gamma_combined_in_bad_based, "gamma_combined", ".v", var_to_elim_index, 0); cout << "\ndelta_combined computed\n"; writeFormulaToFile(pub_aig_manager, delta_combined_in_bad_based, "delta_combined", ".v", var_to_elim_index, 0); #endif #ifdef RECORD_KEEP NumberOfFactors = FactorsWithVariable.size(); #endif } void AIGBasedSkolem::computeGenericSkolemFunctionParametersInBddBased(int var_to_elim_index, Aig_Obj_t* &cofactor_one_in_bdd_based, Aig_Obj_t* &cofactor_zero_in_bdd_based) { // We need to compute cofactor_one_in_bdd_based = (conjunction of co-factor-1_i_j's) // cofactor_zero_in_bdd_based = (conjunction of co-factor-0_i_j's) // Then, // alpha_combined = cofactor_one_in_bdd_based \wedge ~cofactor_zero_in_bdd_based // gamma_combined = cofactor_one_in_bdd_based \wedge cofactor_zero_in_bdd_based // delta_combined = ~cofactor_one_in_bdd_based \wedge ~cofactor_zero_in_bdd_based set cofactor_one_components; set cofactor_zero_components; #ifdef DEBUG_SKOLEM cout << "\ncomputing individual co-factors\n"; #endif #ifdef PRINT_VERY_DETAILED_RECORDS_ON_SCREEN cout << "\ncomputing individual co-factors\n"; #endif for(set::iterator factor_it = FactorsWithVariable.begin(); factor_it != FactorsWithVariable.end(); factor_it++) { int factor_index = *factor_it; #ifdef DEBUG_SKOLEM cout << "\nfactor_index = " << factor_index << endl; #endif // Suppose j = factor_index Aig_Obj_t* cofactor_1_i_j; cofactor_1_i_j = computeCofactorOne(var_to_elim_index, factor_index); assert(cofactor_1_i_j != NULL); cofactor_one_components.insert(cofactor_1_i_j); Aig_Obj_t* cofactor_0_i_j; cofactor_0_i_j = computeCofactorZero(var_to_elim_index, factor_index); assert(cofactor_0_i_j != NULL); cofactor_zero_components.insert(cofactor_0_i_j); }// for each factor ends here if(cofactor_one_components.size() == 0) { cofactor_one_in_bdd_based = createTrue(pub_aig_manager); assert(cofactor_one_in_bdd_based != NULL); } else { cofactor_one_in_bdd_based = createAnd(cofactor_one_components, pub_aig_manager); assert(cofactor_one_in_bdd_based != NULL); } if(cofactor_zero_components.size() == 0) { cofactor_zero_in_bdd_based = createTrue(pub_aig_manager); assert(cofactor_zero_in_bdd_based != NULL); } else { cofactor_zero_in_bdd_based = createAnd(cofactor_zero_components, pub_aig_manager); assert(cofactor_zero_in_bdd_based != NULL); } Aig_Obj_t* alpha_combined_in_bdd_based; Aig_Obj_t* gamma_combined_in_bdd_based; Aig_Obj_t* delta_combined_in_bdd_based; alpha_combined_in_bdd_based = createAnd(cofactor_one_in_bdd_based, createNot(cofactor_zero_in_bdd_based, pub_aig_manager), pub_aig_manager); gamma_combined_in_bdd_based = createAnd(cofactor_one_in_bdd_based, cofactor_zero_in_bdd_based, pub_aig_manager); delta_combined_in_bdd_based = createAnd(createNot(cofactor_one_in_bdd_based, pub_aig_manager), createNot(cofactor_zero_in_bdd_based, pub_aig_manager), pub_aig_manager); assert(alpha_combined_in_bdd_based != NULL); assert(gamma_combined_in_bdd_based != NULL); assert(delta_combined_in_bdd_based != NULL); #ifdef DEBUG_SKOLEM cout << "\ncofactor_zero_in_bdd_based computed\n"; writeFormulaToFile(pub_aig_manager, cofactor_zero_in_bdd_based, "cofactor_zero", ".v", var_to_elim_index, 0); cout << "\ncofactor_one_in_bdd_based computed\n"; writeFormulaToFile(pub_aig_manager, cofactor_one_in_bdd_based, "cofactor_one", ".v", var_to_elim_index, 0); cout << "\nalpha_combined computed\n"; writeFormulaToFile(pub_aig_manager, alpha_combined_in_bdd_based, "alpha_combined", ".v", var_to_elim_index, 0); cout << "\ngamma_combined computed\n"; writeFormulaToFile(pub_aig_manager, gamma_combined_in_bdd_based, "gamma_combined", ".v", var_to_elim_index, 0); cout << "\ndelta_combined computed\n"; writeFormulaToFile(pub_aig_manager, delta_combined_in_bdd_based, "delta_combined", ".v", var_to_elim_index, 0); #endif #ifdef RECORD_KEEP NumberOfFactors = FactorsWithVariable.size(); #endif } void AIGBasedSkolem::updateBadSetWithGivenAlphaCombined(int var_to_elim_index, Aig_Obj_t* alpha_combined_in_bad_based) { // bad_set = (disjunction of alpha's of factors with var_to_elim_index \vee co-factor-0 of bad_set)\wedge // (disjunction of beta's of factors with var_to_elim_index \vee co-factor-1 of bad_set) #ifdef DEBUG_SKOLEM cout << "\nupdating aig_bad_set\n"; #endif set alpha_components; set beta_components; for(set::iterator factor_it = FactorsWithVariable.begin(); factor_it != FactorsWithVariable.end(); factor_it++) { int factor_index = *factor_it; #ifdef DEBUG_SKOLEM cout << "\nfactor_index = " << factor_index << endl; #endif // Suppose j = factor_index // Get beta_i_j Aig_Obj_t* beta_i_j; beta_i_j = computeBeta(var_to_elim_index, factor_index); assert(beta_i_j != NULL); #ifdef DEBUG_SKOLEM writeFormulaToFile(pub_aig_manager, beta_i_j, "beta", ".v", var_to_elim_index, factor_index); cout << "\nbeta_" << var_to_elim_index << "_" << factor_index << " obtained\n"; #endif beta_components.insert(beta_i_j); }// for each factor ends here alpha_components.insert(alpha_combined_in_bad_based); if(checkTimeOut()) // check for time-out { cout << "\nWarning!!Time-out inside the function AIGBasedSkolem::updateBadSetWithGivenAlphaCombined\n"; timed_out = true; // timed_out flag set return; } if(!formulaFreeOfVariable(aig_bad_set, var_to_elim_index)) { // replace var_to_elim_index in bad_set by zero Aig_Obj_t* cofactor_zero = replaceVariableByConstant(aig_bad_set, var_to_elim_index, 0); assert(cofactor_zero != NULL); Aig_Obj_t* cofactor_one = replaceVariableByConstant(aig_bad_set, var_to_elim_index, 1); assert(cofactor_one != NULL); alpha_components.insert(cofactor_zero); beta_components.insert(cofactor_one); } else { alpha_components.insert(aig_bad_set); beta_components.insert(aig_bad_set); } Aig_Obj_t* alpha_part; alpha_part = createOr(alpha_components, pub_aig_manager); assert(alpha_part != NULL); Aig_Obj_t* beta_part; beta_part = createOr(beta_components, pub_aig_manager); assert(beta_part != NULL); aig_bad_set = createAnd(alpha_part, beta_part, pub_aig_manager); assert(aig_bad_set != NULL); #ifdef DEBUG_SKOLEM cout << "\nbad_set computed\n"; writeFormulaToFile(pub_aig_manager, aig_bad_set, "bad_set", ".v", var_to_elim_index, 0); #endif #ifdef RECORD_KEEP DeltaCombinedSize = computeSize(aig_bad_set, pub_aig_manager); #endif #ifdef PRINT_VERY_DETAILED_RECORDS_ON_SCREEN cout << "\nsize of bad_set is " << DeltaCombinedSize << endl; #endif if(checkTimeOut()) // check for time-out { cout << "\nWarning!!Time-out inside the function AIGBasedSkolem::updateBadSet\n"; timed_out = true; // timed_out flag set return; } } Aig_Obj_t* AIGBasedSkolem::computeAlphaCombined(int var_to_elim_index) { // Let us compute alpha_combined_{var_to_elim_index} // Suppose i = var_to_elim_index // i.e. we need to compute alpha_combined_{i} // alpha_combined_{i} = disjunction of alpha_combined_components set alpha_combined_components; #ifdef DEBUG_SKOLEM cout << "\ncomputing components of alpha_combined\n"; #endif #ifdef PRINT_VERY_DETAILED_RECORDS_ON_SCREEN cout << "\ncomputing components of alpha_combined\n"; #endif for(set::iterator factor_it = FactorsWithVariable.begin(); factor_it != FactorsWithVariable.end(); factor_it++) { int factor_index = *factor_it; #ifdef DEBUG_SKOLEM cout << "\nfactor_index = " << factor_index << endl; #endif // Suppose j = factor_index // Each alpha_combined_component_i_j is the conjunction of // alpha_i_j and all_agree_with_i_j Aig_Obj_t* alpha_i_j; alpha_i_j = computeAlpha(var_to_elim_index, factor_index); assert(alpha_i_j != NULL); #ifdef DEBUG_SKOLEM writeFormulaToFile(pub_aig_manager, alpha_i_j, "alpha", ".v", var_to_elim_index, factor_index); #endif // all_agree_with_i_j = conjunction of all_agree_with_components Aig_Obj_t* all_agree_with_i_j; set all_agree_with_components; #ifdef DEBUG_SKOLEM cout << "\nCreating all_agree_with_i_j" << endl; #endif for(set::iterator agree_it = FactorsWithVariable.begin(); agree_it != FactorsWithVariable.end(); agree_it++) { int agree_index = *agree_it; #ifdef DEBUG_SKOLEM cout << "\nagree_index = " << agree_index << endl; #endif // Suppose k = agree_index if(factor_index == agree_index) // j == k; no need to consider { #ifdef DEBUG_SKOLEM cout << "\nfactor_index == agree_index; no need to consider" << endl; #endif continue; } #ifdef DEBUG_SKOLEM cout << "\nfactor_index != agree_index" << endl; #endif Aig_Obj_t* alpha_i_k; alpha_i_k = computeAlpha(var_to_elim_index, agree_index); assert(alpha_i_k != NULL); #ifdef DEBUG_SKOLEM writeFormulaToFile(pub_aig_manager, alpha_i_k, "alpha", ".v", var_to_elim_index, agree_index); #endif Aig_Obj_t* gamma_i_k; gamma_i_k = computeGamma(var_to_elim_index, agree_index); assert(gamma_i_k != NULL); #ifdef DEBUG_SKOLEM writeFormulaToFile(pub_aig_manager, gamma_i_k, "gamma", ".v", var_to_elim_index, agree_index); #endif Aig_Obj_t* all_agree_with_component = createOr(alpha_i_k, gamma_i_k, pub_aig_manager); assert(all_agree_with_component != NULL); #ifdef DEBUG_SKOLEM writeFormulaToFile(pub_aig_manager, all_agree_with_component, "all_agree_with_component", ".v", var_to_elim_index, agree_index); #endif all_agree_with_components.insert(all_agree_with_component); } // for each agree factor ends here // computing all_agree_with_i_j // recall that all_agree_with_i_j = conjunction of all_agree_with_components if(all_agree_with_components.size() == 0) { all_agree_with_i_j = NULL; #ifdef DEBUG_SKOLEM cout << "\nall_agree_with_i_j = NULL" << endl; #endif } else { all_agree_with_i_j = createAnd(all_agree_with_components, pub_aig_manager); assert(all_agree_with_i_j != NULL); #ifdef DEBUG_SKOLEM writeFormulaToFile(pub_aig_manager, all_agree_with_i_j, "all_agree_with_i_j", ".v", var_to_elim_index, factor_index); #endif } // recall that alpha_combined_component_i_j is the conjunction of // alpha_i_j and all_agree_with_i_j Aig_Obj_t* alpha_combined_component; if(all_agree_with_i_j == NULL) { alpha_combined_component = alpha_i_j; } else { alpha_combined_component = createAnd(alpha_i_j, all_agree_with_i_j, pub_aig_manager); assert(alpha_combined_component != NULL); } #ifdef DEBUG_SKOLEM writeFormulaToFile(pub_aig_manager, alpha_combined_component, "alpha_combined_component", ".v", var_to_elim_index, factor_index); cout << "\nalpha_combined_component[" << var_to_elim_index << ", " << factor_index << "] obtained\n"; #endif alpha_combined_components.insert(alpha_combined_component); }// for each factor ends here // recall that alpha_combined = disjunction of alpha_combined_components Aig_Obj_t* alpha_combined; if(alpha_combined_components.size() == 0) // we should return false in this case (as per defn. of alpha) { alpha_combined = createFalse(pub_aig_manager); assert(alpha_combined != NULL); } else { alpha_combined = createOr(alpha_combined_components, pub_aig_manager); assert(alpha_combined != NULL); } #ifdef DEBUG_SKOLEM writeFormulaToFile(pub_aig_manager, alpha_combined, "alpha_combined", ".v", var_to_elim_index, 0); #endif #ifdef RECORD_KEEP NumberOfFactors = FactorsWithVariable.size(); #endif // Enter into matrix insertIntoOneDimensionalMatrix(AlphaCombineds, number_of_vars_to_elim, var_to_elim_index, alpha_combined, false); return alpha_combined; } // function ends here Aig_Obj_t* AIGBasedSkolem::computeAlphaCombinedForComputingAbstractSkolemFunction(int var_to_elim_index) { // Let us compute alpha_combined_{var_to_elim_index} // Suppose i = var_to_elim_index // i.e. we need to compute alpha_combined_{i} // alpha_combined_{i} = disjunction of alpha_i_j's // AS IT IS USED FOR COMPUTING ABSTRACT SKOLEM FUNCTIONS set alpha_combined_components; #ifdef DEBUG_SKOLEM cout << "\ncomputing components of alpha_combined\n"; #endif #ifdef PRINT_VERY_DETAILED_RECORDS_ON_SCREEN cout << "\ncomputing components of alpha_combined\n"; #endif for(set::iterator factor_it = FactorsWithVariable.begin(); factor_it != FactorsWithVariable.end(); factor_it++) { int factor_index = *factor_it; #ifdef DEBUG_SKOLEM cout << "\nfactor_index = " << factor_index << endl; #endif // Suppose j = factor_index // Each alpha_combined_component_i_j is alpha_i_j Aig_Obj_t* alpha_i_j; alpha_i_j = computeAlpha(var_to_elim_index, factor_index); assert(alpha_i_j != NULL); #ifdef DEBUG_SKOLEM writeFormulaToFile(pub_aig_manager, alpha_i_j, "alpha", ".v", var_to_elim_index, factor_index); #endif alpha_combined_components.insert(alpha_i_j); }// for each factor ends here // recall that alpha_combined = disjunction of alpha_combined_components Aig_Obj_t* alpha_combined; if(alpha_combined_components.size() == 0) // we should return false in this case (as per defn. of alpha) { alpha_combined = createFalse(pub_aig_manager); assert(alpha_combined != NULL); } else { alpha_combined = createOr(alpha_combined_components, pub_aig_manager); assert(alpha_combined != NULL); } #ifdef DEBUG_SKOLEM writeFormulaToFile(pub_aig_manager, alpha_combined, "alpha_combined", ".v", var_to_elim_index, 0); #endif #ifdef RECORD_KEEP NumberOfFactors = FactorsWithVariable.size(); #endif // Enter into matrix insertIntoOneDimensionalMatrix(AlphaCombineds, number_of_vars_to_elim, var_to_elim_index, alpha_combined, false); return alpha_combined; } // function ends here Aig_Obj_t* AIGBasedSkolem::computeGammaCombined(int var_to_elim_index) { // Let us compute gamma_combined_{var_to_elim_index} // Suppose i = var_to_elim_index // i.e. we need to compute gamma_combined_{i} // gamma_combined_{i} = conjunction of gamma_i_j's set gamma_combined_components; #ifdef DEBUG_SKOLEM cout << "\ncomputing components of gamma_combined\n"; #endif #ifdef PRINT_VERY_DETAILED_RECORDS_ON_SCREEN cout << "\ncomputing components of gamma_combined\n"; #endif for(set::iterator factor_it = FactorsWithVariable.begin(); factor_it != FactorsWithVariable.end(); factor_it++) { int factor_index = *factor_it; #ifdef DEBUG_SKOLEM cout << "\nfactor_index = " << factor_index << endl; #endif // Suppose j = factor_index // Each gamma_combined_component_i_j is gamma_i_j Aig_Obj_t* gamma_i_j; gamma_i_j = computeGamma(var_to_elim_index, factor_index); assert(gamma_i_j != NULL); #ifdef DEBUG_SKOLEM writeFormulaToFile(pub_aig_manager, gamma_i_j, "gamma", ".v", var_to_elim_index, factor_index); #endif gamma_combined_components.insert(gamma_i_j); }// for each factor ends here // recall that gamma_combined = conjunction of gamma_combined_components Aig_Obj_t* gamma_combined; if(gamma_combined_components.size() == 0) // we should return true in this case { gamma_combined = createTrue(pub_aig_manager); assert(gamma_combined != NULL); } else { gamma_combined = createAnd(gamma_combined_components, pub_aig_manager); assert(gamma_combined != NULL); } #ifdef DEBUG_SKOLEM writeFormulaToFile(pub_aig_manager, gamma_combined, "gamma_combined", ".v", var_to_elim_index, 0); #endif // Enter into matrix insertIntoOneDimensionalMatrix(GammaCombineds, number_of_vars_to_elim, var_to_elim_index, gamma_combined, false); return gamma_combined; } // function ends here Aig_Obj_t* AIGBasedSkolem::computeAbstractSkolemFunction(int var_to_elim_index) { bool abstract_skolem_function_for_cegar = true; if(abstract_skolem_function_for_cegar) { // abstract skolem function = (alpha_i \vee (gamma_i \wedge ~co-factor 1 of bad_i)) Aig_Obj_t* skolem_function; #ifdef RECORD_KEEP unsigned long long int alpha_duration_ms; struct timeval start_ms, finish_ms; #endif #ifdef RECORD_KEEP gettimeofday (&start_ms, NULL); #endif // computing alpha_combined_{var_to_elim_index} #ifdef DEBUG_SKOLEM cout << "\ncomputing alpha_combined_" << var_to_elim_index << "\n"; #endif Aig_Obj_t* alpha_combined = computeAlphaCombinedForComputingAbstractSkolemFunction(var_to_elim_index); assert(alpha_combined != NULL); Aig_Obj_t* alpha_combined_CO = Aig_ObjCreateCo( pub_aig_manager, alpha_combined ); // to aviod // unwanted cleanup of alpha_combined assert(alpha_combined_CO != NULL); if(checkTimeOut()) // check for time-out { cout << "\nWarning!!Time-out inside the function AIGBasedSkolem::computeAbstractSkolemFunction\n"; timed_out = true; // timed_out flag set return NULL; } #ifdef DEBUG_SKOLEM cout << "\nalpha_combined_" << var_to_elim_index << " computed\n"; #endif // computing gamma_combined_{var_to_elim_index} #ifdef DEBUG_SKOLEM cout << "\ncomputing gamma_combined_" << var_to_elim_index << "\n"; #endif Aig_Obj_t* gamma_combined = computeGammaCombined(var_to_elim_index); assert(gamma_combined != NULL); Aig_Obj_t* gamma_combined_CO = Aig_ObjCreateCo( pub_aig_manager, gamma_combined ); // to aviod // unwanted cleanup of gamma_combined assert(gamma_combined_CO != NULL); if(checkTimeOut()) // check for time-out { cout << "\nWarning!!Time-out inside the function AIGBasedSkolem::computeAbstractSkolemFunction\n"; timed_out = true; // timed_out flag set return NULL; } #ifdef DEBUG_SKOLEM cout << "\ngamma_combined_" << var_to_elim_index << " computed\n"; #endif // computing bad_part_{var_to_elim_index} #ifdef DEBUG_SKOLEM cout << "\ncomputing bad_part_" << var_to_elim_index << "\n"; #endif Aig_Obj_t* bad_part; if(include_bad_in_initial_abstractions) { // get the bad set for var_to_elim_index // bad_part = ~bad_set with x_var_to_elim_index set to 1 Aig_Obj_t* bad_set_obj; bad_set_obj = searchOneDimensionalMatrix(BadSets, number_of_vars_to_elim, var_to_elim_index); assert(bad_set_obj != NULL); // bad_set_i obtained if(!formulaFreeOfVariable(bad_set_obj, var_to_elim_index)) { // replace var_to_elim_index in bad_set_obj by one Aig_Obj_t* cofactor_one = replaceVariableByConstant(bad_set_obj, var_to_elim_index, 1); assert(cofactor_one != NULL); bad_part = createNot(cofactor_one, pub_aig_manager); assert(bad_part != NULL); } else { Aig_Obj_t* cofactor_one = bad_set_obj; bad_part = createNot(cofactor_one, pub_aig_manager); assert(bad_part != NULL); } } else { bad_part = createTrue(pub_aig_manager); } #ifdef DEBUG_SKOLEM cout << "\nbad_part computed\n"; writeFormulaToFile(pub_aig_manager, bad_part, "bad_part", ".v", var_to_elim_index, 0); #endif Aig_Obj_t* skolem_function_component_2 = createAnd(gamma_combined, bad_part, pub_aig_manager); assert(skolem_function_component_2 != NULL); skolem_function = createOr(alpha_combined, skolem_function_component_2, pub_aig_manager); assert(skolem_function != NULL); Aig_Obj_t* skolem_function_CO = Aig_ObjCreateCo( pub_aig_manager, skolem_function ); // to aviod // unwanted cleanup of skolem_function assert(skolem_function_CO != NULL); #ifdef RECORD_KEEP gettimeofday (&finish_ms, NULL); alpha_duration_ms = finish_ms.tv_sec * 1000 + finish_ms.tv_usec / 1000; alpha_duration_ms -= start_ms.tv_sec * 1000 + start_ms.tv_usec / 1000; AlphaCombGenTime = alpha_duration_ms; AlphaPartSize = computeSize(alpha_combined, pub_aig_manager); DeltaPartSize = computeSize(gamma_combined, pub_aig_manager); DeltaCombinedSize = computeSize(bad_part, pub_aig_manager); #endif #ifdef DEBUG_SKOLEM cout << "\nabstract skolem_function computed\n"; #endif #ifdef PRINT_SKOLEM_FUNCTIONS string skolem_function_file_name = benchmark_name_without_extension; skolem_function_file_name += "_skolem_function"; writeFormulaToFile(pub_aig_manager, skolem_function, skolem_function_file_name, ".v", var_to_elim_index, cegar_iteration_number); #endif // Enter into matrix insertIntoOneDimensionalMatrix(SkolemFunctions, number_of_vars_to_elim, var_to_elim_index, skolem_function, false); return skolem_function; } else { bool include_bad_part_in_abstract_skolem_function = true; // if include_bad_part_in_abstract_skolem_function = true then // abstract skolem function = (conjunction of co-factor-1's of factors with var_to_elim_index) \wedge ~(co-factor 1 of bad_var_to_elim_index) // else // abstract skolem function = (conjunction of co-factor-1's of factors with var_to_elim_index) Aig_Obj_t* skolem_function; // computing conjunction of co-factor-1's of factors with var_to_elim_index #ifdef RECORD_KEEP unsigned long long int alpha_duration_ms, delta_duration_ms; struct timeval start_ms, finish_ms; #endif #ifdef RECORD_KEEP gettimeofday (&start_ms, NULL); #endif // computing alpha_combined_or_gamma_combined_{var_to_elim_index} #ifdef DEBUG_SKOLEM cout << "\ncomputing alpha_combined_or_gamma_combined_" << var_to_elim_index << "\n"; #endif Aig_Obj_t* alpha_combined_or_gamma_combined = computeAlphaCombinedOrGammaCombined(var_to_elim_index); assert(alpha_combined_or_gamma_combined != NULL); if(checkTimeOut()) // check for time-out { cout << "\nWarning!!Time-out inside the function AIGBasedSkolem::computeAbstractSkolemFunction\n"; timed_out = true; // timed_out flag set return NULL; } #ifdef DEBUG_SKOLEM cout << "\nalpha_combined_or_gamma_combined_" << var_to_elim_index << " computed\n"; #endif #ifdef RECORD_KEEP gettimeofday (&finish_ms, NULL); alpha_duration_ms = finish_ms.tv_sec * 1000 + finish_ms.tv_usec / 1000; alpha_duration_ms -= start_ms.tv_sec * 1000 + start_ms.tv_usec / 1000; AlphaCombGenTime = alpha_duration_ms; #endif #ifdef DETAILED_RECORD_KEEP cout << "\ncomputeAlphaCombinedOrGammaCombined finished in " << alpha_duration_ms << "milli seconds\n"; #endif #ifdef PRINT_VERY_DETAILED_RECORDS_ON_SCREEN cout << "\nsize of alpha_combined_or_gamma_combined is " << computeSize(alpha_combined_or_gamma_combined, pub_aig_manager) << endl; #endif #ifdef RECORD_KEEP AlphaPartSize = computeSize(alpha_combined_or_gamma_combined, pub_aig_manager); #endif if(include_bad_part_in_abstract_skolem_function) { // computing cofactor-1 of bad part #ifdef RECORD_KEEP gettimeofday (&start_ms, NULL); #endif // computing bad_part_{var_to_elim_index} #ifdef DEBUG_SKOLEM cout << "\ncomputing bad_part_" << var_to_elim_index << "\n"; #endif Aig_Obj_t* bad_part; // get the bad set for var_to_elim_index Aig_Obj_t* bad_set_obj; bad_set_obj = searchOneDimensionalMatrix(BadSets, number_of_vars_to_elim, var_to_elim_index); assert(bad_set_obj != NULL); // bad_set_i obtained if(!formulaFreeOfVariable(bad_set_obj, var_to_elim_index)) { // replace var_to_elim_index in bad_set_obj by one Aig_Obj_t* cofactor_one = replaceVariableByConstant(bad_set_obj, var_to_elim_index, 1); assert(cofactor_one != NULL); bad_part = createNot(cofactor_one, pub_aig_manager); assert(bad_part != NULL); } else { Aig_Obj_t* cofactor_one = bad_set_obj; bad_part = createNot(cofactor_one, pub_aig_manager); assert(bad_part != NULL); } #ifdef DEBUG_SKOLEM cout << "\nbad_part computed\n"; writeFormulaToFile(pub_aig_manager, bad_part, "bad_part", ".v", var_to_elim_index, 0); #endif #ifdef RECORD_KEEP gettimeofday (&finish_ms, NULL); delta_duration_ms = finish_ms.tv_sec * 1000 + finish_ms.tv_usec / 1000; delta_duration_ms -= start_ms.tv_sec * 1000 + start_ms.tv_usec / 1000; DeltaPartGenTime = delta_duration_ms; #endif #ifdef DETAILED_RECORD_KEEP cout << "\ncomputing delta part finished in " << delta_duration_ms << "milli seconds\n"; #endif #ifdef PRINT_VERY_DETAILED_RECORDS_ON_SCREEN cout << "\nsize of bad_part is " << computeSize(bad_part, pub_aig_manager) << endl; #endif #ifdef RECORD_KEEP DeltaPartSize = computeSize(bad_part, pub_aig_manager); #endif //computing abstract skolem_function // skolem_function = alpha_combined_or_gamma_combined \wedge bad_part skolem_function = createAnd(alpha_combined_or_gamma_combined, bad_part, pub_aig_manager); assert(skolem_function != NULL); } else { // computing cofactor-1 of bad part is not needed #ifdef RECORD_KEEP DeltaPartGenTime = 0; DeltaPartSize = 0; #endif //computing abstract skolem_function // skolem_function = alpha_combined_or_gamma_combined \wedge bad_part skolem_function = alpha_combined_or_gamma_combined; } #ifdef DEBUG_SKOLEM cout << "\nabstract skolem_function computed\n"; #endif #ifdef PRINT_SKOLEM_FUNCTIONS string skolem_function_file_name = benchmark_name_without_extension; skolem_function_file_name += "_skolem_function"; writeFormulaToFile(pub_aig_manager, skolem_function, skolem_function_file_name, ".v", var_to_elim_index, cegar_iteration_number); #endif // Enter into matrix insertIntoOneDimensionalMatrix(SkolemFunctions, number_of_vars_to_elim, var_to_elim_index, skolem_function, false); return skolem_function; } } void AIGBasedSkolem::replaceConnectionsByFormulas_In_Two_Point_Connections() { for(int var_to_elim_index = 1; var_to_elim_index <= number_of_vars_to_elim; var_to_elim_index++) { #ifdef DEBUG_SKOLEM cout << "\nvar_to_elim_index = " << var_to_elim_index << endl; #endif Aig_Obj_t* skolem_function_i; skolem_function_i = searchOneDimensionalMatrix(SkolemFunctions, number_of_vars_to_elim, var_to_elim_index); assert(skolem_function_i != NULL); #ifdef DEBUG_SKOLEM writeFormulaToFile(pub_aig_manager, skolem_function_i, "skolemfunction_before_replaceConnections", ".v", var_to_elim_index, 0); #endif map >::iterator start_locations_it = start_locations_of_connections_skolem_function_is_sensitive_to.find(var_to_elim_index); if(start_locations_it == start_locations_of_connections_skolem_function_is_sensitive_to.end()) { // skolem_function_i is not dependent on any other variable's skolem function // no need to do anything #ifdef DEBUG_SKOLEM cout << "\nskolem_function_" << var_to_elim_index << " is not dependent on any other variable's skolem function " << endl; #endif continue; } else { assert(var_to_elim_index >= 3); set start_locations_set = start_locations_it->second; list start_locations_list(start_locations_set.begin(), start_locations_set.end()); start_locations_list.reverse(); for(list::iterator start_locations_list_it = start_locations_list.begin(); start_locations_list_it != start_locations_list.end(); start_locations_list_it++) { int start_index = *start_locations_list_it; #ifdef DEBUG_SKOLEM cout << "\nstart_index = " << start_index << endl; #endif assert(start_index <= var_to_elim_index-1); if(start_index < var_to_elim_index-1) { #ifdef DEBUG_SKOLEM cout << "\nLet's obtain final dag for C_" << start_index << "_" << var_to_elim_index << endl; #endif // Obtaining final dag for C_start_index_var_to_elim_index // and inserting it into Connections // Let's obtain the present dag for C_start_index_var_to_elim_index string connection_string = "C_"; char start_char[100]; sprintf(start_char, "%d", start_index); string start_string(start_char); connection_string += start_string; connection_string += "_"; char variable_char[100]; sprintf(variable_char, "%d", var_to_elim_index); string variable_string(variable_char); connection_string += variable_string; Aig_Obj_t* present_connection_dag; map::iterator Connections_it = Connections.find(connection_string); assert(Connections_it != Connections.end()); present_connection_dag = Connections_it->second; assert(present_connection_dag != NULL); // obtain the connection_dag after replacing the connections and update Connections Aig_Obj_t* changed_connection_dag; changed_connection_dag = obtainFormulaWithoutConnections(present_connection_dag); assert(changed_connection_dag != NULL); Connections[connection_string] = changed_connection_dag; } }// for ends here #ifdef DEBUG_SKOLEM cout << "\nLet's obtain final dag for skolem_function_" << var_to_elim_index << endl; #endif // Obtaining final dag for skolem_function_var_to_elim_index // and inserting it into SkolemFunctions Aig_Obj_t* changed_skolem_function_i; changed_skolem_function_i = obtainFormulaWithoutConnections(skolem_function_i); assert(changed_skolem_function_i != NULL); insertIntoOneDimensionalMatrix(SkolemFunctions, number_of_vars_to_elim, var_to_elim_index, changed_skolem_function_i, true); #ifdef DEBUG_SKOLEM writeFormulaToFile(pub_aig_manager, changed_skolem_function_i, "skolemfunction_after_replaceConnections", ".v", var_to_elim_index, 0); #endif }//else ends here }// for ends here } void AIGBasedSkolem::initializeCEGAR_using_ABC() { // Creating F(X', Y) and (B1\vee ... \vee B_n \vee B_{n+1}) #ifdef DEBUG_SKOLEM cout << "\nObtaining Ci's for X'\n"; #endif vector var_to_elim_renamed_objects; for(int var_to_elim_index = 1; var_to_elim_index <= number_of_vars_to_elim; var_to_elim_index++) { string var_to_elim = searchVarIndexToVarNameMap(var_index_to_var_name_map, var_to_elim_index); string var_to_elim_renamed = var_to_elim; var_to_elim_renamed += "_new"; Aig_Obj_t* var_to_elim_renamed_obj = Aig_ObjCreateCi(pub_aig_manager); int var_to_elim_renamed_id = Aig_ObjId(var_to_elim_renamed_obj); // no need to apply Aig_Regular() as var_to_elim_renamed_obj is CI Ci_id_to_Ci_name_map.insert(make_pair(var_to_elim_renamed_id, var_to_elim_renamed)); Ci_name_to_Ci_number_map.insert(make_pair(var_to_elim_renamed, number_of_Cis)); var_to_elim_renamed_objects.push_back(var_to_elim_renamed_obj); Ci_to_eliminate_renamed_to_Ci_to_eliminate_renamed_object_map.insert(make_pair(var_to_elim_index, var_to_elim_renamed_obj)); Ci_to_eliminate_renamed_name_to_Ci_to_eliminate_renamed_object_map.insert(make_pair(var_to_elim_renamed, var_to_elim_renamed_obj)); number_of_Cis++; } #ifdef DEBUG_SKOLEM cout << "\nCi's for X' obtained\n"; #endif set B_i_objects; if(use_mu_based_scheme_with_optimizations_in_cegar || use_mu_based_scheme_in_cegar) { // create B_1,...,B_n #ifdef DEBUG_SKOLEM cout << "\nObtaining Ci's for Bad's\n"; #endif for(int bad_location_index = 1; bad_location_index <= number_of_vars_to_elim; bad_location_index++) { string B_i = "B_"; char bad_count_char[100]; sprintf(bad_count_char, "%d", bad_location_index); string bad_count_string(bad_count_char); B_i += bad_count_string; Aig_Obj_t* B_i_obj = Aig_ObjCreateCi(pub_aig_manager); int B_i_id = Aig_ObjId(B_i_obj); // no need to apply Aig_Regular() as B_i_obj is CI Ci_id_to_Ci_name_map.insert(make_pair(B_i_id, B_i)); Ci_name_to_Ci_number_map.insert(make_pair(B_i, number_of_Cis)); B_i_index_to_B_i_object_map.insert(make_pair(bad_location_index, B_i_obj)); B_i_objects.insert(B_i_obj); number_of_Cis++; } #ifdef DEBUG_SKOLEM cout << "\nCi's for Bad's obtained\n"; #endif } else //if(!use_mu_based_scheme_in_cegar) { // create B_1,...,B_{n+1} #ifdef DEBUG_SKOLEM cout << "\nObtaining Ci's for Bad's\n"; #endif for(int bad_location_index = 1; bad_location_index <= number_of_vars_to_elim+1; bad_location_index++) { string B_i = "B_"; char bad_count_char[100]; sprintf(bad_count_char, "%d", bad_location_index); string bad_count_string(bad_count_char); B_i += bad_count_string; Aig_Obj_t* B_i_obj = Aig_ObjCreateCi(pub_aig_manager); int B_i_id = Aig_ObjId(B_i_obj); // no need to apply Aig_Regular() as B_i_obj is CI Ci_id_to_Ci_name_map.insert(make_pair(B_i_id, B_i)); Ci_name_to_Ci_number_map.insert(make_pair(B_i, number_of_Cis)); B_i_index_to_B_i_object_map.insert(make_pair(bad_location_index, B_i_obj)); B_i_objects.insert(B_i_obj); number_of_Cis++; } #ifdef DEBUG_SKOLEM cout << "\nCi's for Bad's obtained\n"; #endif } if(!(use_mu_based_scheme_with_optimizations_in_cegar && !use_incremental_sat_solving_in_mu_based_scheme_with_optimizations_in_cegar)) { #ifdef DEBUG_SKOLEM cout << "\nObtaining F(X', Y)\n"; #endif cout << "\nObtaining F(X', Y)\n"; renamed_conjunction_of_factors = conjunction_of_factors; for(int var_to_elim_index = 1; var_to_elim_index <= number_of_vars_to_elim; var_to_elim_index++) { #ifdef DEBUG_SKOLEM cout << "\nvar_to_elim_index = " << var_to_elim_index << endl; #endif string var_to_elim = searchVarIndexToVarNameMap(var_index_to_var_name_map, var_to_elim_index); #ifdef DEBUG_SKOLEM cout << "\nvar_to_elim = " << var_to_elim << endl; #endif Aig_Obj_t* var_to_elim_renamed_obj = var_to_elim_renamed_objects[var_to_elim_index-1]; #ifdef DEBUG_SKOLEM cout << "\nReplacing "<< var_to_elim << " by renamed object for it\n"; #endif renamed_conjunction_of_factors = ReplaceLeafByExpression(renamed_conjunction_of_factors, var_to_elim, var_to_elim_renamed_obj, pub_aig_manager); } #ifdef DEBUG_SKOLEM cout << "\nF(X', Y) obtained\n"; #endif cout << "\nF(X', Y) obtained\n"; } //if(!use_mu_based_scheme_in_cegar && !(use_mu_based_scheme_with_optimizations_in_cegar && !use_incremental_sat_solving_in_mu_based_scheme_with_optimizations_in_cegar)) if(!(use_mu_based_scheme_with_optimizations_in_cegar && !use_incremental_sat_solving_in_mu_based_scheme_with_optimizations_in_cegar)) { #ifdef DEBUG_SKOLEM cout << "\nObtaining disjunction_of_bad_symbols\n"; #endif if(B_i_objects.empty()) { disjunction_of_bad_symbols = createFalse(pub_aig_manager); } else { disjunction_of_bad_symbols = createOr(B_i_objects, pub_aig_manager); } #ifdef DEBUG_SKOLEM cout << "\ndisjunction_of_bad_symbols obtained\n"; #endif } if(!(use_mu_based_scheme_with_optimizations_in_cegar && !use_incremental_sat_solving_in_mu_based_scheme_with_optimizations_in_cegar)) { #ifdef DEBUG_SKOLEM string renamed_conjunction_of_factors_file_name = benchmark_name_without_extension; renamed_conjunction_of_factors_file_name += "_renamed_conjunction_of_factors"; cout << "\nrenamed_conjunction_of_factors computed\n"; writeFormulaToFile(pub_aig_manager, renamed_conjunction_of_factors, renamed_conjunction_of_factors_file_name, ".v", 0, 0); #endif Aig_Obj_t* renamed_conjunction_of_factors_CO = Aig_ObjCreateCo( pub_aig_manager, renamed_conjunction_of_factors ); // to aviod // unwanted cleanup of renamed_conjunction_of_factors assert(renamed_conjunction_of_factors_CO != NULL); } //if(!use_mu_based_scheme_in_cegar && !(use_mu_based_scheme_with_optimizations_in_cegar && !use_incremental_sat_solving_in_mu_based_scheme_with_optimizations_in_cegar)) if(!(use_mu_based_scheme_with_optimizations_in_cegar && !use_incremental_sat_solving_in_mu_based_scheme_with_optimizations_in_cegar)) { #ifdef DEBUG_SKOLEM string disjunction_of_bad_symbols_file_name = benchmark_name_without_extension; disjunction_of_bad_symbols_file_name += "_disjunction_of_bad_symbols"; cout << "\ndisjunction_of_bad_symbols computed\n"; writeFormulaToFile(pub_aig_manager, disjunction_of_bad_symbols, disjunction_of_bad_symbols_file_name, ".v", 0, 0); #endif Aig_Obj_t* disjunction_of_bad_symbols_CO = Aig_ObjCreateCo( pub_aig_manager, disjunction_of_bad_symbols ); // to aviod // unwanted cleanup of disjunction_of_bad_symbols assert(disjunction_of_bad_symbols_CO != NULL); } if(use_mu_based_scheme_with_optimizations_in_cegar && use_incremental_sat_solving_in_mu_based_scheme_with_optimizations_in_cegar) { #ifdef DEBUG_SKOLEM cout << "\ncreating bads_to_exclude\n"; #endif map > bad_supports; for(int var_to_elim_index = 1; var_to_elim_index <= number_of_vars_to_elim; var_to_elim_index++) { Aig_Obj_t* bad_dag; bad_dag = searchOneDimensionalMatrix(BadSets, number_of_vars_to_elim, var_to_elim_index); assert(bad_dag != NULL); set support_bad_dag; computeSupport(bad_dag, support_bad_dag, pub_aig_manager); bad_supports.insert(make_pair(var_to_elim_index, support_bad_dag)); } set frozen_support; frozen_support = variables_not_quantified; for(int var_to_elim_index = number_of_vars_to_elim-1; var_to_elim_index >= 1; var_to_elim_index--) { set bads_to_exclude_for_me; int last_frozen = var_to_elim_index + 1; string var_last_frozen = searchVarIndexToVarNameMap(var_index_to_var_name_map, last_frozen); frozen_support.insert(var_last_frozen); for(int lower_index = number_of_vars_to_elim; lower_index >= last_frozen; lower_index--) { bads_to_exclude_for_me.insert(lower_index); } for(int upper_index = last_frozen-1; upper_index >= 1; upper_index--) { set support_bad_upper_index = bad_supports[upper_index]; set remaining_variables_in_support_bad_upper_index; set_difference(support_bad_upper_index.begin(), support_bad_upper_index.end(), frozen_support.begin(), frozen_support.end(), inserter(remaining_variables_in_support_bad_upper_index, remaining_variables_in_support_bad_upper_index.begin())); if(remaining_variables_in_support_bad_upper_index.empty()) { bads_to_exclude_for_me.insert(upper_index); } }//for #ifdef DEBUG_SKOLEM cout << "\nbads_to_exclude["<< var_to_elim_index << "] is\n"; showSet(bads_to_exclude_for_me, "bads_to_exclude_for_me"); #endif bads_to_exclude.insert(make_pair(var_to_elim_index, bads_to_exclude_for_me)); }//for }//if(use_mu_based_scheme_with_optimizations_in_cegar && use_incremental_sat_solving_in_mu_based_scheme_with_optimizations_in_cegar) ends here }//function bool AIGBasedSkolem::checkIfSkolemFunctionsAreExact_using_ABC_with_Cyclic_Two_Point_Connections(map &Model_of_ExactnessCheck, map &Refinement_Hint_To_Eliminate_This_CEX) { Aig_Obj_t* exactnesscheck; #ifdef RECORD_KEEP string record_file; record_file = logfile_prefix; record_file += "skolem_function_generation_details.txt"; FILE* record_fp = fopen(record_file.c_str(), "a+"); assert(record_fp != NULL); #endif if(cegar_iteration_number == 0) { // Create the dag for // F(X',Y) \wedge (B1\vee ... \vee B_n \vee B_{n+1}) \wedge // (B_1 = bad_set_1) \wedge ... \wedge (B_n = bad_set_n) \wedge (B_{n+1} = bad_set_{n+1}) \wedge // (x_1 = psi_1) \wedge ... \wedge (x_n = psi_n) // dag for F(X',Y) is already created in renamed_conjunction_of_factors // dag for (B1\vee ... \vee B_n \vee B_{n+1}) is already created in disjunction_of_bad_symbols // Let's first create dag for (B_1 = bad_set_1) \wedge ... \wedge (B_n = bad_set_n) \wedge (B_{n+1} = bad_set_{n+1}) set B_equivalence_objects; for(int bad_location_index = 1; bad_location_index <= number_of_vars_to_elim+1; bad_location_index++) { // Let bad_location_index be i // Obtaining dag for bad_set_i Aig_Obj_t* bad_set_obj; bad_set_obj = searchOneDimensionalMatrix(BadSets, number_of_vars_to_elim+1, bad_location_index); assert(bad_set_obj != NULL); // Obtaining dag for B_i map::iterator B_i_index_to_B_i_object_map_iterator = B_i_index_to_B_i_object_map.find(bad_location_index); assert(B_i_index_to_B_i_object_map_iterator != B_i_index_to_B_i_object_map.end()); Aig_Obj_t* B_obj = B_i_index_to_B_i_object_map_iterator->second; Aig_Obj_t* B_equivalence_i = createEquivalence(bad_set_obj, B_obj, pub_aig_manager); B_equivalence_objects.insert(B_equivalence_i); } assert(!B_equivalence_objects.empty()); B_equivalence_part = createAnd(B_equivalence_objects, pub_aig_manager); assert(B_equivalence_part != NULL); // Let's create dag for (x_1 = psi_1) \wedge ... \wedge (x_n = psi_n) Aig_Obj_t* S_equivalence_part; set S_equivalence_objects; for(int var_to_elim_index = 1; var_to_elim_index <= number_of_vars_to_elim; var_to_elim_index++) { // obtaining dag for x_i string var_to_elim = searchVarIndexToVarNameMap(var_index_to_var_name_map, var_to_elim_index); map::iterator Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it = Ci_to_eliminate_name_to_Ci_to_eliminate_object_map.find(var_to_elim); assert(Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it != Ci_to_eliminate_name_to_Ci_to_eliminate_object_map.end()); Aig_Obj_t* var_to_elim_obj = Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it->second; // obtaining \psi_i Aig_Obj_t* skolem_function; skolem_function = searchOneDimensionalMatrix(SkolemFunctions, number_of_vars_to_elim, var_to_elim_index); assert(skolem_function != NULL); Aig_Obj_t* S_equivalence_i = createEquivalence(skolem_function, var_to_elim_obj, pub_aig_manager); S_equivalence_objects.insert(S_equivalence_i); } assert(!S_equivalence_objects.empty()); S_equivalence_part = createAnd(S_equivalence_objects, pub_aig_manager); assert(S_equivalence_part != NULL); #ifdef DEBUG_SKOLEM string B_equivalence_part_file_name = benchmark_name_without_extension; B_equivalence_part_file_name += "_B_equivalence_part"; string S_equivalence_part_file_name = benchmark_name_without_extension; S_equivalence_part_file_name += "_S_equivalence_part"; cout << "\nB_equivalence_part computed\n"; cout << "\nS_equivalence_part computed\n"; writeFormulaToFile(pub_aig_manager, B_equivalence_part, B_equivalence_part_file_name, ".v", 0, 0); writeFormulaToFile(pub_aig_manager, S_equivalence_part, S_equivalence_part_file_name, ".v", 0, 0); #endif set exactnesscheck_objects; exactnesscheck_objects.insert(renamed_conjunction_of_factors); exactnesscheck_objects.insert(disjunction_of_bad_symbols); exactnesscheck_objects.insert(S_equivalence_part); exactnesscheck_objects.insert(B_equivalence_part); exactnesscheck = createAnd(exactnesscheck_objects, pub_aig_manager); assert(exactnesscheck != NULL); } // if(cegar_iteration_number == 0) ends here else // if(cegar_iteration_number > 0) { // copy the Refinement_Hint_To_Eliminate_This_CEX to refinement_hints for(map::iterator hint_it = Refinement_Hint_To_Eliminate_This_CEX.begin(); hint_it != Refinement_Hint_To_Eliminate_This_CEX.end(); hint_it++) { int variable_index = hint_it->first; int bad_index = hint_it->second; map >::iterator refinement_hint_it = refinement_hints.find(variable_index); if(refinement_hint_it == refinement_hints.end()) // entry does not exist for variable_index { set bad_indices; bad_indices.insert(bad_index); refinement_hints.insert(make_pair(variable_index, bad_indices)); } else // entry exists for variable_index { (refinement_hint_it->second).insert(bad_index); } } #ifdef DEBUG_SKOLEM cout << "\nThe refinement hint to eliminate this counterexample is copied into refinement hints\n"; #endif #ifdef RECORD_KEEP fprintf(record_fp, "\t"); #endif // take each hint in Refinement_Hint_To_Eliminate_This_CEX to refinement_hints for(map::iterator hint_it = Refinement_Hint_To_Eliminate_This_CEX.begin(); hint_it != Refinement_Hint_To_Eliminate_This_CEX.end(); hint_it++) { int variable_index = hint_it->first; int bad_index = hint_it->second; #ifdef DEBUG_SKOLEM cout << "\nvariable_index = " << variable_index << "\tbad_index = " << bad_index << endl; #endif #ifdef RECORD_KEEP fprintf(record_fp, "%d-->%d,", bad_index, variable_index); #endif assert(bad_index < variable_index); #ifdef DEBUG_SKOLEM cout << "\ncreating replacement_map" << endl; #endif map replacement_map; for(int subst_index = bad_index; subst_index <= variable_index-1; subst_index++) { // we need to replace occurences of x_subst_index by C_subst_index_variable_index // Getting the object for C_subst_index_variable_index string connection_string = "C_"; char subst_char[100]; sprintf(subst_char, "%d", subst_index); string subst_string(subst_char); connection_string += subst_string; connection_string += "_"; char variable_char[100]; sprintf(variable_char, "%d", variable_index); string variable_string(variable_char); connection_string += variable_string; #ifdef DEBUG_SKOLEM cout << "\nconnection_string = " << connection_string << endl; #endif Aig_Obj_t* connection_object; map::iterator connection_string_to_connection_object_map_it = connection_string_to_connection_object_map.find(connection_string); if(connection_string_to_connection_object_map_it != connection_string_to_connection_object_map.end()) // object for connection_string exists { #ifdef DEBUG_SKOLEM cout << "\nconnection_object exists for this connection_string" << endl; #endif connection_object = connection_string_to_connection_object_map_it->second; assert(connection_object != NULL); } else { // creating new connection #ifdef DEBUG_SKOLEM cout << "\ncreating connection_object for this connection_string" << endl; #endif connection_object = Aig_ObjCreateCi(pub_aig_manager); assert(connection_object != NULL); int connection_id = Aig_ObjId(connection_object); // no need to apply Aig_Regular() as connection_object is CI Ci_id_to_Ci_name_map.insert(make_pair(connection_id, connection_string)); Ci_name_to_Ci_number_map.insert(make_pair(connection_string, number_of_Cis)); connection_string_to_connection_object_map.insert(make_pair(connection_string, connection_object)); number_of_Cis++; } replacement_map.insert(make_pair(subst_index, connection_object)); map >::iterator end_locations_it = end_locations_of_connections_sensitive_to_skolem_function.find(subst_index); if(end_locations_it == end_locations_of_connections_sensitive_to_skolem_function.end()) { set end_locations; end_locations.insert(variable_index); end_locations_of_connections_sensitive_to_skolem_function.insert(make_pair(subst_index, end_locations)); } else { (end_locations_it->second).insert(variable_index); } map >::iterator start_locations_it = start_locations_of_connections_skolem_function_is_sensitive_to.find(variable_index); if(start_locations_it == start_locations_of_connections_skolem_function_is_sensitive_to.end()) { set start_locations; start_locations.insert(subst_index); start_locations_of_connections_skolem_function_is_sensitive_to.insert(make_pair(variable_index, start_locations)); } else { (start_locations_it->second).insert(subst_index); } }// for subst_index from bad_index to variable_index-1 ends here #ifdef DEBUG_SKOLEM cout << "\nreplacement_map created" << endl; #endif // recomputing skolem function for variable at variable_index // new skolem function for variable at variable_index is // old_skolem_function \wedge (~bad_set at bad_index with replacements as per replacement_map // and x_variable_index replaced by 1) #ifdef DEBUG_SKOLEM cout << "\nrecomputing skolem function for variable at " << variable_index << endl; #endif Aig_Obj_t* bad_set_obj_at_bad_index; bad_set_obj_at_bad_index = searchOneDimensionalMatrix(BadSets, number_of_vars_to_elim, bad_index); assert(bad_set_obj_at_bad_index != NULL); Aig_Obj_t* bad_set_obj_after_replacements; if(replacement_map.size() > 0) { bad_set_obj_after_replacements = replaceVariablesByFormulas(bad_set_obj_at_bad_index, replacement_map); assert(bad_set_obj_after_replacements != NULL); } else { bad_set_obj_after_replacements = bad_set_obj_at_bad_index; } // we need to replace occurences of x_variable_index by true bad_set_obj_after_replacements = replaceVariableByConstant(bad_set_obj_after_replacements, variable_index, 1); assert(bad_set_obj_after_replacements != NULL); Aig_Obj_t* current_skolem_function; current_skolem_function = searchOneDimensionalMatrix(SkolemFunctions, number_of_vars_to_elim, variable_index); assert(current_skolem_function != NULL); Aig_Obj_t* new_skolem_function; // The new part in the skolem function is // (alpha_i \vee ~Bad after substitutions) Aig_Obj_t* alpha_combined; alpha_combined = searchOneDimensionalMatrix(AlphaCombineds, number_of_vars_to_elim, variable_index); assert(alpha_combined != NULL); Aig_Obj_t* new_component_in_skolem_function; new_component_in_skolem_function = createOr(alpha_combined, createNot(bad_set_obj_after_replacements, pub_aig_manager), pub_aig_manager); assert(new_component_in_skolem_function != NULL); new_skolem_function = createAnd(current_skolem_function, new_component_in_skolem_function, pub_aig_manager); assert(new_skolem_function != NULL); if(new_skolem_function != current_skolem_function) // skolem function is changed { #ifdef DEBUG_SKOLEM cout << "\nSkolem function for " << variable_index << " is changed\n"; #endif // insert the new skolem function insertIntoOneDimensionalMatrix(SkolemFunctions, number_of_vars_to_elim, variable_index, new_skolem_function, true); #ifdef PRINT_SKOLEM_FUNCTIONS string skolem_function_file_name = benchmark_name_without_extension; skolem_function_file_name += "_skolem_function"; writeFormulaToFile(pub_aig_manager, new_skolem_function, skolem_function_file_name, ".v", variable_index, cegar_iteration_number); #endif } else { #ifdef DEBUG_SKOLEM cout << "\nSkolem function for " << variable_index << " is not changed\n"; #endif #ifdef PRINT_SKOLEM_FUNCTIONS string skolem_function_file_name = benchmark_name_without_extension; skolem_function_file_name += "_skolem_function"; writeFormulaToFile(pub_aig_manager, new_skolem_function, skolem_function_file_name, ".v", variable_index, cegar_iteration_number); #endif } // skolem function of variable_index and its CNF are regenerated // Recomputing expressions for C_subst_index_variable_index #ifdef DEBUG_SKOLEM cout << "\nRecomputing expressions for C_subst_index_variable_index\n"; #endif for(int subst_index = bad_index; subst_index <= variable_index-1; subst_index++) { // we need to obtain expression and CNF for C_subst_index_variable_index // Getting the name of C_subst_index_variable_index string connection_string = "C_"; char subst_char[100]; sprintf(subst_char, "%d", subst_index); string subst_string(subst_char); connection_string += subst_string; connection_string += "_"; char variable_char[100]; sprintf(variable_char, "%d", variable_index); string variable_string(variable_char); connection_string += variable_string; #ifdef DEBUG_SKOLEM cout << "\nconnection_string = " << connection_string << endl; #endif // expression for C_subst_index_variable_index is obtained as // skolem_function for subst_index with replacements as per replacement_map from subst_index+1 // and x_variable_index replaced by 1 map local_replacement_map; for(int local_subst_index = subst_index+1; local_subst_index <= variable_index-1; local_subst_index++) { map::iterator replacement_map_it = replacement_map.find(local_subst_index); assert(replacement_map_it != replacement_map.end()); Aig_Obj_t* object_to_replace = replacement_map_it->second; local_replacement_map.insert(make_pair(local_subst_index, object_to_replace)); } Aig_Obj_t* skolem_function_at_subst_index; skolem_function_at_subst_index = searchOneDimensionalMatrix(SkolemFunctions, number_of_vars_to_elim, subst_index); assert(skolem_function_at_subst_index != NULL); Aig_Obj_t* skolem_function_after_replacements; if(local_replacement_map.size() > 0) { skolem_function_after_replacements = replaceVariablesByFormulas(skolem_function_at_subst_index, local_replacement_map); assert(skolem_function_after_replacements != NULL); } else { skolem_function_after_replacements = skolem_function_at_subst_index; } // we need to replace occurences of x_variable_index by true skolem_function_after_replacements = replaceVariableByConstant(skolem_function_after_replacements, variable_index, 1); assert(skolem_function_after_replacements != NULL); Aig_Obj_t* new_connection_dag = skolem_function_after_replacements; Aig_Obj_t* current_connection_dag; map::iterator Connections_it = Connections.find(connection_string); if(Connections_it == Connections.end()) // dag does not exist for connection_string { current_connection_dag = NULL; } else { current_connection_dag = Connections_it->second; assert(current_connection_dag != NULL); } if(current_connection_dag != new_connection_dag) // connection_dag has changed { #ifdef DEBUG_SKOLEM cout << "\nConnection dag for " << connection_string << " is changed\n"; #endif // insert it first Connections[connection_string] = new_connection_dag; #ifdef PRINT_SKOLEM_FUNCTIONS string connection_file_name = benchmark_name_without_extension; connection_file_name += "_connection"; writeFormulaToFile(pub_aig_manager, new_connection_dag, connection_file_name, ".v", subst_index, variable_index); #endif } else { #ifdef DEBUG_SKOLEM cout << "\nConnection dag for " << connection_string << " is not changed\n"; #endif } }// for subst_index from bad_index to variable_index-1 ends here // We have changed the skolem function for variable_index // There may be connections sensitive to this. They should be recreated. // Finding the connections sensitive to skolem function for variable_index #ifdef DEBUG_SKOLEM cout << "\nRecomputing the connections sensitive to skolem function for " << variable_index << endl; #endif map >::iterator end_locations_it = end_locations_of_connections_sensitive_to_skolem_function.find(variable_index); if(end_locations_it != end_locations_of_connections_sensitive_to_skolem_function.end()) { set end_locations = end_locations_it->second; for(set::iterator end_locations_it = end_locations.begin(); end_locations_it != end_locations.end(); end_locations_it++) { int end_index = *end_locations_it; // we need to obtain expression and CNF for C_variable_index_end_index // Getting the name of C_variable_index_end_index string connection_string = "C_"; char variable_char[100]; sprintf(variable_char, "%d", variable_index); string variable_string(variable_char); connection_string += variable_string; connection_string += "_"; char end_char[100]; sprintf(end_char, "%d", end_index); string end_string(end_char); connection_string += end_string; #ifdef DEBUG_SKOLEM cout << "\nend_index = " << end_index<< "\tconnection_string = " << connection_string << endl; #endif // expression for C_variable_index_end_index is obtained as // skolem_function for variable_index with replacements variable_index+1 with C_(variable_index+1)_end_index // .......... // end_index-1 with C_(end_index-1)_end_index // and end_index replaced by 1 #ifdef DEBUG_SKOLEM cout << "\ncreating local_replacement_map\n"; #endif map local_replacement_map; for(int local_subst_index = variable_index+1; local_subst_index <= end_index-1; local_subst_index++) { // Getting the object for C_local_subst_index_end_index string local_connection_string = "C_"; char local_subst_char[100]; sprintf(local_subst_char, "%d", local_subst_index); string local_subst_string(local_subst_char); local_connection_string += local_subst_string; local_connection_string += "_"; local_connection_string += end_string; map::iterator connection_map_it = connection_string_to_connection_object_map.find(local_connection_string); assert(connection_map_it != connection_string_to_connection_object_map.end()); Aig_Obj_t* object_to_replace = connection_map_it->second; local_replacement_map.insert(make_pair(local_subst_index, object_to_replace)); #ifdef DEBUG_SKOLEM cout << "\nlocal_connection_string = " << local_connection_string << endl; #endif } Aig_Obj_t* skolem_function_at_variable_index; skolem_function_at_variable_index = searchOneDimensionalMatrix(SkolemFunctions, number_of_vars_to_elim, variable_index); assert(skolem_function_at_variable_index != NULL); Aig_Obj_t* skolem_function_after_replacements; if(local_replacement_map.size() > 0) { skolem_function_after_replacements = replaceVariablesByFormulas(skolem_function_at_variable_index, local_replacement_map); assert(skolem_function_after_replacements != NULL); } else { skolem_function_after_replacements = skolem_function_at_variable_index; } // we need to replace occurences of x_end_index by true skolem_function_after_replacements = replaceVariableByConstant(skolem_function_after_replacements, end_index, 1); assert(skolem_function_after_replacements != NULL); Aig_Obj_t* new_connection_dag = skolem_function_after_replacements; Aig_Obj_t* current_connection_dag; map::iterator Connections_it = Connections.find(connection_string); if(Connections_it == Connections.end()) // dag does not exist for connection_string { current_connection_dag = NULL; } else { current_connection_dag = Connections_it->second; assert(current_connection_dag != NULL); } if(current_connection_dag != new_connection_dag) // connection_dag has changed { #ifdef DEBUG_SKOLEM cout << "\nConnection dag for " << connection_string << " is changed\n"; #endif // insert it first Connections[connection_string] = new_connection_dag; #ifdef PRINT_SKOLEM_FUNCTIONS string connection_file_name = benchmark_name_without_extension; connection_file_name += "_connection"; writeFormulaToFile(pub_aig_manager, new_connection_dag, connection_file_name, ".v", variable_index, end_index); #endif } else { #ifdef DEBUG_SKOLEM cout << "\nConnection dag for " << connection_string << " is not changed\n"; #endif } }// for each end location } else { #ifdef DEBUG_SKOLEM cout << "\nNo end locations for " << variable_index << "\n"; #endif } } // take each hint ends here // Create the dag for EXACTNESSCHECK // F(X',Y) \wedge (B1\vee ... \vee B_n \vee B_{n+1}) \wedge // (B_1 = bad_set_1) \wedge ... \wedge (B_n = bad_set_n) \wedge (B_{n+1} = bad_set_{n+1}) \wedge // (x_1 = psi_1) \wedge ... \wedge (x_n = psi_n) \wedge // conjunction of (C_i_j = dags for C_i_j) for all the connections C_i_j // dag for F(X',Y) is already created in renamed_conjunction_of_factors // dag for (B1\vee ... \vee B_n \vee B_{n+1}) is already created in disjunction_of_bad_symbols // dag for (B_1 = bad_set_1) \wedge ... \wedge (B_n = bad_set_n) \wedge (B_{n+1} = bad_set_{n+1}) is already created in B_equivalence_part // Let's first create dag for (x_1 = psi_1) \wedge ... \wedge (x_n = psi_n) Aig_Obj_t* S_equivalence_part; set S_equivalence_objects; for(int var_to_elim_index = 1; var_to_elim_index <= number_of_vars_to_elim; var_to_elim_index++) { // obtaining dag for x_i string var_to_elim = searchVarIndexToVarNameMap(var_index_to_var_name_map, var_to_elim_index); map::iterator Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it = Ci_to_eliminate_name_to_Ci_to_eliminate_object_map.find(var_to_elim); assert(Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it != Ci_to_eliminate_name_to_Ci_to_eliminate_object_map.end()); Aig_Obj_t* var_to_elim_obj = Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it->second; // obtaining \psi_i Aig_Obj_t* skolem_function; skolem_function = searchOneDimensionalMatrix(SkolemFunctions, number_of_vars_to_elim, var_to_elim_index); assert(skolem_function != NULL); Aig_Obj_t* S_equivalence_i = createEquivalence(skolem_function, var_to_elim_obj, pub_aig_manager); S_equivalence_objects.insert(S_equivalence_i); } assert(!S_equivalence_objects.empty()); S_equivalence_part = createAnd(S_equivalence_objects, pub_aig_manager); assert(S_equivalence_part != NULL); // Let's create dag for conjunction of (C_i_j = dags for C_i_j) for all the connections C_i_j Aig_Obj_t* S_connection_part; set S_connection_objects; for(map::iterator connection_string_to_connection_object_map_it = connection_string_to_connection_object_map.begin(); connection_string_to_connection_object_map_it != connection_string_to_connection_object_map.end(); connection_string_to_connection_object_map_it++) { string connection_string = connection_string_to_connection_object_map_it->first; Aig_Obj_t* connection_obj = connection_string_to_connection_object_map_it->second; assert(connection_obj != NULL); map::iterator Connections_it = Connections.find(connection_string); assert(Connections_it != Connections.end()); Aig_Obj_t* connection_dag = Connections_it->second; assert(connection_dag != NULL); Aig_Obj_t* S_connection_i = createEquivalence(connection_dag, connection_obj, pub_aig_manager); S_connection_objects.insert(S_connection_i); } assert(!S_connection_objects.empty()); S_connection_part = createAnd(S_connection_objects, pub_aig_manager); assert(S_connection_part != NULL); #ifdef DEBUG_SKOLEM string S_connection_part_file_name = benchmark_name_without_extension; S_connection_part_file_name += "_S_connection_part"; string S_equivalence_part_file_name = benchmark_name_without_extension; S_equivalence_part_file_name += "_S_equivalence_part"; cout << "\nS_connection_part computed\n"; cout << "\nS_equivalence_part computed\n"; writeFormulaToFile(pub_aig_manager, S_connection_part, S_connection_part_file_name, ".v", 0, cegar_iteration_number); writeFormulaToFile(pub_aig_manager, S_equivalence_part, S_equivalence_part_file_name, ".v", 0, cegar_iteration_number); #endif set exactnesscheck_objects; assert(renamed_conjunction_of_factors != NULL); exactnesscheck_objects.insert(renamed_conjunction_of_factors); assert(disjunction_of_bad_symbols != NULL); exactnesscheck_objects.insert(disjunction_of_bad_symbols); assert(B_equivalence_part != NULL); exactnesscheck_objects.insert(B_equivalence_part); exactnesscheck_objects.insert(S_equivalence_part); exactnesscheck_objects.insert(S_connection_part); exactnesscheck = createAnd(exactnesscheck_objects, pub_aig_manager); assert(exactnesscheck != NULL); } // if(cegar_iteration_number > 0) ends here // Give exactnesscheck to SAT-Solver #ifdef DEBUG_SKOLEM cout << endl << "Giving exactnesscheck to SAT-Solver\n"; #endif #ifdef DETAILED_RECORD_KEEP unsigned long long int solver_ms; struct timeval solver_start_ms, solver_finish_ms; gettimeofday (&solver_start_ms, NULL); #endif // Give to SAT-Solver and get unsat / sat with model unsigned long long int cnf_time; int formula_size; unsigned long long int simplification_time; bool result_of_exactnesscheck = isSat(pub_aig_manager, exactnesscheck, Model_of_ExactnessCheck, cnf_time, formula_size, simplification_time); #ifdef DETAILED_RECORD_KEEP gettimeofday (&solver_finish_ms, NULL); solver_ms = solver_finish_ms.tv_sec * 1000 + solver_finish_ms.tv_usec / 1000; solver_ms -= solver_start_ms.tv_sec * 1000 + solver_start_ms.tv_usec / 1000; cout << "\nsolver finished in " << solver_ms << " milliseconds\n"; total_time_in_smt_solver = total_time_in_smt_solver + solver_ms; #endif #ifdef RECORD_KEEP fprintf(record_fp, "\n\n%d\t%llu(%llu,%llu)(%d)\t", cegar_iteration_number, solver_ms, cnf_time, simplification_time, formula_size); fclose(record_fp); #endif #ifdef DEBUG_SKOLEM displayModelFromSATSolver(Model_of_ExactnessCheck); cout << endl << "result_of_exactnesscheck = " << result_of_exactnesscheck << endl; #endif if(!result_of_exactnesscheck) // ExactnessCheck unsat i.e. skolem functions exact { return true; } else // skolem functions inexact { return false; } } void AIGBasedSkolem::refineSkolemFunctions_using_ABC(map &Model_of_ExactnessCheck, map &Refinement_Hint_To_Eliminate_This_CEX) { // For easy of processing let's create vector BadValues; // BadValues[i-1] gives value of Bad_i vector XValues; // XValues[i-1] gives value of x_i vector XNewValues; // XNewValues[i-1] gives value of x'_i map YValues; // YValues[yvariable] gives value of yvariable set NonYVariables_In_Model; for(int var_to_elim_index = 1; var_to_elim_index <= number_of_vars_to_elim; var_to_elim_index++) { string var_to_elim = searchVarIndexToVarNameMap(var_index_to_var_name_map, var_to_elim_index); string var_to_elim_renamed = var_to_elim; var_to_elim_renamed += "_new"; string B_i = "B_"; char bad_count_char[100]; sprintf(bad_count_char, "%d", var_to_elim_index); string bad_count_string(bad_count_char); B_i += bad_count_string; NonYVariables_In_Model.insert(var_to_elim); NonYVariables_In_Model.insert(var_to_elim_renamed); NonYVariables_In_Model.insert(B_i); map::iterator Model_of_ExactnessCheck_it; Model_of_ExactnessCheck_it = Model_of_ExactnessCheck.find(var_to_elim); assert(Model_of_ExactnessCheck_it != Model_of_ExactnessCheck.end()); XValues.push_back(Model_of_ExactnessCheck_it->second); Model_of_ExactnessCheck_it = Model_of_ExactnessCheck.find(var_to_elim_renamed); assert(Model_of_ExactnessCheck_it != Model_of_ExactnessCheck.end()); XNewValues.push_back(Model_of_ExactnessCheck_it->second); Model_of_ExactnessCheck_it = Model_of_ExactnessCheck.find(B_i); assert(Model_of_ExactnessCheck_it != Model_of_ExactnessCheck.end()); BadValues.push_back(Model_of_ExactnessCheck_it->second); } string B_i = "B_"; char bad_count_char[100]; sprintf(bad_count_char, "%d", number_of_vars_to_elim+1); string bad_count_string(bad_count_char); B_i += bad_count_string; NonYVariables_In_Model.insert(B_i); map::iterator Model_of_ExactnessCheck_it; Model_of_ExactnessCheck_it = Model_of_ExactnessCheck.find(B_i); assert(Model_of_ExactnessCheck_it != Model_of_ExactnessCheck.end()); BadValues.push_back(Model_of_ExactnessCheck_it->second); for(map::iterator model_it = Model_of_ExactnessCheck.begin(); model_it != Model_of_ExactnessCheck.end(); model_it++) { string variable_name = model_it->first; int variable_value = model_it->second; if(NonYVariables_In_Model.find(variable_name) == NonYVariables_In_Model.end() && connection_string_to_connection_object_map.find(variable_name) == connection_string_to_connection_object_map.end()) // variable is a Y variable { YValues.insert(make_pair(variable_name, variable_value)); } } #ifdef DEBUG_SKOLEM for(int i = 0; i < BadValues.size(); i++) { cout << endl << "BadValues[" << i << "] = " << BadValues[i]; } for(int i = 0; i < XValues.size(); i++) { cout << endl << "XValues[" << i << "] = " << XValues[i]; } for(int i = 0; i < XNewValues.size(); i++) { cout << endl << "XNewValues[" << i << "] = " << XNewValues[i]; } for(map::iterator yvalues_it = YValues.begin(); yvalues_it != YValues.end(); yvalues_it++) { cout << endl << "YValues->first = " << yvalues_it->first << "\t" << "YValues->second = " << yvalues_it->second; } #endif // Note that locations in the ...Values vectors // are 0...number_of_vars_to_elim-1 vector BadLocations; for(int location = 0; location < BadValues.size(); location++) { if(BadValues[location] == 1) { BadLocations.push_back(location); } } int minimum_bad_location = BadLocations[0]; int maximum_bad_location = BadLocations[BadLocations.size()-1]; if(maximum_bad_location == minimum_bad_location && maximum_bad_location == number_of_vars_to_elim+1) { // Bad at number_of_vars_to_elim+1 is the only Bad; how to refine this? cout << "\nError in AIGBasedSkolem::refineSkolemFunctions_using_ABC!! Bad at " << number_of_vars_to_elim+1 << " is the only Bad; how to refine this?\n"; assert(false); } #ifdef DEBUG_SKOLEM for(int i = 0; i < BadLocations.size(); i++) { cout << endl << "BadLocations[" << i << "] = " << BadLocations[i]; } cout << "\nminimum_bad_location = " << minimum_bad_location; #endif for(int var_to_elim_index = number_of_vars_to_elim; var_to_elim_index >= 1; var_to_elim_index--) { #ifdef DEBUG_SKOLEM cout << "\nvar_to_elim_index = " << var_to_elim_index; #endif int location = var_to_elim_index-1; if(location <= minimum_bad_location) // we have reached locations below min. bad; let's stop { #ifdef DEBUG_SKOLEM cout << "\nwe have reached locations below min. bad; let's stop"; #endif break; } else if(XValues[location] != XNewValues[location]) // mismatch found { #ifdef DEBUG_SKOLEM cout << "\nmismatch found"; #endif assert(XValues[location] == 1 && XNewValues[location] == 0); // over-approximation bool mismatch_genuine = checkIfMismatchIsGenuine_using_ABC(location, XNewValues, YValues); if(!mismatch_genuine) // For XNewValues s.t. XValuesNew[location] == 0 // and XNewValues[i] = XValues[i] for i from number_of_vars_to_elim-1 to location+1, mismatch avoidable // But XNewValues[j] for j from location to 0 are changed { #ifdef DEBUG_SKOLEM cout << "\nmismatch is not genuine..Changed XNewValues are..."; for(int i = 0; i < XNewValues.size(); i++) { cout << endl << "XNewValues[" << i << "] = " << XNewValues[i]; } #endif continue; } else { #ifdef DEBUG_SKOLEM cout << "\nmismatch is genuine"; #endif vector bad_locations_to_refine_mismatch_at_location; findBadLocationsToRefineMismatchAtLocation(location, BadLocations, bad_locations_to_refine_mismatch_at_location); vector bads_to_refine_mismatch_at_location; // actual bads are locations + 1 for(int bad_location_it = 0; bad_location_it < bad_locations_to_refine_mismatch_at_location.size(); bad_location_it++) { bads_to_refine_mismatch_at_location.push_back(bad_locations_to_refine_mismatch_at_location[bad_location_it] + 1); } #ifdef DEBUG_SKOLEM cout << "\nbads_to_refine_mismatch_at_location"; for(int i = 0; i < bads_to_refine_mismatch_at_location.size(); i++) { cout << endl << "bads_to_refine_mismatch_at_location[" << i << "] = " << bads_to_refine_mismatch_at_location[i]; } #endif #ifdef DEBUG_SKOLEM cout << "\nLet's insert " << var_to_elim_index << " --> " << bads_to_refine_mismatch_at_location[0] << " in refinement hint\n"; #endif assert(bads_to_refine_mismatch_at_location.size() > 0); // there must be at least one bad location // For the time being, let us pull only the top-most bad Refinement_Hint_To_Eliminate_This_CEX.insert(make_pair(var_to_elim_index, bads_to_refine_mismatch_at_location[0])); }// refinement hint addition ends here } // mismatch found ends here }// loop ends here } bool AIGBasedSkolem::checkIfMismatchIsGenuine_using_ABC(int mismatch_location, vector &XNewValues, map &YValues) { bool result_of_sufficiencycheck; map Model_of_Sufficiencycheck; if(use_incremental_sat_solving && apply_incremental_solving_for_mismatch_check) { vector positive_assumptions; vector negative_assumptions; // assert that all y variables keep their values in the existing model for(map::iterator yvalues_it = YValues.begin(); yvalues_it != YValues.end(); yvalues_it++) { string variable_name = yvalues_it->first; int variable_value = yvalues_it->second; Aig_Obj_t* variable_object; map::iterator Ci_name_to_Ci_object_map_it = Ci_name_to_Ci_object_map.find(variable_name); assert(Ci_name_to_Ci_object_map_it != Ci_name_to_Ci_object_map.end()); variable_object = Ci_name_to_Ci_object_map_it->second; if(variable_value == 1) // variable_value is true { positive_assumptions.push_back(variable_object); } else // variable_value is false { negative_assumptions.push_back(variable_object); } } // assert that all x_new variables upto mismatch_location keep their values in the existing model for(int var_to_elim_index = number_of_vars_to_elim; var_to_elim_index >= 1; var_to_elim_index--) { int location = var_to_elim_index-1; if(location <= mismatch_location) { break; } else { Aig_Obj_t* variable_object; map::iterator Ci_to_eliminate_renamed_to_Ci_to_eliminate_renamed_object_map_it = Ci_to_eliminate_renamed_to_Ci_to_eliminate_renamed_object_map.find(var_to_elim_index); assert(Ci_to_eliminate_renamed_to_Ci_to_eliminate_renamed_object_map_it != Ci_to_eliminate_renamed_to_Ci_to_eliminate_renamed_object_map.end()); variable_object = Ci_to_eliminate_renamed_to_Ci_to_eliminate_renamed_object_map_it->second; if(XNewValues[location] == 1) // variable_value is true { positive_assumptions.push_back(variable_object); } else { negative_assumptions.push_back(variable_object); } } } // assert that x_new variable at mismatch_location is true Aig_Obj_t* variable_object; map::iterator Ci_to_eliminate_renamed_to_Ci_to_eliminate_renamed_object_map_it = Ci_to_eliminate_renamed_to_Ci_to_eliminate_renamed_object_map.find(mismatch_location+1); assert(Ci_to_eliminate_renamed_to_Ci_to_eliminate_renamed_object_map_it != Ci_to_eliminate_renamed_to_Ci_to_eliminate_renamed_object_map.end()); variable_object = Ci_to_eliminate_renamed_to_Ci_to_eliminate_renamed_object_map_it->second; positive_assumptions.push_back(variable_object); Aig_Obj_t* increment; if(incremental_solver_for_mismatch_check_initialized) { increment = createTrue(pub_aig_manager); } else { increment = renamed_conjunction_of_factors; } assert(increment != NULL); incremental_solver_for_mismatch_check_initialized = true; // Let's call the SAT-Solver to see if sufficiencycheck is still satisfiable #ifdef DEBUG_SKOLEM cout << endl << "Giving sufficiencycheck to SAT-Solver\n"; #endif #ifdef DETAILED_RECORD_KEEP unsigned long long int solver_ms; struct timeval solver_start_ms, solver_finish_ms; gettimeofday (&solver_start_ms, NULL); #endif // Give to SAT-Solver and get unsat / sat with model unsigned long long int cnf_time; int formula_size; unsigned long long int simplification_time; result_of_sufficiencycheck = isExactnessCheckSatisfiable(pub_aig_manager, increment, Model_of_Sufficiencycheck, cnf_time, formula_size, simplification_time, positive_assumptions, negative_assumptions, pSat_for_mismatch_check, IncrementalLabelTableForMismatchCheck, IncrementalLabelCountForMismatchCheck, Ci_name_to_Ci_label_mapForMismatchCheck, Ci_label_to_Ci_name_mapForMismatchCheck); #ifdef DETAILED_RECORD_KEEP gettimeofday (&solver_finish_ms, NULL); solver_ms = solver_finish_ms.tv_sec * 1000 + solver_finish_ms.tv_usec / 1000; solver_ms -= solver_start_ms.tv_sec * 1000 + solver_start_ms.tv_usec / 1000; cout << "\nsolver finished in " << solver_ms << " milliseconds\n"; total_time_in_smt_solver = total_time_in_smt_solver + solver_ms; total_time_in_x_new_recompution_in_cegar = total_time_in_x_new_recompution_in_cegar + solver_ms; number_of_x_new_recompution_in_cegar++; #endif #ifdef RECORD_KEEP string record_file; record_file = logfile_prefix; record_file += "skolem_function_generation_details.txt"; FILE* record_fp = fopen(record_file.c_str(), "a+"); assert(record_fp != NULL); fprintf(record_fp, "%llu(%llu,%llu)(%d),", solver_ms, cnf_time, simplification_time, formula_size); fclose(record_fp); #endif } else { set assignment_objects; // assert that all y variables keep their values in the existing model for(map::iterator yvalues_it = YValues.begin(); yvalues_it != YValues.end(); yvalues_it++) { string variable_name = yvalues_it->first; int variable_value = yvalues_it->second; Aig_Obj_t* variable_object; map::iterator Ci_name_to_Ci_object_map_it = Ci_name_to_Ci_object_map.find(variable_name); if(Ci_name_to_Ci_object_map_it == Ci_name_to_Ci_object_map.end()) { cout << "\nNo entry for " << variable_name << " in Ci_name_to_Ci_object_map\n"; assert(false); } variable_object = Ci_name_to_Ci_object_map_it->second; if(variable_value == 0) // variable_value is false { // negate variable_object variable_object = createNot(variable_object, pub_aig_manager); } assignment_objects.insert(variable_object); } // assert that all x_new variables upto mismatch_location keep their values in the existing model for(int var_to_elim_index = number_of_vars_to_elim; var_to_elim_index >= 1; var_to_elim_index--) { int location = var_to_elim_index-1; if(location <= mismatch_location) { break; } else { Aig_Obj_t* variable_object; map::iterator Ci_to_eliminate_renamed_to_Ci_to_eliminate_renamed_object_map_it = Ci_to_eliminate_renamed_to_Ci_to_eliminate_renamed_object_map.find(var_to_elim_index); assert(Ci_to_eliminate_renamed_to_Ci_to_eliminate_renamed_object_map_it != Ci_to_eliminate_renamed_to_Ci_to_eliminate_renamed_object_map.end()); variable_object = Ci_to_eliminate_renamed_to_Ci_to_eliminate_renamed_object_map_it->second; if(XNewValues[location] == 0) // variable_value is false { // negate variable_object variable_object = createNot(variable_object, pub_aig_manager); } assignment_objects.insert(variable_object); } } // assert that x_new variable at mismatch_location is true Aig_Obj_t* variable_object; map::iterator Ci_to_eliminate_renamed_to_Ci_to_eliminate_renamed_object_map_it = Ci_to_eliminate_renamed_to_Ci_to_eliminate_renamed_object_map.find(mismatch_location+1); assert(Ci_to_eliminate_renamed_to_Ci_to_eliminate_renamed_object_map_it != Ci_to_eliminate_renamed_to_Ci_to_eliminate_renamed_object_map.end()); variable_object = Ci_to_eliminate_renamed_to_Ci_to_eliminate_renamed_object_map_it->second; assignment_objects.insert(variable_object); assert(!assignment_objects.empty()); Aig_Obj_t* assignment = createAnd(assignment_objects, pub_aig_manager); assert(assignment != NULL); #ifdef DEBUG_SKOLEM string assignment_file_name = benchmark_name_without_extension; assignment_file_name += "_assignment"; cout << "\nassignment computed\n"; writeFormulaToFile(pub_aig_manager, assignment, assignment_file_name, ".v", 0, cegar_iteration_number); #endif Aig_Obj_t* sufficiencycheck = createAnd(renamed_conjunction_of_factors, assignment, pub_aig_manager); assert(sufficiencycheck != NULL); // Let's call the SAT-Solver to see if sufficiencycheck is still satisfiable #ifdef DEBUG_SKOLEM cout << endl << "Giving sufficiencycheck to SAT-Solver\n"; #endif #ifdef DETAILED_RECORD_KEEP unsigned long long int solver_ms; struct timeval solver_start_ms, solver_finish_ms; gettimeofday (&solver_start_ms, NULL); #endif // Give to SAT-Solver and get unsat / sat with model unsigned long long int cnf_time; int formula_size; unsigned long long int simplification_time; result_of_sufficiencycheck = isSat(pub_aig_manager, sufficiencycheck, Model_of_Sufficiencycheck, cnf_time, formula_size, simplification_time); #ifdef DETAILED_RECORD_KEEP gettimeofday (&solver_finish_ms, NULL); solver_ms = solver_finish_ms.tv_sec * 1000 + solver_finish_ms.tv_usec / 1000; solver_ms -= solver_start_ms.tv_sec * 1000 + solver_start_ms.tv_usec / 1000; cout << "\nsolver finished in " << solver_ms << " milliseconds\n"; total_time_in_smt_solver = total_time_in_smt_solver + solver_ms; total_time_in_x_new_recompution_in_cegar = total_time_in_x_new_recompution_in_cegar + solver_ms; number_of_x_new_recompution_in_cegar++; #endif #ifdef RECORD_KEEP string record_file; record_file = logfile_prefix; record_file += "skolem_function_generation_details.txt"; FILE* record_fp = fopen(record_file.c_str(), "a+"); assert(record_fp != NULL); fprintf(record_fp, "%llu(%llu,%llu)(%d),", solver_ms, cnf_time, simplification_time, formula_size); fclose(record_fp); #endif }// else of if(use_incremental_sat_solving && apply_incremental_solving_for_mismatch_check) ends here #ifdef DEBUG_SKOLEM displayModelFromSATSolver(Model_of_Sufficiencycheck); cout << endl << "result_of_sufficiencycheck = " << result_of_sufficiencycheck << endl; #endif if(!result_of_sufficiencycheck) // sufficiencycheck is unsat // mismatch unavoidable/genuine { return true; } else // mismatch avoidable { // Get the changed XNewValues for(int var_to_elim_index = 1; var_to_elim_index <= number_of_vars_to_elim; var_to_elim_index++) { int location = var_to_elim_index-1; string var_to_elim = searchVarIndexToVarNameMap(var_index_to_var_name_map, var_to_elim_index); string var_to_elim_renamed = var_to_elim; var_to_elim_renamed += "_new"; map::iterator Model_of_Sufficiencycheck_it; Model_of_Sufficiencycheck_it = Model_of_Sufficiencycheck.find(var_to_elim_renamed); assert(Model_of_Sufficiencycheck_it != Model_of_Sufficiencycheck.end()); int changed_xnew_value = Model_of_Sufficiencycheck_it->second; if(location < mismatch_location) { XNewValues[location] = changed_xnew_value; } else if(location > mismatch_location) { assert(XNewValues[location] == changed_xnew_value); } else //location == mismatch_location { assert(changed_xnew_value == 1); XNewValues[location] = 1; } } return false; } // avoidable mismatch found ends here }// function ends here Aig_Obj_t* AIGBasedSkolem::obtainFormulaWithoutConnections(Aig_Obj_t* formula) { assert(formula != NULL); set support_formula; computeSupport(formula, support_formula, pub_aig_manager); Aig_Obj_t* formula_without_connections = formula; for(set::iterator support_it = support_formula.begin(); support_it != support_formula.end(); support_it++) { string variable = *support_it; #ifdef DEBUG_SKOLEM cout << "\nvariable in support = " << variable << endl; #endif map::iterator Connections_it = Connections.find(variable); if(Connections_it != Connections.end()) // variable is a connection variable { #ifdef DEBUG_SKOLEM cout << endl << variable << " is a connection variable" << endl; #endif Aig_Obj_t* connection_dag = Connections_it->second; assert(connection_dag != NULL); formula_without_connections = ReplaceLeafByExpression(formula_without_connections, variable, connection_dag, pub_aig_manager); assert(formula_without_connections != NULL); } } return formula_without_connections; } void AIGBasedSkolem::refineSkolemFunctions_using_ABC_EvaluationBasedStrategy(map &Model_of_ExactnessCheck, map &Refinement_Hint_To_Eliminate_This_CEX) { // For easy of processing let's create vector BadValues; // BadValues[i-1] gives value of Bad_i vector XValues; // XValues[i-1] gives value of x_i vector XNewValues; // XNewValues[i-1] gives value of x'_i map YValues; // YValues[yvariable] gives value of yvariable set NonYVariables_In_Model; map MismatchType; for(int var_to_elim_index = 1; var_to_elim_index <= number_of_vars_to_elim; var_to_elim_index++) { string var_to_elim = searchVarIndexToVarNameMap(var_index_to_var_name_map, var_to_elim_index); string var_to_elim_renamed = var_to_elim; var_to_elim_renamed += "_new"; string B_i = "B_"; char bad_count_char[100]; sprintf(bad_count_char, "%d", var_to_elim_index); string bad_count_string(bad_count_char); B_i += bad_count_string; NonYVariables_In_Model.insert(var_to_elim); NonYVariables_In_Model.insert(var_to_elim_renamed); NonYVariables_In_Model.insert(B_i); map::iterator Model_of_ExactnessCheck_it; Model_of_ExactnessCheck_it = Model_of_ExactnessCheck.find(var_to_elim); assert(Model_of_ExactnessCheck_it != Model_of_ExactnessCheck.end()); XValues.push_back(Model_of_ExactnessCheck_it->second); Model_of_ExactnessCheck_it = Model_of_ExactnessCheck.find(var_to_elim_renamed); assert(Model_of_ExactnessCheck_it != Model_of_ExactnessCheck.end()); XNewValues.push_back(Model_of_ExactnessCheck_it->second); Model_of_ExactnessCheck_it = Model_of_ExactnessCheck.find(B_i); assert(Model_of_ExactnessCheck_it != Model_of_ExactnessCheck.end()); BadValues.push_back(Model_of_ExactnessCheck_it->second); } string B_i = "B_"; char bad_count_char[100]; sprintf(bad_count_char, "%d", number_of_vars_to_elim+1); string bad_count_string(bad_count_char); B_i += bad_count_string; NonYVariables_In_Model.insert(B_i); map::iterator Model_of_ExactnessCheck_it; Model_of_ExactnessCheck_it = Model_of_ExactnessCheck.find(B_i); assert(Model_of_ExactnessCheck_it != Model_of_ExactnessCheck.end()); BadValues.push_back(Model_of_ExactnessCheck_it->second); for(map::iterator model_it = Model_of_ExactnessCheck.begin(); model_it != Model_of_ExactnessCheck.end(); model_it++) { string variable_name = model_it->first; int variable_value = model_it->second; if(NonYVariables_In_Model.find(variable_name) == NonYVariables_In_Model.end() && connection_string_to_connection_object_map.find(variable_name) == connection_string_to_connection_object_map.end()) // variable is a Y variable { YValues.insert(make_pair(variable_name, variable_value)); } } #ifdef DEBUG_CEGAR for(int i = 0; i < BadValues.size(); i++) { cout << endl << "BadValues[" << i << "] = " << BadValues[i]; } for(int i = 0; i < XValues.size(); i++) { cout << endl << "XValues[" << i << "] = " << XValues[i]; } for(int i = 0; i < XNewValues.size(); i++) { cout << endl << "XNewValues[" << i << "] = " << XNewValues[i]; } //for(map::iterator yvalues_it = YValues.begin(); yvalues_it != YValues.end(); yvalues_it++) //{ // cout << endl << "YValues->first = " << yvalues_it->first << "\t" << "YValues->second = " << yvalues_it->second; //} if(false) { for(int i = 0; i < XValues.size(); i++) { if(XValues[i] == 0 && XNewValues[i] == 1) { string var_to_elim_i = searchVarIndexToVarNameMap(var_index_to_var_name_map, i+1); cout << "\nSkolem function for x_" << i+1 << " i.e. " << var_to_elim_i << " no more over-approximation\n"; analyzeReasonBehindUnderApproximation(i+1, XValues, XNewValues, YValues); assert(false); } } } #endif if(false) { for(int i = 0; i < XValues.size(); i++) { if(XValues[i] == 0 && XNewValues[i] == 1) { string var_to_elim_i = searchVarIndexToVarNameMap(var_index_to_var_name_map, i+1); cout << "\nSkolem function for x_" << i+1 << " i.e. " << var_to_elim_i << " no more over-approximation\n"; assert(false); } } } // Note that locations in the ...Values vectors // are 0...number_of_vars_to_elim-1 vector BadLocations; for(int location = 0; location < BadValues.size(); location++) { if(BadValues[location] == 1) { BadLocations.push_back(location); } } int minimum_bad_location = BadLocations[0]; int maximum_bad_location = BadLocations[BadLocations.size()-1]; #ifdef ADDITIONAL_ASSERTION_CHECKS_INSIDE_CEGAR maximum_bad_location_from_counterexample_in_this_iteration = maximum_bad_location; #endif if(maximum_bad_location == minimum_bad_location && maximum_bad_location == number_of_vars_to_elim+1) { // Bad at number_of_vars_to_elim+1 is the only Bad; how to refine this? cout << "\nError in AIGBasedSkolem::refineSkolemFunctions_using_ABC_EvaluationBasedStrategy!! Bad at " << number_of_vars_to_elim+1 << " is the only Bad; how to refine this?\n"; assert(false); } #ifdef DEBUG_CEGAR for(int i = 0; i < BadLocations.size(); i++) { cout << endl << "BadLocations[" << i << "] = " << BadLocations[i]; } cout << "\nminimum_bad_location = " << minimum_bad_location; #endif set GenuineMismatchLocations; for(int var_to_elim_index = number_of_vars_to_elim; var_to_elim_index >= 1; var_to_elim_index--) { #ifdef DEBUG_CEGAR cout << "\nvar_to_elim_index = " << var_to_elim_index; #endif int location = var_to_elim_index-1; bool limit_upto_minimum_bad_location = false; if(limit_upto_minimum_bad_location) // problem is that the bad locations are // getting changed as the loop executes { if(location <= minimum_bad_location) // we have reached locations below min. bad; let's stop { #ifdef DEBUG_CEGAR cout << "\nwe have reached locations below min. bad; let's stop"; #endif break; } } else if(XValues[location] != XNewValues[location]) // mismatch found { #ifdef DEBUG_CEGAR cout << "\nmismatch found"; #endif if(XValues[location] == 0 && XNewValues[location] == 1) // under-approximation { cout << "\nUnder-approximation at " << var_to_elim_index << endl; string mismatch_type = "u"; MismatchType.insert(make_pair(location, mismatch_type)); // This can be due to an over-approximation above #ifdef DEBUG_CEGAR for(int i = 0; i < XValues.size(); i++) { cout << endl << "XValues[" << i << "] = " << XValues[i] << "\tXNewValues[" << i << "] = " << XNewValues[i]; } #endif bool analyze_underapproximation = false; if(analyze_underapproximation) { analyzeReasonBehindUnderApproximation(location+1, XValues, XNewValues, YValues); } // We need to change XValues in the following way: // XValues[location] should be one // XValues[i] s.t. i >=0 && i < location-1 should be reevaluated // starting from location-1 unsigned long long int reevaluation_ms; struct timeval reevaluation_start_ms, reevaluation_finish_ms; gettimeofday (&reevaluation_start_ms, NULL); if(reevaluation_using_solver) { reevaluateXValues_using_Solver(XValues, YValues, location, 1); } else { reevaluateXValues(XValues, YValues, location, 1); } gettimeofday (&reevaluation_finish_ms, NULL); reevaluation_ms = reevaluation_finish_ms.tv_sec * 1000 + reevaluation_finish_ms.tv_usec / 1000; reevaluation_ms -= reevaluation_start_ms.tv_sec * 1000 + reevaluation_start_ms.tv_usec / 1000; total_time_in_reevaluation_in_cegar = total_time_in_reevaluation_in_cegar + reevaluation_ms; number_of_reevaluation_in_cegar++; cout << "\ntotal_time_in_reevaluation_in_cegar = " << total_time_in_reevaluation_in_cegar << endl; #ifdef DEBUG_CEGAR for(int i = 0; i < XValues.size(); i++) { cout << endl << "XValues[" << i << "] = " << XValues[i] << "\tXNewValues[" << i << "] = " << XNewValues[i]; } #endif } else // over-approximation { cout << "\nOver-approximation at " << var_to_elim_index << endl; bool mismatch_genuine = checkIfMismatchIsGenuine_using_ABC(location, XNewValues, YValues); cout << "\ntotal_time_in_x_new_recompution_in_cegar = " << total_time_in_x_new_recompution_in_cegar << endl; if(!mismatch_genuine) // For XNewValues s.t. XValuesNew[location] == 0 // and XNewValues[i] = XValues[i] for i from number_of_vars_to_elim-1 to location+1, mismatch avoidable // But XNewValues[j] for j from location to 0 are changed { cout << "\nOver-approximation at " << var_to_elim_index << " is not genuine\n"; string mismatch_type = "o-n"; MismatchType.insert(make_pair(location, mismatch_type)); #ifdef DEBUG_CEGAR cout << "\nmismatch is not genuine..Changed XNewValues are..."; for(int i = 0; i < XNewValues.size(); i++) { cout << endl << "XNewValues[" << i << "] = " << XNewValues[i]; } #endif continue; } else { cout << "\nOver-approximation at " << var_to_elim_index << " is genuine\n"; string mismatch_type = "o-g"; MismatchType.insert(make_pair(location, mismatch_type)); #ifdef DEBUG_CEGAR cout << "\nmismatch is genuine"; #endif GenuineMismatchLocations.insert(location); // We need to change XValues in the following way: // XValues[location] should be zero // XValues[i] s.t. i >=0 && i < location-1 should be reevaluated // starting from location-1 unsigned long long int reevaluation_ms; struct timeval reevaluation_start_ms, reevaluation_finish_ms; gettimeofday (&reevaluation_start_ms, NULL); if(reevaluation_using_solver) { reevaluateXValues_using_Solver(XValues, YValues, location, 0); } else { reevaluateXValues(XValues, YValues, location, 0); } gettimeofday (&reevaluation_finish_ms, NULL); reevaluation_ms = reevaluation_finish_ms.tv_sec * 1000 + reevaluation_finish_ms.tv_usec / 1000; reevaluation_ms -= reevaluation_start_ms.tv_sec * 1000 + reevaluation_start_ms.tv_usec / 1000; total_time_in_reevaluation_in_cegar = total_time_in_reevaluation_in_cegar + reevaluation_ms; number_of_reevaluation_in_cegar++; cout << "\ntotal_time_in_reevaluation_in_cegar = " << total_time_in_reevaluation_in_cegar << endl; #ifdef DEBUG_CEGAR for(int i = 0; i < XValues.size(); i++) { cout << endl << "XValues[" << i << "] = " << XValues[i]; } #endif }// genuine mismatch found ends here }// over-approximation ends here } // mismatch found ends here }// loop ends here // Ensure that X' == X for(int i = 0; i < XValues.size(); i++) { if(XValues[i] != XNewValues[i]) // mismatch found; Error! { cout << "\nMismatch after loop with minimum_bad_location = " << minimum_bad_location << endl; cout << endl << "XValues[" << i << "] = " << XValues[i] << "\tXNewValues[" << i << "] = " << XNewValues[i] << endl; assert(false); } } #ifdef ADDITIONAL_ASSERTION_CHECKS_INSIDE_CEGAR bool additional_assertion_checks = false; if(additional_assertion_checks) { // None of the bads should be true // Evaluate all bad_j vector BadValuesForDebugging; evaluateBadValues(XValues, YValues, 1, BadValuesForDebugging); // no need of sat-solving as we have all XValues for(int i = 0; i < BadValuesForDebugging.size(); i++) { if(BadValuesForDebugging[i] == 1) // bad found; Error! { cout << endl << "Bad at location " << i << " is true " << endl; assert(false); } } } #endif //#ifdef DEBUG_CEGAR cout << endl << "Finding the refinement hints" << endl; //#endif if(use_generalized_value_based_scheme || use_values_in_refinement_when_multi_point_connections_deteorates) { values_of_variables_from_bad_to_var.clear(); } if(use_explicit_values_in_refinement || use_generalized_value_based_scheme || use_values_in_refinement_when_multi_point_connections_deteorates) { values_of_variables_from_var.clear(); values_of_Y_variables.clear(); values_of_Y_variables = YValues; } #ifdef ADDITIONAL_ASSERTION_CHECKS_INSIDE_CEGAR if(use_multi_point_connections && !use_explicit_values_in_refinement && !use_generalized_value_based_scheme && !use_values_in_refinement_when_multi_point_connections_deteorates) { values_of_variables_from_var.clear(); values_of_Y_variables.clear(); values_of_Y_variables = YValues; } #endif for(set::iterator mismatch_location_it = GenuineMismatchLocations.begin(); mismatch_location_it != GenuineMismatchLocations.end(); mismatch_location_it++) { int genuine_mismatch_location = *mismatch_location_it; //#ifdef DEBUG_CEGAR cout << endl << "genuine_mismatch_location = " << genuine_mismatch_location << endl; //#endif vector ModifiedXValues(XValues.begin(), XValues.end()); ModifiedXValues[genuine_mismatch_location] = 1; // XValues with XValues[genuine_mismatch_location] = 1 #ifdef DEBUG_CEGAR for(int i = 0; i < ModifiedXValues.size(); i++) { cout << endl << "ModifiedXValues[" << i << "] = " << ModifiedXValues[i]; } #endif int var_to_elim_index = genuine_mismatch_location + 1; // Evaluate bad_j s.t. j < var_to_elim_index vector EvaluatedBadValues; #ifdef DEBUG_CEGAR cout << "\nevaluateBadValues started\n"; #endif unsigned long long int reevaluation_ms; struct timeval reevaluation_start_ms, reevaluation_finish_ms; gettimeofday (&reevaluation_start_ms, NULL); if(reevaluation_using_solver) { evaluateBadValues_using_Solver(ModifiedXValues, YValues, var_to_elim_index, EvaluatedBadValues); } else { evaluateBadValues(ModifiedXValues, YValues, var_to_elim_index, EvaluatedBadValues); } gettimeofday (&reevaluation_finish_ms, NULL); reevaluation_ms = reevaluation_finish_ms.tv_sec * 1000 + reevaluation_finish_ms.tv_usec / 1000; reevaluation_ms -= reevaluation_start_ms.tv_sec * 1000 + reevaluation_start_ms.tv_usec / 1000; total_time_in_reevaluation_in_cegar = total_time_in_reevaluation_in_cegar + reevaluation_ms; number_of_reevaluation_in_cegar++; #ifdef DEBUG_CEGAR cout << "\nevaluateBadValues ends\n"; #endif cout << "\ntotal_time_in_reevaluation_in_cegar = " << total_time_in_reevaluation_in_cegar << endl; #ifdef DEBUG_CEGAR for(int i = 0; i < ModifiedXValues.size(); i++) { cout << endl << "ModifiedXValues[" << i << "] = " << ModifiedXValues[i]; } #endif vector bads_to_refine_mismatch_at_genuine_mismatch_location; // actual bads are locations + 1 for(int bad_index = 0; bad_index < EvaluatedBadValues.size(); bad_index++) { if(EvaluatedBadValues[bad_index] == 1) // Bad[bad_index] is true { bads_to_refine_mismatch_at_genuine_mismatch_location.push_back(bad_index + 1); } } #ifdef DEBUG_CEGAR cout << "\nbads_to_refine_mismatch_at_genuine_mismatch_location"; for(int i = 0; i < bads_to_refine_mismatch_at_genuine_mismatch_location.size(); i++) { cout << endl << "bads_to_refine_mismatch_at_genuine_mismatch_location[" << i << "] = " << bads_to_refine_mismatch_at_genuine_mismatch_location[i]; } #endif assert(bads_to_refine_mismatch_at_genuine_mismatch_location.size() > 0); // there must be at least one bad location int bad_to_be_pulled; if(bad_to_be_pulled_in_each_iteration == "bottom") { bad_to_be_pulled = bads_to_refine_mismatch_at_genuine_mismatch_location[bads_to_refine_mismatch_at_genuine_mismatch_location.size()-1]; } else if(bad_to_be_pulled_in_each_iteration == "top") { bad_to_be_pulled = bads_to_refine_mismatch_at_genuine_mismatch_location[0]; } else { assert(false); } #ifdef DEBUG_CEGAR cout << "\nLet's insert " << var_to_elim_index << " --> " << bad_to_be_pulled << " in refinement hint - cegar iteration number = " << cegar_iteration_number << endl; #endif #ifdef ANALYZE_CEGAR string cegar_file = "cegar_details.txt"; FILE* cegar_fp = fopen(cegar_file.c_str(), "a+"); assert(cegar_fp != NULL); fprintf(cegar_fp, "\n\n\ncegar iteration number = %d\n****************************\n", cegar_iteration_number); fprintf(cegar_fp, "\ngenuine_mismatch_location = %d", var_to_elim_index); fprintf(cegar_fp, "\nbads_to_refine_mismatch_at_genuine_mismatch_location"); for(int i = 0; i < bads_to_refine_mismatch_at_genuine_mismatch_location.size(); i++) { fprintf(cegar_fp, "\nbads_to_refine_mismatch_at_genuine_mismatch_location[%d] = %d", i, bads_to_refine_mismatch_at_genuine_mismatch_location[i]); } fprintf(cegar_fp, "\nbad selected = %d", bad_to_be_pulled); fclose(cegar_fp); #endif Refinement_Hint_To_Eliminate_This_CEX.insert(make_pair(var_to_elim_index, bad_to_be_pulled)); if(use_generalized_value_based_scheme || use_values_in_refinement_when_multi_point_connections_deteorates) { map value_map_for_var_to_elim_index; for(int index_in_map = bad_to_be_pulled; index_in_map < var_to_elim_index; index_in_map++) { int value_in_map = ModifiedXValues[index_in_map-1]; value_map_for_var_to_elim_index.insert(make_pair(index_in_map, value_in_map)); } int last_value_in_map = ModifiedXValues[var_to_elim_index-1]; assert(last_value_in_map == 1); value_map_for_var_to_elim_index.insert(make_pair(var_to_elim_index, last_value_in_map)); values_of_variables_from_bad_to_var.insert(make_pair(var_to_elim_index, value_map_for_var_to_elim_index)); } if(use_explicit_values_in_refinement || use_generalized_value_based_scheme || use_values_in_refinement_when_multi_point_connections_deteorates) { map value_map_for_var_to_elim_index; int first_value_in_map = ModifiedXValues[var_to_elim_index-1]; assert(first_value_in_map == 1); for(int index_in_map = var_to_elim_index+1; index_in_map <= number_of_vars_to_elim; index_in_map++) { int value_in_map = ModifiedXValues[index_in_map-1]; value_map_for_var_to_elim_index.insert(make_pair(index_in_map, value_in_map)); } values_of_variables_from_var.insert(make_pair(var_to_elim_index, value_map_for_var_to_elim_index)); } #ifdef ADDITIONAL_ASSERTION_CHECKS_INSIDE_CEGAR if(use_multi_point_connections && !use_explicit_values_in_refinement && !use_generalized_value_based_scheme && !use_values_in_refinement_when_multi_point_connections_deteorates) { map value_map_for_var_to_elim_index; for(int index_in_map = bad_to_be_pulled; index_in_map < var_to_elim_index; index_in_map++) { int value_in_map = ModifiedXValues[index_in_map-1]; value_map_for_var_to_elim_index.insert(make_pair(index_in_map, value_in_map)); } int last_value_in_map = ModifiedXValues[var_to_elim_index-1]; assert(last_value_in_map == 1); value_map_for_var_to_elim_index.insert(make_pair(var_to_elim_index, last_value_in_map)); values_of_variables_from_bad_to_var.insert(make_pair(var_to_elim_index, value_map_for_var_to_elim_index)); value_map_for_var_to_elim_index.clear(); int first_value_in_map = ModifiedXValues[var_to_elim_index-1]; assert(first_value_in_map == 1); for(int index_in_map = var_to_elim_index+1; index_in_map <= number_of_vars_to_elim; index_in_map++) { int value_in_map = ModifiedXValues[index_in_map-1]; value_map_for_var_to_elim_index.insert(make_pair(index_in_map, value_in_map)); } values_of_variables_from_var.insert(make_pair(var_to_elim_index, value_map_for_var_to_elim_index)); } #endif } #ifdef RECORD_KEEP string record_file; record_file = logfile_prefix; record_file += "skolem_function_generation_details.txt"; FILE* record_fp = fopen(record_file.c_str(), "a+"); assert(record_fp != NULL); fprintf(record_fp, "\t"); for(map::iterator MismatchType_it = MismatchType.begin(); MismatchType_it != MismatchType.end(); MismatchType_it++) { fprintf(record_fp, "%d(%s),", MismatchType_it->first, (MismatchType_it->second).c_str()); } fclose(record_fp); #endif #ifdef DEBUG_CEGAR showVariableWiseValueMap(); #endif } void AIGBasedSkolem::reevaluateXValues(vector &XValues, map &YValues, int asserted_location, int asserted_value) { assert(asserted_value == 0 || asserted_value == 1); XValues[asserted_location] = asserted_value; map variable_to_value_map; for(map::iterator yvalues_it = YValues.begin(); yvalues_it != YValues.end(); yvalues_it++) { bool bool_value; if(yvalues_it->second == 1) { bool_value = true; } else { bool_value = false; } variable_to_value_map.insert(make_pair(yvalues_it->first, bool_value)); #ifdef DEBUG_SKOLEM cout << endl << yvalues_it->first << " --> " << bool_value << " inserted into variable_to_value_map\n"; #endif } for(int var_to_elim_index = number_of_vars_to_elim; var_to_elim_index >= 1; var_to_elim_index--) { int var_location = var_to_elim_index-1; if(var_location < asserted_location) { break; } else { string var_to_elim = searchVarIndexToVarNameMap(var_index_to_var_name_map, var_to_elim_index); int value = XValues[var_location]; bool bool_value; if(value == 1) { bool_value = true; } else { bool_value = false; } variable_to_value_map.insert(make_pair(var_to_elim, bool_value)); #ifdef DEBUG_SKOLEM cout << endl << var_to_elim << " --> " << bool_value << " inserted into variable_to_value_map\n"; #endif } } for(int var_location = asserted_location-1; var_location >= 0; var_location--) { // Obtain XValues[var_location] int var_to_elim_index = var_location+1; // obtaining \psi_i Aig_Obj_t* skolem_function; skolem_function = searchOneDimensionalMatrix(SkolemFunctions, number_of_vars_to_elim, var_to_elim_index); assert(skolem_function != NULL); bool bool_value = evaluateFormulaOfCi(skolem_function, variable_to_value_map); int value; if(bool_value) { value = 1; } else { value = 0; } XValues[var_location] = value; string var_to_elim = searchVarIndexToVarNameMap(var_index_to_var_name_map, var_to_elim_index); variable_to_value_map.insert(make_pair(var_to_elim, bool_value)); #ifdef DEBUG_SKOLEM cout << endl << var_to_elim << " --> " << bool_value << " inserted into variable_to_value_map\n"; #endif } } bool AIGBasedSkolem::obtainValueOfCi(string variable, map &variable_to_value_map) { map::iterator variable_to_value_map_it = variable_to_value_map.find(variable); if(variable_to_value_map_it != variable_to_value_map.end()) { #ifdef DEBUG_SKOLEM //cout << endl << "Entry exists for " << variable << " in variable_to_value_map" << endl; #endif return variable_to_value_map_it->second; } else { //#ifdef DEBUG_SKOLEM cout << endl << "Entry does not exist for " << variable << " in variable_to_value_map" << endl; //#endif // get the formula for variable Aig_Obj_t* formula; map::iterator Connections_it = Connections.find(variable); if(Connections_it != Connections.end()) // variable is a connection variable { //#ifdef DEBUG_SKOLEM cout << endl << variable << " is a connection variable" << endl; //#endif formula = Connections_it->second; } else { int var_to_elim_index = searchVarNameToVarIndexMap(var_name_to_var_index_map, variable); if(var_to_elim_index == -1) { cout << "\nError in function AIGBasedSkolem::obtainValueOfCi! variable other than connection variable and variable to be eliminated encountered\n"; assert(false); } else { //#ifdef DEBUG_SKOLEM cout << endl << variable << " is a variable to be eliminated" << endl; //#endif formula = searchOneDimensionalMatrix(SkolemFunctions, number_of_vars_to_elim, var_to_elim_index); } } assert(formula != NULL); //#ifdef DEBUG_SKOLEM cout << endl << "evaluating formula for " << variable << endl; //#endif bool value = evaluateFormulaOfCi(formula, variable_to_value_map); //#ifdef DEBUG_SKOLEM cout << endl << "formula for " << variable << " evaluated\n"; //#endif variable_to_value_map.insert(make_pair(variable, value)); return value; } } bool AIGBasedSkolem::evaluateFormulaOfCi(Aig_Obj_t* formula, map &variable_to_value_map) { EvaluationTable.clear(); bool value = evaluateFormulaOfCi_DFS(formula, variable_to_value_map); return value; } bool AIGBasedSkolem::evaluateFormulaOfCi_DFS(Aig_Obj_t* formula, map &variable_to_value_map) { assert(formula != NULL); string key = toString(formula); t_HashTable::iterator EvaluationTable_it = EvaluationTable.find(key); if (EvaluationTable_it != EvaluationTable.end()) // traversed already { return EvaluationTable_it.getValue();; } else { bool node_value; if(Aig_IsComplement(formula)) // ~ encountered { Aig_Obj_t* child_1 = Aig_Regular(formula); assert(child_1 != NULL); bool child_1_value = evaluateFormulaOfCi_DFS(child_1, variable_to_value_map); node_value = !child_1_value; } // if(Aig_IsComplement(formula)) ends here else if(formula->Type == AIG_OBJ_CI) //CI encountered { int Ci_id = Aig_ObjId(formula); map::iterator Ci_id_to_Ci_name_map_it = Ci_id_to_Ci_name_map.find(Ci_id); assert(Ci_id_to_Ci_name_map_it != Ci_id_to_Ci_name_map.end()); string Ci_name = Ci_id_to_Ci_name_map_it->second; #ifdef DEBUG_SKOLEM //cout << endl << Ci_name << " encountered in evaluation\n"; #endif node_value = obtainValueOfCi(Ci_name, variable_to_value_map); } else if(formula->Type == AIG_OBJ_CO) //CO encountered { cout << "\nError inside function AIGBasedSkolem::evaluateFormulaOfCi_DFS! CO encountered\n"; assert(false); } else if(formula->Type == AIG_OBJ_CONST1) // 1 encountered { node_value = true; } else if(formula->Type == AIG_OBJ_AND)// child_1 \wedge child_2 encountered { Aig_Obj_t* child_1 = Aig_ObjChild0(formula); Aig_Obj_t* child_2 = Aig_ObjChild1(formula); assert(child_1 != NULL); assert(child_2 != NULL); bool child_1_value = evaluateFormulaOfCi_DFS(child_1, variable_to_value_map); bool child_2_value = evaluateFormulaOfCi_DFS(child_2, variable_to_value_map); node_value = child_1_value && child_2_value; } else { cout << "\nError inside function AIGBasedSkolem::evaluateFormulaOfCi_DFS! Unknown formula->Type " << formula->Type << " encountered\n"; assert(false); } EvaluationTable[key] = node_value; return node_value; } // if(!traversed already) ends here } void AIGBasedSkolem::evaluateBadValues(vector &XValues, map &YValues, int index_of_variable, vector &BadValues) { map variable_to_value_map; for(map::iterator yvalues_it = YValues.begin(); yvalues_it != YValues.end(); yvalues_it++) { bool bool_value; if(yvalues_it->second == 1) { bool_value = true; } else { bool_value = false; } variable_to_value_map.insert(make_pair(yvalues_it->first, bool_value)); #ifdef DEBUG_SKOLEM cout << endl << yvalues_it->first << " --> " << bool_value << " inserted into variable_to_value_map\n"; #endif } for(int var_to_elim_index = number_of_vars_to_elim; var_to_elim_index >= index_of_variable; var_to_elim_index--) { int var_location = var_to_elim_index-1; string var_to_elim = searchVarIndexToVarNameMap(var_index_to_var_name_map, var_to_elim_index); int value = XValues[var_location]; bool bool_value; if(value == 1) { bool_value = true; } else { bool_value = false; } variable_to_value_map.insert(make_pair(var_to_elim, bool_value)); #ifdef DEBUG_SKOLEM cout << endl << var_to_elim << " --> " << bool_value << " inserted into variable_to_value_map\n"; #endif } for(int var_to_elim_index = index_of_variable-1; var_to_elim_index >= 1; var_to_elim_index--) { // obtaining \psi_i Aig_Obj_t* skolem_function; skolem_function = searchOneDimensionalMatrix(SkolemFunctions, number_of_vars_to_elim, var_to_elim_index); assert(skolem_function != NULL); bool bool_value = evaluateFormulaOfCi(skolem_function, variable_to_value_map); int value; if(bool_value) { value = 1; } else { value = 0; } int var_location = var_to_elim_index-1; XValues[var_location] = value; string var_to_elim = searchVarIndexToVarNameMap(var_index_to_var_name_map, var_to_elim_index); variable_to_value_map.insert(make_pair(var_to_elim, bool_value)); #ifdef DEBUG_SKOLEM cout << endl << var_to_elim << " --> " << bool_value << " inserted into variable_to_value_map\n"; #endif } for(int bad_index = 1; bad_index < index_of_variable; bad_index++) { // Obtaining dag for bad_set_i Aig_Obj_t* bad_set_obj; bad_set_obj = searchOneDimensionalMatrix(BadSets, number_of_vars_to_elim+1, bad_index); assert(bad_set_obj != NULL); // evaluate bad_set_obj #ifdef DEBUG_SKOLEM cout << endl << "formula for bad_" << bad_index << " obtained" << endl; #endif bool bool_value = evaluateFormulaOfCi(bad_set_obj, variable_to_value_map); int value; if(bool_value) { value = 1; } else { value = 0; } #ifdef DEBUG_SKOLEM cout << endl << "value of bad_" << bad_index << " is " << value << endl; #endif BadValues.push_back(value); } } void AIGBasedSkolem::analyzeReasonBehindUnderApproximation(int index_of_variable, vector &XValues, vector &XNewValues, map &YValues) { map variable_to_value_map; for(map::iterator yvalues_it = YValues.begin(); yvalues_it != YValues.end(); yvalues_it++) { bool bool_value; if(yvalues_it->second == 1) { bool_value = true; } else { bool_value = false; } variable_to_value_map.insert(make_pair(yvalues_it->first, bool_value)); } for(int var_to_elim_index = number_of_vars_to_elim; var_to_elim_index >= 1; var_to_elim_index--) { int var_location = var_to_elim_index-1; string var_to_elim = searchVarIndexToVarNameMap(var_index_to_var_name_map, var_to_elim_index); int value = XValues[var_location]; bool bool_value; if(value == 1) { bool_value = true; } else { bool_value = false; } variable_to_value_map.insert(make_pair(var_to_elim, bool_value)); } int debug = 3; if(debug == 1) { assert(conjunction_of_factors != NULL); cout << endl << "size_of_conjunction_of_factors = " << computeSize(conjunction_of_factors, pub_aig_manager) << endl; bool value_of_conjunction_of_factors_under_x_y = evaluateFormulaOfCi(conjunction_of_factors, variable_to_value_map); cout << endl << "value_of_conjunction_of_factors under X, Y = " << value_of_conjunction_of_factors_under_x_y << endl; for(int var_to_elim_index = 1; var_to_elim_index <= number_of_vars_to_elim; var_to_elim_index++) { Aig_Obj_t* delta_disjunction_at_i; delta_disjunction_at_i = searchOneDimensionalMatrix(DeltaDisjunctions, number_of_vars_to_elim, var_to_elim_index); assert(delta_disjunction_at_i != NULL); string var_to_elim = searchVarIndexToVarNameMap(var_index_to_var_name_map, var_to_elim_index); //cout << endl << "size_of_delta_disjunction_at " << var_to_elim_index << " = " << computeSize(delta_disjunction_at_i, pub_aig_manager) << endl; bool value_of_delta_disjunction_at_i = evaluateFormulaOfCi(delta_disjunction_at_i, variable_to_value_map); cout << endl << "delta_disjunction[" << var_to_elim_index << "] , i.e. " << var_to_elim << " = " << value_of_delta_disjunction_at_i << endl; } for(int factor_index = 0; factor_index < DeltasForSpecificVariable.size(); factor_index++) { Aig_Obj_t* delta_i_j = DeltasForSpecificVariable[factor_index]; assert(delta_i_j != NULL); cout << endl << "size_of_delta_" << index_of_variable << "_" << factor_index+1 << " = " << computeSize(delta_i_j, pub_aig_manager) << endl; bool value_of_delta_i_j = evaluateFormulaOfCi(delta_i_j, variable_to_value_map); cout << endl << "value_of_delta_" << index_of_variable << "_" << factor_index+1 << " = " << value_of_delta_i_j << endl; } for(int var_to_elim_index = number_of_vars_to_elim; var_to_elim_index >= 1; var_to_elim_index--) { int var_location = var_to_elim_index-1; string var_to_elim = searchVarIndexToVarNameMap(var_index_to_var_name_map, var_to_elim_index); int value = XNewValues[var_location]; bool bool_value; if(value == 1) { bool_value = true; } else { bool_value = false; } variable_to_value_map[var_to_elim] = bool_value; } bool value_of_conjunction_of_factors_under_x_new_y = evaluateFormulaOfCi(conjunction_of_factors, variable_to_value_map); cout << endl << "value_of_conjunction_of_factors under X', Y = " << value_of_conjunction_of_factors_under_x_new_y << endl; } else if(debug == 2) { Aig_Obj_t* bad_set_obj_at_i; bad_set_obj_at_i = searchOneDimensionalMatrix(BadSets, number_of_vars_to_elim, index_of_variable); assert(bad_set_obj_at_i != NULL); Aig_Obj_t* skolem_function_at_i; skolem_function_at_i = searchOneDimensionalMatrix(SkolemFunctions, number_of_vars_to_elim, index_of_variable); assert(skolem_function_at_i != NULL); Aig_Obj_t* alpha_combined_at_i; alpha_combined_at_i = searchOneDimensionalMatrix(AlphaCombineds, number_of_vars_to_elim, index_of_variable); assert(alpha_combined_at_i != NULL); #ifdef DEBUG_SKOLEM Aig_Obj_t* gamma_combined_at_i; gamma_combined_at_i = searchOneDimensionalMatrix(GammaCombineds, number_of_vars_to_elim, index_of_variable); assert(gamma_combined_at_i != NULL); Aig_Obj_t* alpha_gamma_combined_at_i; alpha_gamma_combined_at_i = searchOneDimensionalMatrix(AlphaOrGammaCombineds, number_of_vars_to_elim, index_of_variable); assert(alpha_gamma_combined_at_i != NULL); Aig_Obj_t* beta_combined_at_i; beta_combined_at_i = searchOneDimensionalMatrix(BetaCombineds, number_of_vars_to_elim, index_of_variable); assert(beta_combined_at_i != NULL); Aig_Obj_t* gamma_disjunction_at_i; gamma_disjunction_at_i = searchOneDimensionalMatrix(GammaDisjunctions, number_of_vars_to_elim, index_of_variable); assert(gamma_disjunction_at_i != NULL); Aig_Obj_t* delta_disjunction_at_i; delta_disjunction_at_i = searchOneDimensionalMatrix(DeltaDisjunctions, number_of_vars_to_elim, index_of_variable); assert(delta_disjunction_at_i != NULL); #endif bool value_of_skolem_function_at_i = evaluateFormulaOfCi(skolem_function_at_i, variable_to_value_map); cout << endl << "value_of_skolem_function_at_i = " << value_of_skolem_function_at_i << endl; cout << endl << "size_of_skolem_function_at_i = " << computeSize(skolem_function_at_i, pub_aig_manager) << endl; bool value_of_alpha_combined_at_i = evaluateFormulaOfCi(alpha_combined_at_i, variable_to_value_map); cout << endl << "value_of_alpha_combined_at_i = " << value_of_alpha_combined_at_i << endl; cout << endl << "size_of_alpha_combined_at_i = " << computeSize(alpha_combined_at_i, pub_aig_manager) << endl; bool value_of_bad_set_obj_at_i = evaluateFormulaOfCi(bad_set_obj_at_i, variable_to_value_map); cout << endl << "value_of_bad_set_obj_at_i = " << value_of_bad_set_obj_at_i << endl; cout << endl << "size_of_bad_set_obj_at_i = " << computeSize(bad_set_obj_at_i, pub_aig_manager) << endl; #ifdef DEBUG_SKOLEM bool value_of_gamma_combined_at_i = evaluateFormulaOfCi(gamma_combined_at_i, variable_to_value_map); cout << endl << "value_of_gamma_combined_at_i = " << value_of_gamma_combined_at_i << endl; cout << endl << "size_of_gamma_combined_at_i = " << computeSize(gamma_combined_at_i, pub_aig_manager) << endl; bool value_of_alpha_gamma_combined_at_i = evaluateFormulaOfCi(alpha_gamma_combined_at_i, variable_to_value_map); cout << endl << "value_of_alpha_gamma_combined_at_i = " << value_of_alpha_gamma_combined_at_i << endl; cout << endl << "size_of_alpha_gamma_combined_at_i = " << computeSize(alpha_gamma_combined_at_i, pub_aig_manager) << endl; bool value_of_beta_combined_at_i = evaluateFormulaOfCi(beta_combined_at_i, variable_to_value_map); cout << endl << "value_of_beta_combined_at_i = " << value_of_beta_combined_at_i << endl; cout << endl << "size_of_beta_combined_at_i = " << computeSize(beta_combined_at_i, pub_aig_manager) << endl; bool value_of_gamma_disjunction_at_i = evaluateFormulaOfCi(gamma_disjunction_at_i, variable_to_value_map); cout << endl << "value_of_gamma_disjunction_at_i = " << value_of_gamma_disjunction_at_i << endl; cout << endl << "size_of_gamma_disjunction_at_i = " << computeSize(gamma_disjunction_at_i, pub_aig_manager) << endl; //bool value_of_delta_disjunction_at_i = evaluateFormulaOfCi(delta_disjunction_at_i, variable_to_value_map); //cout << endl << "value_of_delta_disjunction_at_i = " << value_of_delta_disjunction_at_i << endl; writeFormulaToFile(pub_aig_manager, delta_disjunction_at_i, "disjunction_delta", ".v", index_of_variable, 0); cout << endl << "size_of_delta_disjunction_at_i = " << computeSize(delta_disjunction_at_i, pub_aig_manager) << endl; #endif } else { Aig_Obj_t* alpha_combined_at_i; alpha_combined_at_i = searchOneDimensionalMatrix(AlphaCombineds, number_of_vars_to_elim, index_of_variable); assert(alpha_combined_at_i != NULL); Aig_Obj_t* gamma_combined_at_i; gamma_combined_at_i = searchOneDimensionalMatrix(GammaCombineds, number_of_vars_to_elim, index_of_variable); assert(gamma_combined_at_i != NULL); Aig_Obj_t* delta_disjunction_at_i; delta_disjunction_at_i = searchOneDimensionalMatrix(DeltaDisjunctions, number_of_vars_to_elim, index_of_variable); assert(delta_disjunction_at_i != NULL); bool value_of_alpha_combined_at_i = evaluateFormulaOfCi(alpha_combined_at_i, variable_to_value_map); cout << endl << "value_of_alpha_combined_at " << index_of_variable << " = " << value_of_alpha_combined_at_i << endl; cout << endl << "size_of_alpha_combined_at " << index_of_variable << " = " << computeSize(alpha_combined_at_i, pub_aig_manager) << endl; bool value_of_gamma_combined_at_i = evaluateFormulaOfCi(gamma_combined_at_i, variable_to_value_map); cout << endl << "value_of_gamma_combined_at " << index_of_variable << " = " << value_of_gamma_combined_at_i << endl; cout << endl << "size_of_gamma_combined_at " << index_of_variable << " = " << computeSize(gamma_combined_at_i, pub_aig_manager) << endl; //bool value_of_delta_disjunction_at_i = evaluateFormulaOfCi(delta_disjunction_at_i, variable_to_value_map); //cout << endl << "value_of_delta_disjunction_at " << index_of_variable << " = " << value_of_delta_disjunction_at_i << endl; //cout << endl << "size_of_delta_disjunction_at " << index_of_variable << " = " << computeSize(delta_disjunction_at_i, pub_aig_manager) << endl; } } Aig_Obj_t* AIGBasedSkolem::computeBetaCombinedForDebugging(int var_to_elim_index) { // Let us compute beta_combined_{var_to_elim_index} // Suppose i = var_to_elim_index // i.e. we need to compute beta_combined_{i} // beta_combined_{i} = disjunction of beta_i_j's set beta_combined_components; #ifdef DEBUG_SKOLEM cout << "\ncomputing components of beta_combined\n"; #endif #ifdef PRINT_VERY_DETAILED_RECORDS_ON_SCREEN cout << "\ncomputing components of beta_combined\n"; #endif for(set::iterator factor_it = FactorsWithVariable.begin(); factor_it != FactorsWithVariable.end(); factor_it++) { int factor_index = *factor_it; #ifdef DEBUG_SKOLEM cout << "\nfactor_index = " << factor_index << endl; #endif // Suppose j = factor_index // Each beta_combined_component_i_j is beta_i_j Aig_Obj_t* beta_i_j; beta_i_j = computeBeta(var_to_elim_index, factor_index); assert(beta_i_j != NULL); #ifdef DEBUG_SKOLEM writeFormulaToFile(pub_aig_manager, beta_i_j, "beta", ".v", var_to_elim_index, factor_index); #endif beta_combined_components.insert(beta_i_j); }// for each factor ends here // recall that beta_combined = disjunction of beta_combined_components Aig_Obj_t* beta_combined; if(beta_combined_components.size() == 0) // we should return false in this case (as per defn. of beta) { beta_combined = createFalse(pub_aig_manager); assert(beta_combined != NULL); } else { beta_combined = createOr(beta_combined_components, pub_aig_manager); assert(beta_combined != NULL); } #ifdef DEBUG_SKOLEM writeFormulaToFile(pub_aig_manager, beta_combined, "beta_combined", ".v", var_to_elim_index, 0); #endif #ifdef RECORD_KEEP NumberOfFactors = FactorsWithVariable.size(); #endif return beta_combined; } // function ends here Aig_Obj_t* AIGBasedSkolem::computeDisjunctionOfGammas(int var_to_elim_index) { // Suppose i = var_to_elim_index set gamma_combined_components; for(set::iterator factor_it = FactorsWithVariable.begin(); factor_it != FactorsWithVariable.end(); factor_it++) { int factor_index = *factor_it; #ifdef DEBUG_SKOLEM cout << "\nfactor_index = " << factor_index << endl; #endif // Suppose j = factor_index Aig_Obj_t* gamma_i_j; gamma_i_j = computeGamma(var_to_elim_index, factor_index); assert(gamma_i_j != NULL); gamma_combined_components.insert(gamma_i_j); }// for each factor ends here Aig_Obj_t* gamma_combined; if(gamma_combined_components.size() == 0) { gamma_combined = createFalse(pub_aig_manager); assert(gamma_combined != NULL); } else { gamma_combined = createOr(gamma_combined_components, pub_aig_manager); assert(gamma_combined != NULL); } #ifdef DEBUG_SKOLEM writeFormulaToFile(pub_aig_manager, gamma_combined, "disjunction_gamma", ".v", var_to_elim_index, 0); #endif return gamma_combined; } // function ends here Aig_Obj_t* AIGBasedSkolem::computeDisjunctionOfDeltas(int var_to_elim_index) { // Suppose i = var_to_elim_index set delta_combined_components; for(set::iterator factor_it = FactorsWithVariable.begin(); factor_it != FactorsWithVariable.end(); factor_it++) { int factor_index = *factor_it; #ifdef DEBUG_SKOLEM cout << "\nfactor_index = " << factor_index << endl; #endif // Suppose j = factor_index Aig_Obj_t* delta_i_j; delta_i_j = computeDelta(var_to_elim_index, factor_index); assert(delta_i_j != NULL); #ifdef DEBUG_SKOLEM writeFormulaToFile(pub_aig_manager, delta_i_j, "delta", ".v", var_to_elim_index, factor_index); #endif delta_combined_components.insert(delta_i_j); if(var_to_elim_index == 1) { DeltasForSpecificVariable.push_back(delta_i_j); } }// for each factor ends here Aig_Obj_t* delta_combined; if(delta_combined_components.size() == 0) { delta_combined = createFalse(pub_aig_manager); assert(delta_combined != NULL); } else { delta_combined = createOr(delta_combined_components, pub_aig_manager); assert(delta_combined != NULL); } #ifdef DEBUG_SKOLEM writeFormulaToFile(pub_aig_manager, delta_combined, "disjunction_delta", ".v", var_to_elim_index, 0); #endif return delta_combined; } // function ends here void AIGBasedSkolem::reevaluateXValues_using_Solver(vector &XValues, map &YValues, int asserted_location, int asserted_value) { assert(asserted_value == 0 || asserted_value == 1); XValues[asserted_location] = asserted_value; set assignment_objects; // assert that all y variables keep their values as in the existing model for(map::iterator yvalues_it = YValues.begin(); yvalues_it != YValues.end(); yvalues_it++) { string variable_name = yvalues_it->first; int variable_value = yvalues_it->second; Aig_Obj_t* variable_object; map::iterator Ci_name_to_Ci_object_map_it = Ci_name_to_Ci_object_map.find(variable_name); assert(Ci_name_to_Ci_object_map_it != Ci_name_to_Ci_object_map.end()); variable_object = Ci_name_to_Ci_object_map_it->second; if(variable_value == 0) // variable_value is false { // negate variable_object variable_object = createNot(variable_object, pub_aig_manager); } assignment_objects.insert(variable_object); } // assert that all x variables upto and including asserted_location keep their values as in the existing model for(int var_to_elim_index = number_of_vars_to_elim; var_to_elim_index >= 1; var_to_elim_index--) { int location = var_to_elim_index-1; if(location < asserted_location) { break; } else { Aig_Obj_t* variable_object; string var_to_elim = searchVarIndexToVarNameMap(var_index_to_var_name_map, var_to_elim_index); map::iterator Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it = Ci_to_eliminate_name_to_Ci_to_eliminate_object_map.find(var_to_elim); assert(Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it != Ci_to_eliminate_name_to_Ci_to_eliminate_object_map.end()); variable_object = Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it->second; if(XValues[location] == 0) // variable_value is false { // negate variable_object variable_object = createNot(variable_object, pub_aig_manager); } assignment_objects.insert(variable_object); } } assert(!assignment_objects.empty()); Aig_Obj_t* assignment = createAnd(assignment_objects, pub_aig_manager); assert(assignment != NULL); #ifdef DEBUG_SKOLEM string assignment_file_name = benchmark_name_without_extension; assignment_file_name += "_asserted_value_assignment"; cout << "\nassignment computed\n"; writeFormulaToFile(pub_aig_manager, assignment, assignment_file_name, ".v", asserted_location, cegar_iteration_number); #endif #ifdef DEBUG_SKOLEM cout << "\nassignment computed\n"; cout << "\nLet's compute S_equivalence_part\n"; #endif Aig_Obj_t* S_equivalence_part; set S_equivalence_objects; for(int var_to_elim_index = 1; var_to_elim_index <= number_of_vars_to_elim; var_to_elim_index++) { int location = var_to_elim_index-1; if(location >= asserted_location) { break; } else { // obtaining dag for x_i string var_to_elim = searchVarIndexToVarNameMap(var_index_to_var_name_map, var_to_elim_index); #ifdef DEBUG_SKOLEM cout << "\nvar_to_elim_index = " << var_to_elim_index << "\tvar_to_elim = " << var_to_elim << endl; #endif map::iterator Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it = Ci_to_eliminate_name_to_Ci_to_eliminate_object_map.find(var_to_elim); assert(Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it != Ci_to_eliminate_name_to_Ci_to_eliminate_object_map.end()); Aig_Obj_t* var_to_elim_obj = Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it->second; // obtaining \psi_i Aig_Obj_t* skolem_function; skolem_function = searchOneDimensionalMatrix(SkolemFunctions, number_of_vars_to_elim, var_to_elim_index); assert(skolem_function != NULL); Aig_Obj_t* S_equivalence_i = createEquivalence(skolem_function, var_to_elim_obj, pub_aig_manager); S_equivalence_objects.insert(S_equivalence_i); } } assert(!S_equivalence_objects.empty()); S_equivalence_part = createAnd(S_equivalence_objects, pub_aig_manager); assert(S_equivalence_part != NULL); #ifdef DEBUG_SKOLEM cout << "\nS_equivalence_part computed\n"; #endif // Let's create dag for conjunction of (C_i_j = dags for C_i_j) for all the connections C_i_j #ifdef DEBUG_SKOLEM cout << "\nLet's compute S_connection_part\n"; #endif Aig_Obj_t* S_connection_part; set S_connection_objects; for(map::iterator connection_string_to_connection_object_map_it = connection_string_to_connection_object_map.begin(); connection_string_to_connection_object_map_it != connection_string_to_connection_object_map.end(); connection_string_to_connection_object_map_it++) { string connection_string = connection_string_to_connection_object_map_it->first; Aig_Obj_t* connection_obj = connection_string_to_connection_object_map_it->second; assert(connection_obj != NULL); map::iterator Connections_it = Connections.find(connection_string); assert(Connections_it != Connections.end()); Aig_Obj_t* connection_dag = Connections_it->second; assert(connection_dag != NULL); Aig_Obj_t* S_connection_i = createEquivalence(connection_dag, connection_obj, pub_aig_manager); S_connection_objects.insert(S_connection_i); } if(S_connection_objects.empty()) { S_connection_part = createTrue(pub_aig_manager); } else { S_connection_part = createAnd(S_connection_objects, pub_aig_manager); } assert(S_connection_part != NULL); #ifdef DEBUG_SKOLEM cout << "\nS_connection_part computed\n"; #endif #ifdef DEBUG_SKOLEM string S_connection_part_file_name = benchmark_name_without_extension; S_connection_part_file_name += "_S_asserted_value_connection_part"; string S_equivalence_part_file_name = benchmark_name_without_extension; S_equivalence_part_file_name += "_S_asserted_value_equivalence_part"; cout << "\nS_zero_connection_part computed\n"; cout << "\nS_zero_equivalence_part computed\n"; writeFormulaToFile(pub_aig_manager, S_connection_part, S_connection_part_file_name, ".v", asserted_location, cegar_iteration_number); writeFormulaToFile(pub_aig_manager, S_equivalence_part, S_equivalence_part_file_name, ".v", asserted_location, cegar_iteration_number); #endif set modelderive_objects; modelderive_objects.insert(S_equivalence_part); modelderive_objects.insert(S_connection_part); modelderive_objects.insert(assignment); Aig_Obj_t* modelderive = createAnd(modelderive_objects, pub_aig_manager); assert(modelderive != NULL); // Let's call the SAT-Solver to obtain model for modelderive #ifdef DEBUG_SKOLEM cout << endl << "Giving modelderive to SAT-Solver\n"; #endif map Model_of_Modelderive; #ifdef DETAILED_RECORD_KEEP unsigned long long int solver_ms; struct timeval solver_start_ms, solver_finish_ms; gettimeofday (&solver_start_ms, NULL); #endif // Give to SAT-Solver and get unsat / sat with model unsigned long long int cnf_time; int formula_size; unsigned long long int simplification_time; bool result_of_modelderive = isSat(pub_aig_manager, modelderive, Model_of_Modelderive, cnf_time, formula_size, simplification_time); #ifdef DETAILED_RECORD_KEEP gettimeofday (&solver_finish_ms, NULL); solver_ms = solver_finish_ms.tv_sec * 1000 + solver_finish_ms.tv_usec / 1000; solver_ms -= solver_start_ms.tv_sec * 1000 + solver_start_ms.tv_usec / 1000; cout << "\nsolver finished in " << solver_ms << " milliseconds\n"; total_time_in_smt_solver = total_time_in_smt_solver + solver_ms; #endif #ifdef RECORD_KEEP string record_file; record_file = logfile_prefix; record_file += "skolem_function_generation_details.txt"; FILE* record_fp = fopen(record_file.c_str(), "a+"); assert(record_fp != NULL); fprintf(record_fp, "%llu(%llu,%llu)(%d),", solver_ms, cnf_time, simplification_time, formula_size); fclose(record_fp); #endif #ifdef DEBUG_SKOLEM displayModelFromSATSolver(Model_of_Modelderive); cout << endl << "result_of_modelderive = " << result_of_modelderive << endl; #endif if(!result_of_modelderive) // modelderive is unsat { cout << "\nError inside AIGBasedSkolem::reevaluateXValues_using_Solver!! In model derivation\n"; assert(false); } else { // Get the changed XValues for(int var_to_elim_index = 1; var_to_elim_index <= number_of_vars_to_elim; var_to_elim_index++) { int location = var_to_elim_index-1; string var_to_elim = searchVarIndexToVarNameMap(var_index_to_var_name_map, var_to_elim_index); map::iterator Model_of_Modelderive_it; Model_of_Modelderive_it = Model_of_Modelderive.find(var_to_elim); assert(Model_of_Modelderive_it != Model_of_Modelderive.end()); int changed_x_value = Model_of_Modelderive_it->second; if(location < asserted_location) { XValues[location] = changed_x_value; } else if(location > asserted_location) { assert(XValues[location] == changed_x_value); } else //location == asserted_location { assert(changed_x_value == asserted_value); } } } // Get the changed XValues ends here } void AIGBasedSkolem::evaluateBadValues_using_Solver(vector &XValues, map &YValues, int index_of_variable, vector &BadValues) { int one_location = index_of_variable - 1; // Let's obtain values for XValues[0] ... XValues[one_location-1] using sat solver set assignment_objects; // assert that all y variables keep their values as in the existing model for(map::iterator yvalues_it = YValues.begin(); yvalues_it != YValues.end(); yvalues_it++) { string variable_name = yvalues_it->first; int variable_value = yvalues_it->second; Aig_Obj_t* variable_object; map::iterator Ci_name_to_Ci_object_map_it = Ci_name_to_Ci_object_map.find(variable_name); assert(Ci_name_to_Ci_object_map_it != Ci_name_to_Ci_object_map.end()); variable_object = Ci_name_to_Ci_object_map_it->second; if(variable_value == 0) // variable_value is false { // negate variable_object variable_object = createNot(variable_object, pub_aig_manager); } assignment_objects.insert(variable_object); } // assert that all x variables upto and including one_location keep their values as in the existing model for(int var_to_elim_index = number_of_vars_to_elim; var_to_elim_index >= 1; var_to_elim_index--) { int location = var_to_elim_index-1; if(location < one_location) { break; } else { Aig_Obj_t* variable_object; string var_to_elim = searchVarIndexToVarNameMap(var_index_to_var_name_map, var_to_elim_index); map::iterator Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it = Ci_to_eliminate_name_to_Ci_to_eliminate_object_map.find(var_to_elim); assert(Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it != Ci_to_eliminate_name_to_Ci_to_eliminate_object_map.end()); variable_object = Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it->second; if(XValues[location] == 0) // variable_value is false { // negate variable_object variable_object = createNot(variable_object, pub_aig_manager); } assignment_objects.insert(variable_object); } } assert(!assignment_objects.empty()); Aig_Obj_t* assignment = createAnd(assignment_objects, pub_aig_manager); assert(assignment != NULL); #ifdef DEBUG_SKOLEM string assignment_file_name = benchmark_name_without_extension; assignment_file_name += "_one_assignment"; cout << "\nassignment computed\n"; writeFormulaToFile(pub_aig_manager, assignment, assignment_file_name, ".v", one_location, cegar_iteration_number); #endif Aig_Obj_t* S_equivalence_part; set S_equivalence_objects; for(int var_to_elim_index = 1; var_to_elim_index <= number_of_vars_to_elim; var_to_elim_index++) { int location = var_to_elim_index-1; if(location >= one_location) { break; } else { // obtaining dag for x_i string var_to_elim = searchVarIndexToVarNameMap(var_index_to_var_name_map, var_to_elim_index); map::iterator Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it = Ci_to_eliminate_name_to_Ci_to_eliminate_object_map.find(var_to_elim); assert(Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it != Ci_to_eliminate_name_to_Ci_to_eliminate_object_map.end()); Aig_Obj_t* var_to_elim_obj = Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it->second; // obtaining \psi_i Aig_Obj_t* skolem_function; skolem_function = searchOneDimensionalMatrix(SkolemFunctions, number_of_vars_to_elim, var_to_elim_index); assert(skolem_function != NULL); Aig_Obj_t* S_equivalence_i = createEquivalence(skolem_function, var_to_elim_obj, pub_aig_manager); S_equivalence_objects.insert(S_equivalence_i); } } assert(!S_equivalence_objects.empty()); S_equivalence_part = createAnd(S_equivalence_objects, pub_aig_manager); assert(S_equivalence_part != NULL); // Let's create dag for conjunction of (C_i_j = dags for C_i_j) for all the connections C_i_j Aig_Obj_t* S_connection_part; set S_connection_objects; for(map::iterator connection_string_to_connection_object_map_it = connection_string_to_connection_object_map.begin(); connection_string_to_connection_object_map_it != connection_string_to_connection_object_map.end(); connection_string_to_connection_object_map_it++) { string connection_string = connection_string_to_connection_object_map_it->first; Aig_Obj_t* connection_obj = connection_string_to_connection_object_map_it->second; assert(connection_obj != NULL); map::iterator Connections_it = Connections.find(connection_string); assert(Connections_it != Connections.end()); Aig_Obj_t* connection_dag = Connections_it->second; assert(connection_dag != NULL); Aig_Obj_t* S_connection_i = createEquivalence(connection_dag, connection_obj, pub_aig_manager); S_connection_objects.insert(S_connection_i); } if(S_connection_objects.empty()) { S_connection_part = createTrue(pub_aig_manager); } else { S_connection_part = createAnd(S_connection_objects, pub_aig_manager); } assert(S_connection_part != NULL); #ifdef DEBUG_SKOLEM string S_connection_part_file_name = benchmark_name_without_extension; S_connection_part_file_name += "_S_one_connection_part"; string S_equivalence_part_file_name = benchmark_name_without_extension; S_equivalence_part_file_name += "_S_one_equivalence_part"; cout << "\nS_one_connection_part computed\n"; cout << "\nS_one_equivalence_part computed\n"; writeFormulaToFile(pub_aig_manager, S_connection_part, S_connection_part_file_name, ".v", one_location, cegar_iteration_number); writeFormulaToFile(pub_aig_manager, S_equivalence_part, S_equivalence_part_file_name, ".v", one_location, cegar_iteration_number); #endif set modelderive_objects; modelderive_objects.insert(S_equivalence_part); modelderive_objects.insert(S_connection_part); modelderive_objects.insert(assignment); Aig_Obj_t* modelderive = createAnd(modelderive_objects, pub_aig_manager); assert(modelderive != NULL); // Let's call the SAT-Solver to obtain model for modelderive #ifdef DEBUG_SKOLEM cout << endl << "Giving modelderive to SAT-Solver\n"; #endif map Model_of_Modelderive; #ifdef DETAILED_RECORD_KEEP unsigned long long int solver_ms; struct timeval solver_start_ms, solver_finish_ms; gettimeofday (&solver_start_ms, NULL); #endif // Give to SAT-Solver and get unsat / sat with model unsigned long long int cnf_time; int formula_size; unsigned long long int simplification_time; bool result_of_modelderive = isSat(pub_aig_manager, modelderive, Model_of_Modelderive, cnf_time, formula_size, simplification_time); #ifdef DETAILED_RECORD_KEEP gettimeofday (&solver_finish_ms, NULL); solver_ms = solver_finish_ms.tv_sec * 1000 + solver_finish_ms.tv_usec / 1000; solver_ms -= solver_start_ms.tv_sec * 1000 + solver_start_ms.tv_usec / 1000; cout << "\nsolver finished in " << solver_ms << " milliseconds\n"; total_time_in_smt_solver = total_time_in_smt_solver + solver_ms; #endif #ifdef RECORD_KEEP string record_file; record_file = logfile_prefix; record_file += "skolem_function_generation_details.txt"; FILE* record_fp = fopen(record_file.c_str(), "a+"); assert(record_fp != NULL); fprintf(record_fp, "%llu(%llu,%llu)(%d),", solver_ms, cnf_time, simplification_time, formula_size); fclose(record_fp); #endif #ifdef DEBUG_SKOLEM displayModelFromSATSolver(Model_of_Modelderive); cout << endl << "result_of_modelderive = " << result_of_modelderive << endl; #endif if(!result_of_modelderive) // modelderive is unsat { cout << "\nError inside AIGBasedSkolem::evaluateBadValues_using_Solver!! In model derivation\n"; assert(false); } else { // Get the changed XValues for(int var_to_elim_index = 1; var_to_elim_index <= number_of_vars_to_elim; var_to_elim_index++) { int location = var_to_elim_index-1; string var_to_elim = searchVarIndexToVarNameMap(var_index_to_var_name_map, var_to_elim_index); map::iterator Model_of_Modelderive_it; Model_of_Modelderive_it = Model_of_Modelderive.find(var_to_elim); assert(Model_of_Modelderive_it != Model_of_Modelderive.end()); int changed_x_value = Model_of_Modelderive_it->second; if(location < one_location) { XValues[location] = changed_x_value; } else if(location > one_location) { assert(XValues[location] == changed_x_value); } else //location == one_location { assert(changed_x_value == 1); } } } // Get the changed XValues ends here map variable_to_value_map; for(map::iterator yvalues_it = YValues.begin(); yvalues_it != YValues.end(); yvalues_it++) { bool bool_value; if(yvalues_it->second == 1) { bool_value = true; } else { bool_value = false; } variable_to_value_map.insert(make_pair(yvalues_it->first, bool_value)); #ifdef DEBUG_SKOLEM cout << endl << yvalues_it->first << " --> " << bool_value << " inserted into variable_to_value_map\n"; #endif } for(int var_to_elim_index = number_of_vars_to_elim; var_to_elim_index >= 1; var_to_elim_index--) { int var_location = var_to_elim_index-1; string var_to_elim = searchVarIndexToVarNameMap(var_index_to_var_name_map, var_to_elim_index); int value = XValues[var_location]; bool bool_value; if(value == 1) { bool_value = true; } else { bool_value = false; } variable_to_value_map.insert(make_pair(var_to_elim, bool_value)); #ifdef DEBUG_SKOLEM cout << endl << var_to_elim << " --> " << bool_value << " inserted into variable_to_value_map\n"; #endif #ifdef DEBUG_CEGAR cout << endl << "x[" << var_location << "] --> " << bool_value << " inserted into variable_to_value_map\n"; #endif } for(int bad_index = 1; bad_index < index_of_variable; bad_index++) { // Obtaining dag for bad_set_i Aig_Obj_t* bad_set_obj; bad_set_obj = searchOneDimensionalMatrix(BadSets, number_of_vars_to_elim+1, bad_index); assert(bad_set_obj != NULL); // evaluate bad_set_obj #ifdef DEBUG_SKOLEM cout << endl << "formula for bad_" << bad_index << " obtained" << endl; #endif bool bool_value = evaluateFormulaOfCi(bad_set_obj, variable_to_value_map); int value; if(bool_value) { value = 1; } else { value = 0; } #ifdef DEBUG_CEGAR cout << endl << "value of bad_" << bad_index << " is " << value << endl; #endif BadValues.push_back(value); } } bool AIGBasedSkolem::checkIfSkolemFunctionsAreExact_using_ABC_with_Composes(map &Model_of_ExactnessCheck, map &Refinement_Hint_To_Eliminate_This_CEX, list &VariablesToEliminate) { Aig_Obj_t* exactnesscheck; #ifdef RECORD_KEEP string record_file; record_file = logfile_prefix; record_file += "skolem_function_generation_details.txt"; FILE* record_fp = fopen(record_file.c_str(), "a+"); assert(record_fp != NULL); #endif if(cegar_iteration_number > 0) { #ifdef RECORD_KEEP fprintf(record_fp, "\t"); #endif for(map::iterator hint_it = Refinement_Hint_To_Eliminate_This_CEX.begin(); hint_it != Refinement_Hint_To_Eliminate_This_CEX.end(); hint_it++) { // take each refinement hint // copy it to refinement_hints int variable_index = hint_it->first; int bad_index = hint_it->second; assert(bad_index < variable_index); #ifdef DEBUG_CEGAR cout << "\nThe refinement hint is: variable_index = " << variable_index << ", bad_index = " << bad_index << endl; #endif #ifdef RECORD_KEEP fprintf(record_fp, "%d-->%d,", bad_index, variable_index); #endif #ifdef ANALYZE_CEGAR string cegar_file = "cegar_details.txt"; FILE* cegar_fp = fopen(cegar_file.c_str(), "a+"); assert(cegar_fp != NULL); fprintf(cegar_fp, "\n\nThe refinement hint is: %d-->%d\n", bad_index, variable_index); fclose(cegar_fp); #endif map >::iterator refinement_hint_it = refinement_hints.find(variable_index); if(refinement_hint_it == refinement_hints.end()) // entry does not exist for variable_index { set bad_indices; bad_indices.insert(bad_index); refinement_hints.insert(make_pair(variable_index, bad_indices)); } else // entry exists for variable_index { (refinement_hint_it->second).insert(bad_index); } #ifdef DEBUG_CEGAR cout << "\nThe refinement hint to eliminate this counterexample is copied into refinement hints\n"; showMap(refinement_hints, "refinement_hints"); #endif // update the sensitivity list for(int skolem_index = bad_index; skolem_index < variable_index; skolem_index++) { // variable_index is sensitive to skolem_index #ifdef DEBUG_CEGAR cout << "\n" << variable_index << " is sensitive to " << skolem_index << endl; #endif map >::iterator sensitivity_list_it = sensitivity_list.find(skolem_index); if(sensitivity_list_it == sensitivity_list.end()) // entry does not exist for skolem_index { set sensitive_indices; sensitive_indices.insert(variable_index); sensitivity_list.insert(make_pair(skolem_index, sensitive_indices)); } else // entry exists for skolem_index { (sensitivity_list_it->second).insert(variable_index); } #ifdef DEBUG_CEGAR cout << "\n" << variable_index << " -> " << skolem_index << " inserted into sensitivity_list\n"; #endif } #ifdef DEBUG_CEGAR cout << "\nSensitivity list updated\n"; showMap(sensitivity_list, "sensitivity_list"); #endif // find the skolem functions to be re-computed set skolem_functions_to_recompute; set skolem_functions_changed; skolem_functions_changed.insert(variable_index); // find skolem functions that are sensitive to change in skolem // function at variable_index findSkolemFunctionsToRecompute(skolem_functions_changed, skolem_functions_to_recompute); #ifdef DEBUG_CEGAR showSet(skolem_functions_to_recompute, "skolem_functions_to_recompute"); #endif for(set::iterator skolem_functions_to_recompute_it = skolem_functions_to_recompute.begin(); skolem_functions_to_recompute_it != skolem_functions_to_recompute.end(); skolem_functions_to_recompute_it++) { // update skolem function at skolem_index int skolem_index = *skolem_functions_to_recompute_it; #ifdef DEBUG_CEGAR cout << "\nRecomputing skolem function at " << skolem_index << endl; #endif // Recomputing skolem function at skolem_index // skolem_function_i = alpha_i \vee (gamma_i \wedge (~Bad_i with x_i set to true) \wedge (~Bad_j after substitutions)) Aig_Obj_t* alpha_combined; alpha_combined = searchOneDimensionalMatrix(AlphaCombineds, number_of_vars_to_elim, skolem_index); assert(alpha_combined != NULL); set gamma_parts; Aig_Obj_t* gamma_combined; gamma_combined = searchOneDimensionalMatrix(GammaCombineds, number_of_vars_to_elim, skolem_index); assert(gamma_combined != NULL); gamma_parts.insert(gamma_combined); Aig_Obj_t* bad_set_obj; bad_set_obj = searchOneDimensionalMatrix(BadSets, number_of_vars_to_elim, skolem_index); assert(bad_set_obj != NULL); Aig_Obj_t* bad_part; if(!formulaFreeOfVariable(bad_set_obj, skolem_index)) { // replace skolem_index in bad_set_obj by one Aig_Obj_t* cofactor_one = replaceVariableByConstant(bad_set_obj, skolem_index, 1); assert(cofactor_one != NULL); bad_part = createNot(cofactor_one, pub_aig_manager); assert(bad_part != NULL); } else { Aig_Obj_t* cofactor_one = bad_set_obj; bad_part = createNot(cofactor_one, pub_aig_manager); assert(bad_part != NULL); } gamma_parts.insert(bad_part); // obtain the bad parts from the refinement hints map >::iterator refinement_hint_it_for_skolem_index = refinement_hints.find(skolem_index); assert(refinement_hint_it_for_skolem_index != refinement_hints.end()); set bad_indices_for_skolem_index = refinement_hint_it_for_skolem_index->second; assert(!bad_indices_for_skolem_index.empty()); for(set::iterator bad_indices_for_skolem_index_it = bad_indices_for_skolem_index.begin(); bad_indices_for_skolem_index_it != bad_indices_for_skolem_index.end(); bad_indices_for_skolem_index_it++) { int bad_index_for_skolem_index = *bad_indices_for_skolem_index_it; assert(bad_index_for_skolem_index < skolem_index); #ifdef DEBUG_CEGAR cout << "\nbad_index_for_skolem_index = " << bad_index_for_skolem_index << endl; #endif Aig_Obj_t* bad_set_obj_at_bad_index; bad_set_obj_at_bad_index = searchOneDimensionalMatrix(BadSets, number_of_vars_to_elim, bad_index_for_skolem_index); assert(bad_set_obj_at_bad_index != NULL); for(int subst_index = bad_index_for_skolem_index; subst_index < skolem_index; subst_index++) { Aig_Obj_t* skolem_function_to_substitute; skolem_function_to_substitute = searchOneDimensionalMatrix(SkolemFunctions, number_of_vars_to_elim, subst_index); assert(skolem_function_to_substitute != NULL); bad_set_obj_at_bad_index = replaceVariableByFormula(bad_set_obj_at_bad_index, subst_index, skolem_function_to_substitute); assert(bad_set_obj_at_bad_index != NULL); } bad_set_obj_at_bad_index = replaceVariableByConstant(bad_set_obj_at_bad_index, skolem_index, 1); assert(bad_set_obj_at_bad_index != NULL); bad_set_obj_at_bad_index = createNot(bad_set_obj_at_bad_index, pub_aig_manager); assert(bad_set_obj_at_bad_index != NULL); gamma_parts.insert(bad_set_obj_at_bad_index); } // obtain the bad parts from the refinement hints ends here Aig_Obj_t* gamma_part; assert(!gamma_parts.empty()); gamma_part = createAnd(gamma_parts, pub_aig_manager); assert(gamma_part != NULL); Aig_Obj_t* new_skolem_function; new_skolem_function = createOr(alpha_combined, gamma_part, pub_aig_manager); assert(new_skolem_function != NULL); #ifdef ANALYZE_CEGAR int size_of_existing_skolem_function; Aig_Obj_t* skolem_function_existing_previously; skolem_function_existing_previously = searchOneDimensionalMatrix(SkolemFunctions, number_of_vars_to_elim, skolem_index); assert(skolem_function_existing_previously != NULL); size_of_existing_skolem_function = computeSize(skolem_function_existing_previously, pub_aig_manager); #endif // insert the new skolem function insertIntoOneDimensionalMatrix(SkolemFunctions, number_of_vars_to_elim, skolem_index, new_skolem_function, true); #ifdef PRINT_SKOLEM_FUNCTIONS string skolem_function_file_name = benchmark_name_without_extension; skolem_function_file_name += "_skolem_function"; writeFormulaToFile(pub_aig_manager, new_skolem_function, skolem_function_file_name, ".v", skolem_index, cegar_iteration_number); #endif #ifdef DEBUG_CEGAR cout << "\nSkolem function at " << skolem_index << " recomputed\n"; #endif #ifdef ANALYZE_CEGAR string cegar_file = "cegar_details.txt"; FILE* cegar_fp = fopen(cegar_file.c_str(), "a+"); assert(cegar_fp != NULL); set Final_VariablesToEliminate_Set(VariablesToEliminate.begin(), VariablesToEliminate.end()); // code for showing supports set support_new_skolem_function; computeSupport(new_skolem_function, support_new_skolem_function, pub_aig_manager); set inputs_new_skolem_function; set_intersection(support_new_skolem_function.begin(), support_new_skolem_function.end(), Final_VariablesToEliminate_Set.begin(), Final_VariablesToEliminate_Set.end(), inserter(inputs_new_skolem_function, inputs_new_skolem_function.begin())); set inputs_int_new_skolem_function; for(set::iterator inputs_new_skolem_function_it = inputs_new_skolem_function.begin(); inputs_new_skolem_function_it != inputs_new_skolem_function.end(); inputs_new_skolem_function_it++) { string input_string = *inputs_new_skolem_function_it; int input_int = searchVarNameToVarIndexMap(var_name_to_var_index_map, input_string); assert(input_int != -1); inputs_int_new_skolem_function.insert(input_int); } fprintf(cegar_fp, "\n\nSkolem function at %d recomputed", skolem_index); int size_of_new_skolem_function = computeSize(new_skolem_function, pub_aig_manager); int increase_in_size_of_skolem_function = size_of_new_skolem_function - size_of_existing_skolem_function; fprintf(cegar_fp, "\nIncrease in size = %d\n", increase_in_size_of_skolem_function); printSet(inputs_int_new_skolem_function, "inputs_int_new_skolem_function", cegar_fp); fclose(cegar_fp); #endif } // skolem functions of all sensitive variables recomputed } // take each hint ends here } // if(cegar_iteration_number > 0) ends here #ifdef DEBUG_CEGAR cout << "\nCreating exactnesscheck\n"; #endif // Create the dag for // F(X',Y) \wedge (B1\vee ... \vee B_n \vee B_{n+1}) \wedge // (B_1 = bad_set_1) \wedge ... \wedge (B_n = bad_set_n) \wedge (B_{n+1} = bad_set_{n+1}) \wedge // (x_1 = psi_1) \wedge ... \wedge (x_n = psi_n) // dag for F(X',Y) is already created in renamed_conjunction_of_factors // dag for (B1\vee ... \vee B_n \vee B_{n+1}) is already created in disjunction_of_bad_symbols // Let's first create dag for (B_1 = bad_set_1) \wedge ... \wedge (B_n = bad_set_n) \wedge (B_{n+1} = bad_set_{n+1}) set B_equivalence_objects; for(int bad_location_index = 1; bad_location_index <= number_of_vars_to_elim+1; bad_location_index++) { // Let bad_location_index be i // Obtaining dag for bad_set_i Aig_Obj_t* bad_set_obj; bad_set_obj = searchOneDimensionalMatrix(BadSets, number_of_vars_to_elim+1, bad_location_index); assert(bad_set_obj != NULL); // Obtaining dag for B_i map::iterator B_i_index_to_B_i_object_map_iterator = B_i_index_to_B_i_object_map.find(bad_location_index); assert(B_i_index_to_B_i_object_map_iterator != B_i_index_to_B_i_object_map.end()); Aig_Obj_t* B_obj = B_i_index_to_B_i_object_map_iterator->second; Aig_Obj_t* B_equivalence_i = createEquivalence(bad_set_obj, B_obj, pub_aig_manager); B_equivalence_objects.insert(B_equivalence_i); } assert(!B_equivalence_objects.empty()); B_equivalence_part = createAnd(B_equivalence_objects, pub_aig_manager); assert(B_equivalence_part != NULL); // Let's create dag for (x_1 = psi_1) \wedge ... \wedge (x_n = psi_n) Aig_Obj_t* S_equivalence_part; set S_equivalence_objects; for(int var_to_elim_index = 1; var_to_elim_index <= number_of_vars_to_elim; var_to_elim_index++) { // obtaining dag for x_i string var_to_elim = searchVarIndexToVarNameMap(var_index_to_var_name_map, var_to_elim_index); map::iterator Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it = Ci_to_eliminate_name_to_Ci_to_eliminate_object_map.find(var_to_elim); assert(Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it != Ci_to_eliminate_name_to_Ci_to_eliminate_object_map.end()); Aig_Obj_t* var_to_elim_obj = Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it->second; // obtaining \psi_i Aig_Obj_t* skolem_function; skolem_function = searchOneDimensionalMatrix(SkolemFunctions, number_of_vars_to_elim, var_to_elim_index); assert(skolem_function != NULL); Aig_Obj_t* S_equivalence_i = createEquivalence(skolem_function, var_to_elim_obj, pub_aig_manager); S_equivalence_objects.insert(S_equivalence_i); } assert(!S_equivalence_objects.empty()); S_equivalence_part = createAnd(S_equivalence_objects, pub_aig_manager); assert(S_equivalence_part != NULL); #ifdef DEBUG_SKOLEM string B_equivalence_part_file_name = benchmark_name_without_extension; B_equivalence_part_file_name += "_B_equivalence_part"; string S_equivalence_part_file_name = benchmark_name_without_extension; S_equivalence_part_file_name += "_S_equivalence_part"; cout << "\nB_equivalence_part computed\n"; cout << "\nS_equivalence_part computed\n"; writeFormulaToFile(pub_aig_manager, B_equivalence_part, B_equivalence_part_file_name, ".v", 0, 0); writeFormulaToFile(pub_aig_manager, S_equivalence_part, S_equivalence_part_file_name, ".v", 0, 0); #endif set exactnesscheck_objects; exactnesscheck_objects.insert(renamed_conjunction_of_factors); exactnesscheck_objects.insert(disjunction_of_bad_symbols); exactnesscheck_objects.insert(S_equivalence_part); exactnesscheck_objects.insert(B_equivalence_part); exactnesscheck = createAnd(exactnesscheck_objects, pub_aig_manager); assert(exactnesscheck != NULL); // Give exactnesscheck to SAT-Solver #ifdef DEBUG_SKOLEM cout << endl << "Giving exactnesscheck to SAT-Solver\n"; #endif #ifdef DEBUG_CEGAR cout << endl << "Giving exactnesscheck to SAT-Solver\n"; #endif #ifdef DETAILED_RECORD_KEEP unsigned long long int solver_ms; struct timeval solver_start_ms, solver_finish_ms; gettimeofday (&solver_start_ms, NULL); #endif // Give to SAT-Solver and get unsat / sat with model unsigned long long int cnf_time; int formula_size; unsigned long long int simplification_time; bool result_of_exactnesscheck = isSat(pub_aig_manager, exactnesscheck, Model_of_ExactnessCheck, cnf_time, formula_size, simplification_time); #ifdef DETAILED_RECORD_KEEP gettimeofday (&solver_finish_ms, NULL); solver_ms = solver_finish_ms.tv_sec * 1000 + solver_finish_ms.tv_usec / 1000; solver_ms -= solver_start_ms.tv_sec * 1000 + solver_start_ms.tv_usec / 1000; cout << "\nsolver finished in " << solver_ms << " milliseconds\n"; total_time_in_smt_solver = total_time_in_smt_solver + solver_ms; total_time_in_exactness_checking_in_cegar = total_time_in_exactness_checking_in_cegar + solver_ms; number_of_exactness_checking_in_cegar++; #endif #ifdef RECORD_KEEP fprintf(record_fp, "\n\n%d\t%llu(%llu,%llu)(%d)\t", cegar_iteration_number, solver_ms, cnf_time, simplification_time, formula_size); fclose(record_fp); #endif #ifdef DEBUG_SKOLEM displayModelFromSATSolver(Model_of_ExactnessCheck); cout << endl << "result_of_exactnesscheck = " << result_of_exactnesscheck << endl; #endif #ifdef DEBUG_CEGAR cout << endl << "result_of_exactnesscheck = " << result_of_exactnesscheck << endl; #endif if(!result_of_exactnesscheck) // ExactnessCheck unsat i.e. skolem functions exact { return true; } else // skolem functions inexact { return false; } } void AIGBasedSkolem::findSkolemFunctionsToRecompute(set &skolem_functions_changed, set &skolem_functions_to_recompute) { skolem_functions_to_recompute = skolem_functions_changed; while(true) { set skolem_functions_sensitive; findSensitiveSkolemFunctions(skolem_functions_changed, skolem_functions_sensitive); if(skolem_functions_sensitive.empty()) // no more sensitive skolem functions { break; } set new_skolem_functions_to_recompute; set_union(skolem_functions_to_recompute.begin(), skolem_functions_to_recompute.end(), skolem_functions_sensitive.begin(), skolem_functions_sensitive.end(),inserter(new_skolem_functions_to_recompute, new_skolem_functions_to_recompute.begin())); skolem_functions_to_recompute = new_skolem_functions_to_recompute; skolem_functions_changed = skolem_functions_sensitive; } } void AIGBasedSkolem::findSensitiveSkolemFunctions(set &skolem_functions_changed, set &skolem_functions_sensitive) { skolem_functions_sensitive.clear(); for(set::iterator skolem_functions_changed_it = skolem_functions_changed.begin(); skolem_functions_changed_it != skolem_functions_changed.end(); skolem_functions_changed_it++) { int skolem_function_changed = *skolem_functions_changed_it; map >::iterator sensitivity_list_it = sensitivity_list.find(skolem_function_changed); if(sensitivity_list_it != sensitivity_list.end()) { set skolem_functions_sensitive_to_skolem_function_changed = sensitivity_list_it->second; set new_skolem_functions_sensitive; set_union(skolem_functions_sensitive.begin(), skolem_functions_sensitive.end(), skolem_functions_sensitive_to_skolem_function_changed.begin(), skolem_functions_sensitive_to_skolem_function_changed.end(),inserter(new_skolem_functions_sensitive, new_skolem_functions_sensitive.begin())); skolem_functions_sensitive = new_skolem_functions_sensitive; } } } Aig_Obj_t* AIGBasedSkolem::computeQuantifierEliminatedResultUsingSkolemFunction(int var_to_elim_index, Aig_Obj_t* skolem_function) { assert(skolem_function != NULL); // QuantifierEliminatedResult = (conjunction of factors with variable) with variable substituted // by the skolem function set QuantifierEliminatedResult_components; for(set::iterator factor_it = FactorsWithVariable.begin(); factor_it != FactorsWithVariable.end(); factor_it++) { int factor_index = *factor_it; #ifdef DEBUG_SKOLEM cout << "\nfactor_index = " << factor_index << endl; #endif Aig_Obj_t* factor = searchOneDimensionalMatrix(FactorMatrix, number_of_factors, factor_index); assert(factor != NULL); Aig_Obj_t* QuantifierEliminatedResult_component = replaceVariableByFormula(factor, var_to_elim_index, skolem_function); assert(QuantifierEliminatedResult_component != NULL); QuantifierEliminatedResult_components.insert(QuantifierEliminatedResult_component); }// for each factor ends here //cout << "\nCreating QuantifierEliminatedResult" << endl; Aig_Obj_t* QuantifierEliminatedResult; if(QuantifierEliminatedResult_components.size() == 0) // we should return true in this case { QuantifierEliminatedResult = createTrue(pub_aig_manager); assert(QuantifierEliminatedResult != NULL); } else { QuantifierEliminatedResult = createAnd(QuantifierEliminatedResult_components, pub_aig_manager); assert(QuantifierEliminatedResult != NULL); } //cout << "\nQuantifierEliminatedResult created" << endl; #ifdef DETAILED_RECORD_KEEP size_of_quantified_result_in_bdd_like_scheme = computeSize(QuantifierEliminatedResult, pub_aig_manager); cout << "\nSize of QuantifierEliminatedResult is " << size_of_quantified_result_in_bdd_like_scheme << endl; #endif #ifdef DEBUG_SKOLEM writeFormulaToFile(pub_aig_manager, QuantifierEliminatedResult, "QuantifierEliminatedResult", ".v", var_to_elim_index, 0); #endif return QuantifierEliminatedResult; } Aig_Obj_t* AIGBasedSkolem::computeBetaCombined(int var_to_elim_index) { // Let us compute beta_combined_{var_to_elim_index} // Suppose i = var_to_elim_index // i.e. we need to compute beta_combined_{i} // beta_combined_{i} = disjunction of beta_combined_components set beta_combined_components; #ifdef DEBUG_SKOLEM cout << "\ncomputing components of beta_combined\n"; #endif #ifdef PRINT_VERY_DETAILED_RECORDS_ON_SCREEN cout << "\ncomputing components of beta_combined\n"; #endif for(set::iterator factor_it = FactorsWithVariable.begin(); factor_it != FactorsWithVariable.end(); factor_it++) { int factor_index = *factor_it; #ifdef DEBUG_SKOLEM cout << "\nfactor_index = " << factor_index << endl; #endif // Suppose j = factor_index // Each beta_combined_component_i_j is the conjunction of // beta_i_j and all_agree_with_i_j Aig_Obj_t* beta_i_j; beta_i_j = computeBeta(var_to_elim_index, factor_index); assert(beta_i_j != NULL); #ifdef DEBUG_SKOLEM writeFormulaToFile(pub_aig_manager, beta_i_j, "beta", ".v", var_to_elim_index, factor_index); #endif // all_agree_with_i_j = conjunction of all_agree_with_components Aig_Obj_t* all_agree_with_i_j; set all_agree_with_components; #ifdef DEBUG_SKOLEM cout << "\nCreating all_agree_with_i_j" << endl; #endif for(set::iterator agree_it = FactorsWithVariable.begin(); agree_it != FactorsWithVariable.end(); agree_it++) { int agree_index = *agree_it; #ifdef DEBUG_SKOLEM cout << "\nagree_index = " << agree_index << endl; #endif // Suppose k = agree_index if(factor_index == agree_index) // j == k; no need to consider { #ifdef DEBUG_SKOLEM cout << "\nfactor_index == agree_index; no need to consider" << endl; #endif continue; } #ifdef DEBUG_SKOLEM cout << "\nfactor_index != agree_index" << endl; #endif Aig_Obj_t* beta_i_k; beta_i_k = computeBeta(var_to_elim_index, agree_index); assert(beta_i_k != NULL); #ifdef DEBUG_SKOLEM writeFormulaToFile(pub_aig_manager, beta_i_k, "beta", ".v", var_to_elim_index, agree_index); #endif Aig_Obj_t* gamma_i_k; gamma_i_k = computeGamma(var_to_elim_index, agree_index); assert(gamma_i_k != NULL); #ifdef DEBUG_SKOLEM writeFormulaToFile(pub_aig_manager, gamma_i_k, "gamma", ".v", var_to_elim_index, agree_index); #endif Aig_Obj_t* all_agree_with_component = createOr(beta_i_k, gamma_i_k, pub_aig_manager); assert(all_agree_with_component != NULL); #ifdef DEBUG_SKOLEM writeFormulaToFile(pub_aig_manager, all_agree_with_component, "all_agree_with_component", ".v", var_to_elim_index, agree_index); #endif all_agree_with_components.insert(all_agree_with_component); } // for each agree factor ends here // computing all_agree_with_i_j // recall that all_agree_with_i_j = conjunction of all_agree_with_components if(all_agree_with_components.size() == 0) { all_agree_with_i_j = NULL; #ifdef DEBUG_SKOLEM cout << "\nall_agree_with_i_j = NULL" << endl; #endif } else { all_agree_with_i_j = createAnd(all_agree_with_components, pub_aig_manager); assert(all_agree_with_i_j != NULL); #ifdef DEBUG_SKOLEM writeFormulaToFile(pub_aig_manager, all_agree_with_i_j, "all_agree_with_i_j", ".v", var_to_elim_index, factor_index); #endif } // recall that beta_combined_component_i_j is the conjunction of // beta_i_j and all_agree_with_i_j Aig_Obj_t* beta_combined_component; if(all_agree_with_i_j == NULL) { beta_combined_component = beta_i_j; } else { beta_combined_component = createAnd(beta_i_j, all_agree_with_i_j, pub_aig_manager); assert(beta_combined_component != NULL); } #ifdef DEBUG_SKOLEM writeFormulaToFile(pub_aig_manager, beta_combined_component, "beta_combined_component", ".v", var_to_elim_index, factor_index); cout << "\nbeta_combined_component[" << var_to_elim_index << ", " << factor_index << "] obtained\n"; #endif beta_combined_components.insert(beta_combined_component); }// for each factor ends here // recall that beta_combined = disjunction of beta_combined_components Aig_Obj_t* beta_combined; if(beta_combined_components.size() == 0) // we should return false in this case (as per defn. of beta) { beta_combined = createFalse(pub_aig_manager); assert(beta_combined != NULL); } else { beta_combined = createOr(beta_combined_components, pub_aig_manager); assert(beta_combined != NULL); } #ifdef DEBUG_SKOLEM writeFormulaToFile(pub_aig_manager, beta_combined, "beta_combined", ".v", var_to_elim_index, 0); #endif // Enter into matrix insertIntoOneDimensionalMatrix(BetaCombineds, number_of_vars_to_elim, var_to_elim_index, beta_combined, false); return beta_combined; } // function ends here Aig_Obj_t* AIGBasedSkolem::computeSkolemFunctionAsInterpolant(int var_to_elim_index) { #ifdef DEBUG_SKOLEM cout << "\ncomputing skolem function as interpolant\n"; #endif Aig_Obj_t* alpha = computeAlphaCombined(var_to_elim_index); assert(alpha != NULL); size_of_alpha_in_interpolant_computation_for_variable = computeSize(alpha, pub_aig_manager); Aig_Obj_t* beta = computeBetaCombined(var_to_elim_index); assert(beta != NULL); size_of_beta_in_interpolant_computation_for_variable = computeSize(beta, pub_aig_manager); unsigned long long int interpolate_ms; struct timeval interpolate_start_ms, interpolate_finish_ms; gettimeofday (&interpolate_start_ms, NULL); Aig_Obj_t* skolem_function; skolem_function = Interpolate(pub_aig_manager, alpha, beta); if(skolem_function == NULL) { cout << "\nInterpolation between alpha and beta fails!!See problem_alpha.v and problem_beta.v\n"; writeFormulaToFile(pub_aig_manager, alpha, "problem_alpha", ".v", 0, 0); writeFormulaToFile(pub_aig_manager, beta, "problem_beta", ".v", 0, 0); assert(false); } gettimeofday (&interpolate_finish_ms, NULL); interpolate_ms = interpolate_finish_ms.tv_sec * 1000 + interpolate_finish_ms.tv_usec / 1000; interpolate_ms -= interpolate_start_ms.tv_sec * 1000 + interpolate_start_ms.tv_usec / 1000; cout << "\ncomputeSkolemFunctionAsInterpolant finished in " << interpolate_ms << " milliseconds\n"; time_in_interpolant_computation_for_variable = interpolate_ms; total_time_in_interpolant_computation = total_time_in_interpolant_computation + time_in_interpolant_computation_for_variable; #ifdef PRINT_SKOLEM_FUNCTIONS_IN_INTERPOLATION writeFormulaToFile(pub_aig_manager, skolem_function, "skolem_function", ".v", var_to_elim_index, 0); #endif return skolem_function; } bool AIGBasedSkolem::checkIfSkolemFunctionsAreExact_using_ABC_with_Multi_Point_Connections(map &Model_of_ExactnessCheck, map &Refinement_Hint_To_Eliminate_This_CEX, list &VariablesToEliminate) { #ifdef RECORD_KEEP string record_file; record_file = logfile_prefix; record_file += "skolem_function_generation_details.txt"; FILE* record_fp = fopen(record_file.c_str(), "a+"); assert(record_fp != NULL); #endif if(cegar_iteration_number == 0) { Aig_Obj_t* epsilon_zero; // Create the dag for epsilon_zero: // F(X',Y) \wedge (B1\vee ... \vee B_n \vee B_{n+1}) \wedge // (B_1 = bad_set_1) \wedge ... \wedge (B_n = bad_set_n) \wedge (B_{n+1} = bad_set_{n+1}) \wedge // (x_1 = psi_1) \wedge ... \wedge (x_n = psi_n) // dag for F(X',Y) is already created in renamed_conjunction_of_factors // dag for (B1\vee ... \vee B_n \vee B_{n+1}) is already created in disjunction_of_bad_symbols // Let's first create dag for (B_1 = bad_set_1) \wedge ... \wedge (B_n = bad_set_n) \wedge (B_{n+1} = bad_set_{n+1}) set B_equivalence_objects; for(int bad_location_index = 1; bad_location_index <= number_of_vars_to_elim+1; bad_location_index++) { // Let bad_location_index be i // Obtaining dag for bad_set_i Aig_Obj_t* bad_set_obj; bad_set_obj = searchOneDimensionalMatrix(BadSets, number_of_vars_to_elim+1, bad_location_index); assert(bad_set_obj != NULL); // Obtaining dag for B_i map::iterator B_i_index_to_B_i_object_map_iterator = B_i_index_to_B_i_object_map.find(bad_location_index); assert(B_i_index_to_B_i_object_map_iterator != B_i_index_to_B_i_object_map.end()); Aig_Obj_t* B_obj = B_i_index_to_B_i_object_map_iterator->second; Aig_Obj_t* B_equivalence_i = createEquivalence(bad_set_obj, B_obj, pub_aig_manager); B_equivalence_objects.insert(B_equivalence_i); } assert(!B_equivalence_objects.empty()); B_equivalence_part = createAnd(B_equivalence_objects, pub_aig_manager); assert(B_equivalence_part != NULL); // Let's create dag for (x_1 = psi_1) \wedge ... \wedge (x_n = psi_n) Aig_Obj_t* S_equivalence_part; set S_equivalence_objects; for(int var_to_elim_index = 1; var_to_elim_index <= number_of_vars_to_elim; var_to_elim_index++) { // obtaining dag for x_i string var_to_elim = searchVarIndexToVarNameMap(var_index_to_var_name_map, var_to_elim_index); map::iterator Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it = Ci_to_eliminate_name_to_Ci_to_eliminate_object_map.find(var_to_elim); assert(Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it != Ci_to_eliminate_name_to_Ci_to_eliminate_object_map.end()); Aig_Obj_t* var_to_elim_obj = Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it->second; // obtaining \psi_i Aig_Obj_t* skolem_function; if(use_incremental_sat_solving) { skolem_function = searchOneDimensionalMatrix(SkolemFunctions, number_of_vars_to_elim, var_to_elim_index); assert(skolem_function != NULL); // initialize Z_variable_counter[var_to_elim_index] to 0 Z_variable_counter.insert(make_pair(var_to_elim_index, 0)); int z_i_count = Z_variable_counter[var_to_elim_index]; // 0 here string z_i_string = obtainZVariableString(var_to_elim_index, z_i_count); // obtain the string Z_{var_to_elim_index}_0 // check if object for z_i_string is already existing; if yes return it; otherwise create, // update temporary_variable_for_incremental_solving_to_object_map and return Aig_Obj_t* z_i_object = obtainObjectOfTemporaryVariableForIncrementalSolving(z_i_string); assert(z_i_object != NULL); Aig_Obj_t* alpha_combined_i; alpha_combined_i = searchOneDimensionalMatrix(AlphaCombineds, number_of_vars_to_elim, var_to_elim_index); assert(alpha_combined_i != NULL); Aig_Obj_t* z_i_increment = createOr(alpha_combined_i, z_i_object, pub_aig_manager); assert(z_i_increment != NULL); skolem_function = createAnd(skolem_function, z_i_increment, pub_aig_manager); assert(skolem_function != NULL); } else { skolem_function = searchOneDimensionalMatrix(SkolemFunctions, number_of_vars_to_elim, var_to_elim_index); } assert(skolem_function != NULL); Aig_Obj_t* S_equivalence_i = createEquivalence(skolem_function, var_to_elim_obj, pub_aig_manager); S_equivalence_objects.insert(S_equivalence_i); } assert(!S_equivalence_objects.empty()); S_equivalence_part = createAnd(S_equivalence_objects, pub_aig_manager); assert(S_equivalence_part != NULL); #ifdef DEBUG_SKOLEM string B_equivalence_part_file_name = benchmark_name_without_extension; B_equivalence_part_file_name += "_B_equivalence_part"; string S_equivalence_part_file_name = benchmark_name_without_extension; S_equivalence_part_file_name += "_S_equivalence_part"; cout << "\nB_equivalence_part computed\n"; cout << "\nS_equivalence_part computed\n"; writeFormulaToFile(pub_aig_manager, B_equivalence_part, B_equivalence_part_file_name, ".v", 0, 0); writeFormulaToFile(pub_aig_manager, S_equivalence_part, S_equivalence_part_file_name, ".v", 0, 0); #endif set epsilon_zero_objects; epsilon_zero_objects.insert(renamed_conjunction_of_factors); epsilon_zero_objects.insert(disjunction_of_bad_symbols); epsilon_zero_objects.insert(S_equivalence_part); epsilon_zero_objects.insert(B_equivalence_part); epsilon_zero = createAnd(epsilon_zero_objects, pub_aig_manager); assert(epsilon_zero != NULL); if(use_incremental_sat_solving) { // Identify labels of Z_1_0 ,..., Z_n_0 and // assume that they are true (in positive_assumptions_in_exactness_check) vector positive_assumptions_in_exactness_check; vector negative_assumptions_in_exactness_check; obtainAssumptionsInExactnessCheck(positive_assumptions_in_exactness_check, negative_assumptions_in_exactness_check, false, false); assert(negative_assumptions_in_exactness_check.size() == 0); assert(positive_assumptions_in_exactness_check.size() != 0); // Use incremental solver call #ifdef DEBUG_CEGAR cout << endl << "Adding clauses of epsilon_zero to SAT-Solver, and calling SAT-Solver\n"; #endif #ifdef DETAILED_RECORD_KEEP unsigned long long int solver_ms; struct timeval solver_start_ms, solver_finish_ms; gettimeofday (&solver_start_ms, NULL); #endif // Give to SAT-Solver and get unsat / sat with model unsigned long long int cnf_time; int formula_size; unsigned long long int simplification_time; bool result_of_exactnesscheck = isExactnessCheckSatisfiable(pub_aig_manager, epsilon_zero, Model_of_ExactnessCheck, cnf_time, formula_size, simplification_time, positive_assumptions_in_exactness_check, negative_assumptions_in_exactness_check, pSat_for_exactness_check, IncrementalLabelTableForExactnessCheck, IncrementalLabelCountForExactnessCheck, Ci_name_to_Ci_label_mapForExactnessCheck, Ci_label_to_Ci_name_mapForExactnessCheck); #ifdef DETAILED_RECORD_KEEP gettimeofday (&solver_finish_ms, NULL); solver_ms = solver_finish_ms.tv_sec * 1000 + solver_finish_ms.tv_usec / 1000; solver_ms -= solver_start_ms.tv_sec * 1000 + solver_start_ms.tv_usec / 1000; cout << "\nsolver finished in " << solver_ms << " milliseconds\n"; total_time_in_smt_solver = total_time_in_smt_solver + solver_ms; total_time_in_exactness_checking_in_cegar = total_time_in_exactness_checking_in_cegar + solver_ms; number_of_exactness_checking_in_cegar++; #endif #ifdef RECORD_KEEP fprintf(record_fp, "\n\n%d\t%llu(%llu,%llu)(%d)\t", cegar_iteration_number, solver_ms, cnf_time, simplification_time, formula_size); fclose(record_fp); #endif #ifdef DEBUG_SKOLEM displayModelFromSATSolver(Model_of_ExactnessCheck); cout << endl << "result_of_exactnesscheck = " << result_of_exactnesscheck << endl; #endif removeTemporaryVariablesFromModel(Model_of_ExactnessCheck); #ifdef DEBUG_CEGAR cout << "\nModel after removing temporary variables\n"; displayModelFromSATSolver(Model_of_ExactnessCheck); cout << endl << "result_of_exactnesscheck = " << result_of_exactnesscheck << endl; #endif if(!result_of_exactnesscheck) // ExactnessCheck unsat i.e. skolem functions exact { return true; } else // skolem functions inexact { return false; } } else { // Use normal solver call // i.e. give epsilon_zero to solver #ifdef DEBUG_CEGAR cout << endl << "Giving epsilon_zero to SAT-Solver\n"; #endif #ifdef DETAILED_RECORD_KEEP unsigned long long int solver_ms; struct timeval solver_start_ms, solver_finish_ms; gettimeofday (&solver_start_ms, NULL); #endif // Give to SAT-Solver and get unsat / sat with model unsigned long long int cnf_time; int formula_size; unsigned long long int simplification_time; bool result_of_exactnesscheck = isSat(pub_aig_manager, epsilon_zero, Model_of_ExactnessCheck, cnf_time, formula_size, simplification_time); #ifdef DETAILED_RECORD_KEEP gettimeofday (&solver_finish_ms, NULL); solver_ms = solver_finish_ms.tv_sec * 1000 + solver_finish_ms.tv_usec / 1000; solver_ms -= solver_start_ms.tv_sec * 1000 + solver_start_ms.tv_usec / 1000; cout << "\nsolver finished in " << solver_ms << " milliseconds\n"; total_time_in_smt_solver = total_time_in_smt_solver + solver_ms; total_time_in_exactness_checking_in_cegar = total_time_in_exactness_checking_in_cegar + solver_ms; number_of_exactness_checking_in_cegar++; #endif #ifdef RECORD_KEEP fprintf(record_fp, "\n\n%d\t%llu(%llu,%llu)(%d)\t", cegar_iteration_number, solver_ms, cnf_time, simplification_time, formula_size); fclose(record_fp); #endif #ifdef DEBUG_SKOLEM displayModelFromSATSolver(Model_of_ExactnessCheck); cout << endl << "result_of_exactnesscheck = " << result_of_exactnesscheck << endl; #endif #ifdef DEBUG_CEGAR cout << endl << "result_of_exactnesscheck = " << result_of_exactnesscheck << endl; #endif if(!result_of_exactnesscheck) // ExactnessCheck unsat i.e. skolem functions exact { return true; } else // skolem functions inexact { return false; } }// else of if(use_incremental_sat_solving) ends here } // if(cegar_iteration_number == 0) ends here else // if(cegar_iteration_number > 0) { Aig_Obj_t* epsilon_i; // for normal sat-solving Aig_Obj_t* delta_epsilon_i; // for incremental sat-solving set delta_epsilon_i_components; #ifdef ADDITIONAL_ASSERTION_CHECKS_INSIDE_CEGAR bool maximum_bad_location_from_counterexample_included = false; for(map::iterator hint_it = Refinement_Hint_To_Eliminate_This_CEX.begin(); hint_it != Refinement_Hint_To_Eliminate_This_CEX.end(); hint_it++) { int variable_index = hint_it->first; int bad_index = hint_it->second; cout << "\nThe refinement hint is:" << bad_index << " --> " << variable_index << endl; if(bad_index == maximum_bad_location_from_counterexample_in_this_iteration+1)//note that bad_index is bad_location + 1 { maximum_bad_location_from_counterexample_included = true; break; } } if(maximum_bad_location_from_counterexample_included) { cout << "\nMaximum bad index from counterexample " << maximum_bad_location_from_counterexample_in_this_iteration+1 << " is included in the hints\n"; } else { cout << "\nMaximum bad index from counterexample " << maximum_bad_location_from_counterexample_in_this_iteration+1 << " is not included in the hints\n"; assert(false); } #endif #ifdef RECORD_KEEP fprintf(record_fp, "\t"); #endif int number_of_literals_dropped_by_unsat_core = 0; bool value_based_scheme_is_used = false; for(map::iterator hint_it = Refinement_Hint_To_Eliminate_This_CEX.begin(); hint_it != Refinement_Hint_To_Eliminate_This_CEX.end(); hint_it++) { // 1. TAKE EACH REFINEMENT HINT #ifdef DEBUG_CEGAR cout << "\nSTEP-1. TAKE EACH REFINEMENT HINT\n"; #endif int variable_index = hint_it->first; int bad_index = hint_it->second; assert(bad_index < variable_index); #ifdef DEBUG_CEGAR cout << "\nThe refinement hint is: variable_index = " << variable_index << ", bad_index = " << bad_index << endl; #endif #ifdef RECORD_KEEP fprintf(record_fp, "%d-->%d,", bad_index, variable_index); #endif #ifdef ANALYZE_CEGAR string cegar_file = "cegar_details.txt"; FILE* cegar_fp = fopen(cegar_file.c_str(), "a+"); assert(cegar_fp != NULL); fprintf(cegar_fp, "\n\nThe refinement hint is: %d-->%d\n", bad_index, variable_index); fclose(cegar_fp); #endif // 2. UPDATE THE DATA-STRUCTURES #ifdef DEBUG_CEGAR cout << "\nSTEP-2. UPDATE THE DATA-STRUCTURES\n"; #endif // copy it to refinement_hints map >::iterator refinement_hint_it = refinement_hints.find(variable_index); if(refinement_hint_it == refinement_hints.end()) // entry does not exist for variable_index { set bad_indices; bad_indices.insert(bad_index); refinement_hints.insert(make_pair(variable_index, bad_indices)); } else // entry exists for variable_index { (refinement_hint_it->second).insert(bad_index); } #ifdef DEBUG_CEGAR cout << "\nThe refinement hint to eliminate this counterexample is copied into refinement hints\n"; showMap(refinement_hints, "refinement_hints"); #endif // Find the connections to be updated set connections_to_update; findConnectionsToUpdate(connections_to_update, variable_index, bad_index); if(connections_to_update.size() > threshold_for_value_based_scheme_when_multi_point_connections_deteorates && use_values_in_refinement_when_multi_point_connections_deteorates) { value_based_scheme_is_used = true; #ifdef ANALYZE_CEGAR cegar_file = "cegar_details.txt"; cegar_fp = fopen(cegar_file.c_str(), "a+"); assert(cegar_fp != NULL); printSet(connections_to_update, "connections_to_update", cegar_fp); fprintf(cegar_fp, "\n\nconnections_to_update.size() > %d\n", threshold_for_value_based_scheme_when_multi_point_connections_deteorates); fclose(cegar_fp); #endif // 3. UPDATE THE SKOLEM FUNCTION AT variable_index #ifdef DEBUG_CEGAR cout << "\nSTEP-3. UPDATE THE SKOLEM FUNCTION AT " << variable_index << endl; #endif Aig_Obj_t* R_i_j_dag; if(false)//using explicit values { // create R_i_j_dag // R_i_j_dag is negation of conjunction // of literals as per values_of_variables_from_var[variable_index] // and values_of_Y_variables // creating the x_replacement_map #ifdef DEBUG_CEGAR cout << "\ncreating x_replacement_map" << endl; #endif map x_replacement_map; map >::iterator values_of_variables_from_var_it = values_of_variables_from_var.find(variable_index); assert(values_of_variables_from_var_it != values_of_variables_from_var.end()); x_replacement_map = values_of_variables_from_var_it->second; #ifdef DEBUG_CEGAR cout << "\nx_replacement_map created\n"; showMap(x_replacement_map, "x_replacement_map"); cout << "\nvalues_of_Y_variables\n"; showYMap(); #endif Aig_Obj_t* bad_set_obj_after_replacements = createAssignment(x_replacement_map); assert(bad_set_obj_after_replacements != NULL); // Obtain R_i_j_dag = ~bad_set_obj_after_replacements R_i_j_dag = createNot(bad_set_obj_after_replacements, pub_aig_manager); assert(R_i_j_dag != NULL); // avoid unwanted deletion of R_i_j_dag Aig_Obj_t* R_i_j_dag_CO = Aig_ObjCreateCo( pub_aig_manager, R_i_j_dag ); assert(R_i_j_dag_CO != NULL); }//if(false) else { // create R_i_j_dag // R_i_j_dag = (conjunction of alpha's and negation of psi's of variables // from bad to var+1 depending on the values of the variables // => ~bad at bad location) with replacement // as per values_of_variables_from_bad_to_var) \wedge ~(values of // variables from var to the last variable) #ifdef DEBUG_CEGAR cout << "\ncreating replacement_map" << endl; #endif map replacement_map; map >::iterator values_of_variables_from_bad_to_var_it = values_of_variables_from_bad_to_var.find(variable_index); assert(values_of_variables_from_bad_to_var_it != values_of_variables_from_bad_to_var.end()); replacement_map = values_of_variables_from_bad_to_var_it->second; #ifdef DEBUG_CEGAR cout << "\nreplacement_map created\n"; showMap(replacement_map, "replacement_map"); #endif assert(replacement_map.size() > 0); #ifdef DEBUG_CEGAR cout << "\nrecomputing skolem function for variable at " << variable_index << endl; #endif set antecedent_components; for(int antecedent_index = bad_index; antecedent_index < variable_index; antecedent_index++) { map::iterator replacement_map_it = replacement_map.find(antecedent_index); assert(replacement_map_it != replacement_map.end()); int value_of_variable_at_antecedent_index = replacement_map_it->second; Aig_Obj_t* antecedent_component; if(value_of_variable_at_antecedent_index == 1) { // antecedent_component is alpha_combined at antecedent_index #ifdef DEBUG_CEGAR cout << "\nantecedent_component is alpha_combined at " << antecedent_index << endl; #endif antecedent_component = searchOneDimensionalMatrix(AlphaCombineds, number_of_vars_to_elim, antecedent_index); assert(antecedent_component != NULL); #ifdef DEBUG_CEGAR cout << "\nsize of antecedent_component is " << computeSize(antecedent_component, pub_aig_manager) << endl; #endif } else if(value_of_variable_at_antecedent_index == 0) { #ifdef DEBUG_CEGAR cout << "\nantecedent_component is negation of skolem function at " << antecedent_index << endl; #endif // antecedent_component is negation of skolem function at antecedent_index antecedent_component = searchOneDimensionalMatrix(SkolemFunctions, number_of_vars_to_elim, antecedent_index); assert(antecedent_component != NULL); antecedent_component = createNot(antecedent_component, pub_aig_manager); assert(antecedent_component != NULL); #ifdef DEBUG_CEGAR cout << "\nsize of antecedent_component is " << computeSize(antecedent_component, pub_aig_manager) << endl; #endif } else { assert(false); } antecedent_components.insert(antecedent_component); } assert(!antecedent_components.empty()); Aig_Obj_t* antecedent = createAnd(antecedent_components, pub_aig_manager); assert(antecedent != NULL); #ifdef DEBUG_CEGAR cout << "\nantecedent created\n"; cout << "\nsize of antecedent is " << computeSize(antecedent, pub_aig_manager) << endl; #endif #ifdef DEBUG_SKOELM string antecedent_file_name = benchmark_name_without_extension; antecedent_file_name += "_antecedent_"; writeFormulaToFile(pub_aig_manager, antecedent, antecedent_file_name, ".v", bad_index, variable_index); #endif Aig_Obj_t* consequent; consequent = searchOneDimensionalMatrix(BadSets, number_of_vars_to_elim, bad_index); assert(consequent != NULL); consequent = createNot(consequent, pub_aig_manager); assert(consequent != NULL); #ifdef DEBUG_CEGAR cout << "\nconsequent created\n"; cout << "\nsize of consequent is " << computeSize(consequent, pub_aig_manager) << endl; #endif #ifdef DEBUG_SKOELM string consequent_file_name = benchmark_name_without_extension; consequent_file_name += "_consequent_"; writeFormulaToFile(pub_aig_manager, consequent, consequent_file_name, ".v", bad_index, variable_index); #endif Aig_Obj_t* implication; implication = createImplication(antecedent, consequent, pub_aig_manager); assert(implication != NULL); #ifdef DEBUG_CEGAR cout << "\nimplication created\n"; cout << "\nsize of implication is " << computeSize(implication, pub_aig_manager) << endl; #endif #ifdef DEBUG_SKOELM string implication_file_name = benchmark_name_without_extension; implication_file_name += "_implication_"; writeFormulaToFile(pub_aig_manager, implication, implication_file_name, ".v", bad_index, variable_index); #endif Aig_Obj_t* R_i_j_dag_part1 = replaceVariablesByConstants(implication, replacement_map); assert(R_i_j_dag_part1 != NULL); // avoid unwanted deletion of R_i_j_dag_part1 inside createUnsatCoreBasedAssignment Aig_Obj_t* R_i_j_dag_part1_CO = Aig_ObjCreateCo( pub_aig_manager, R_i_j_dag_part1 ); assert(R_i_j_dag_part1_CO != NULL); #ifdef DEBUG_CEGAR cout << "\nR_i_j_dag_part1 created\n"; cout << "\nsize of R_i_j_dag_part1 is " << computeSize(R_i_j_dag_part1, pub_aig_manager) << endl; #endif #ifdef DEBUG_SKOELM string R_i_j_dag_part1_file_name = benchmark_name_without_extension; R_i_j_dag_part1_file_name += "_R_i_j_dag_part1_"; writeFormulaToFile(pub_aig_manager, R_i_j_dag_part1, R_i_j_dag_part1_file_name, ".v", bad_index, variable_index); #endif // create R_i_j_dag_part2 // R_i_j_dag_part2 is negation of conjunction // of literals as per values_of_variables_from_var[variable_index] // and values_of_Y_variables // creating the x_replacement_map #ifdef DEBUG_CEGAR cout << "\ncreating x_replacement_map" << endl; #endif map x_replacement_map; map >::iterator values_of_variables_from_var_it = values_of_variables_from_var.find(variable_index); assert(values_of_variables_from_var_it != values_of_variables_from_var.end()); x_replacement_map = values_of_variables_from_var_it->second; #ifdef DEBUG_SKOELM cout << "\nx_replacement_map created\n"; showMap(x_replacement_map, "x_replacement_map"); cout << "\nvalues_of_Y_variables\n"; showYMap(); #endif Aig_Obj_t* R_i_j_dag_part2; if(use_unsat_core_in_refinement) { R_i_j_dag_part2 = createUnsatCoreBasedAssignment(x_replacement_map, variable_index, number_of_literals_dropped_by_unsat_core); } else { R_i_j_dag_part2 = createAssignment(x_replacement_map); } assert(R_i_j_dag_part2 != NULL); R_i_j_dag_part2 = createNot(R_i_j_dag_part2, pub_aig_manager); assert(R_i_j_dag_part2 != NULL); // avoid unwanted deletion of R_i_j_dag_part2 inside createUnsatCoreBasedAssignment Aig_Obj_t* R_i_j_dag_part2_CO = Aig_ObjCreateCo( pub_aig_manager, R_i_j_dag_part2 ); assert(R_i_j_dag_part2_CO != NULL); #ifdef DEBUG_CEGAR cout << "\nR_i_j_dag_part2 created\n"; cout << "\nsize of R_i_j_dag_part2 is " << computeSize(R_i_j_dag_part2, pub_aig_manager) << endl; #endif #ifdef DEBUG_CEGAR string R_i_j_dag_part2_file_name = benchmark_name_without_extension; R_i_j_dag_part2_file_name += "_R_i_j_dag_part2_"; writeFormulaToFile(pub_aig_manager, R_i_j_dag_part2, R_i_j_dag_part2_file_name, ".v", bad_index, variable_index); #endif // Obtain R_i_j_dag = R_i_j_dag_part1 \wedge R_i_j_dag_part2 R_i_j_dag = createAnd(R_i_j_dag_part1, R_i_j_dag_part2, pub_aig_manager); assert(R_i_j_dag != NULL); // avoid unwanted deletion of R_i_j_dag inside createUnsatCoreBasedAssignment Aig_Obj_t* R_i_j_dag_CO = Aig_ObjCreateCo( pub_aig_manager, R_i_j_dag ); assert(R_i_j_dag_CO != NULL); #ifdef DEBUG_CEGAR analyzeReasonBehindMismatch(bad_index, variable_index, replacement_map, x_replacement_map); #endif } Aig_Obj_t* current_skolem_function; current_skolem_function = searchOneDimensionalMatrix(SkolemFunctions, number_of_vars_to_elim, variable_index); assert(current_skolem_function != NULL); Aig_Obj_t* new_skolem_function; // The new part in the skolem function is // (alpha_i \vee ~Bad after substitutions) Aig_Obj_t* alpha_combined; alpha_combined = searchOneDimensionalMatrix(AlphaCombineds, number_of_vars_to_elim, variable_index); assert(alpha_combined != NULL); Aig_Obj_t* new_component_in_skolem_function; new_component_in_skolem_function = createOr(alpha_combined, R_i_j_dag, pub_aig_manager); assert(new_component_in_skolem_function != NULL); new_skolem_function = createAnd(current_skolem_function, new_component_in_skolem_function, pub_aig_manager); assert(new_skolem_function != NULL); if(new_skolem_function != current_skolem_function) // skolem function is changed { Aig_Obj_t* new_skolem_function_CO = Aig_ObjCreateCo( pub_aig_manager, new_skolem_function ); assert(new_skolem_function_CO != NULL); #ifdef DEBUG_CEGAR cout << "\nSkolem function for " << variable_index << " is changed\n"; cout << "\nsize of Skolem function is " << computeSize(new_skolem_function, pub_aig_manager) << endl; #endif // insert the new skolem function insertIntoOneDimensionalMatrix(SkolemFunctions, number_of_vars_to_elim, variable_index, new_skolem_function, true); #ifdef PRINT_SKOLEM_FUNCTIONS string skolem_function_file_name = benchmark_name_without_extension; skolem_function_file_name += "_skolem_function"; writeFormulaToFile(pub_aig_manager, new_skolem_function, skolem_function_file_name, ".v", variable_index, cegar_iteration_number); #endif } else { #ifdef DEBUG_CEGAR cout << "\nSkolem function for " << variable_index << " is not changed\n"; #endif #ifdef PRINT_SKOLEM_FUNCTIONS string skolem_function_file_name = benchmark_name_without_extension; skolem_function_file_name += "_skolem_function"; writeFormulaToFile(pub_aig_manager, new_skolem_function, skolem_function_file_name, ".v", variable_index, cegar_iteration_number); #endif } // skolem function at variable_index updated if(use_incremental_sat_solving) { int present_z_j_k_count = Z_variable_counter[variable_index]; int next_z_j_k_count = present_z_j_k_count + 1; Z_variable_counter[variable_index] = next_z_j_k_count; string present_z_j_k_string = obtainZVariableString(variable_index, present_z_j_k_count); // obtain the string Z_{variable_index}_{present_z_j_k_count} Aig_Obj_t* present_z_j_k_object = obtainExistingObjectOfTemporaryVariableForIncrementalSolving(present_z_j_k_string); assert(present_z_j_k_object != NULL); string next_z_j_k_string = obtainZVariableString(variable_index, next_z_j_k_count); // obtain the string Z_{variable_index}_{next_z_j_k_count} Aig_Obj_t* next_z_j_k_object = obtainObjectOfTemporaryVariableForIncrementalSolving(next_z_j_k_string); assert(next_z_j_k_object != NULL); Aig_Obj_t* R_i_j_increment = createEquivalence(present_z_j_k_object, createAnd(R_i_j_dag, next_z_j_k_object, pub_aig_manager), pub_aig_manager); assert(R_i_j_increment != NULL); // avoid unwanted deletion of R_i_j_increment Aig_Obj_t* R_i_j_increment_CO = Aig_ObjCreateCo( pub_aig_manager, R_i_j_increment ); assert(R_i_j_increment_CO != NULL); // add CNF of R_i_j_increment into solver pSat_for_exactness_check delta_epsilon_i_components.insert(R_i_j_increment); #ifdef DEBUG_CEGAR cout << endl << next_z_j_k_string << " is created\n"; #endif #ifdef DEBUG_CEGAR string R_i_j_file_name = benchmark_name_without_extension; R_i_j_file_name += "_R_increment_"; writeFormulaToFile(pub_aig_manager, R_i_j_increment, R_i_j_file_name, ".v", bad_index, variable_index); #endif #ifdef ANALYZE_CEGAR cegar_fp = fopen(cegar_file.c_str(), "a+"); assert(cegar_fp != NULL); int size_of_R_i_j_dag = computeSize(R_i_j_dag, pub_aig_manager); int size_of_R_i_j_increment = computeSize(R_i_j_increment, pub_aig_manager); fprintf(cegar_fp, "\nSize of R_%d_%d_dag = %d\tSize of R_%d_%d_increment = %d", bad_index, variable_index, size_of_R_i_j_dag, bad_index, variable_index, size_of_R_i_j_increment); fclose(cegar_fp); #endif } // 4. UPDATE THE CONNECTIONS // Note that we are changing the skolem function at variable_index // Hence we need to update the connections starting at // the skolem function of variable_index #ifdef DEBUG_CEGAR cout << "\nSTEP-4. UPDATE THE CONNECTIONS\n"; #endif connections_to_update.clear(); map >::iterator connections_starting_at_skolem_function_it = connections_starting_at_skolem_function.find(variable_index); if(connections_starting_at_skolem_function_it != connections_starting_at_skolem_function.end()) // there are some connections starting at variable_index { connections_to_update = connections_starting_at_skolem_function_it->second; } #ifdef DEBUG_CEGAR showSet(connections_to_update, "connections_to_update"); #endif #ifdef ANALYZE_CEGAR number_of_connections_updated_in_iteration_in_connection_based_scheme = number_of_connections_updated_in_iteration_in_connection_based_scheme + connections_to_update.size(); #endif // Updating the connections for(set::iterator connections_to_update_it = connections_to_update.begin(); connections_to_update_it != connections_to_update.end(); connections_to_update_it++) { string connection_to_update = *connections_to_update_it; #ifdef DEBUG_CEGAR cout << "\nconnection_to_update = " << connection_to_update << endl; #endif map replacement_map_for_connection_to_update; // we can find the replacement map for connection_to_update using // sensitivity_list and dependency_list obtainReplacementMapForConnection(connection_to_update, replacement_map_for_connection_to_update); #ifdef DEBUG_CEGAR cout << "\nreplacement_map_for_connection_to_update created\n"; showMap(replacement_map_for_connection_to_update, "replacement_map_for_connection_to_update", pub_aig_manager, var_name_to_var_index_map); #endif int start_index_of_connection_to_update; int end_index_of_connection_to_update; findStartIndexAndEndIndexOfConnection(connection_to_update, start_index_of_connection_to_update, end_index_of_connection_to_update); assert(start_index_of_connection_to_update < end_index_of_connection_to_update); assert(start_index_of_connection_to_update == variable_index); // Let us now compute the dag for connection_to_update // connection_to_update is C_start_index_of_connection_to_update_...._end_index_of_connection_to_update // Expression for C_start_index_of_connection_to_update_...._end_index_of_connection_to_update is obtained as // skolem_function for start_index_of_connection_to_update with replacements as per replacement_map_for_connection_to_update // and x_end_index_of_connection_to_update replaced by 1 Aig_Obj_t* skolem_function_at_start_index; skolem_function_at_start_index = searchOneDimensionalMatrix(SkolemFunctions, number_of_vars_to_elim, start_index_of_connection_to_update); assert(skolem_function_at_start_index != NULL); Aig_Obj_t* skolem_function_after_replacements; if(replacement_map_for_connection_to_update.size() > 0) { skolem_function_after_replacements = replaceVariablesByFormulas(skolem_function_at_start_index, replacement_map_for_connection_to_update); assert(skolem_function_after_replacements != NULL); } else { skolem_function_after_replacements = skolem_function_at_start_index; } // we need to replace occurences of x_end_index_of_connection_to_update by true skolem_function_after_replacements = replaceVariableByConstant(skolem_function_after_replacements, end_index_of_connection_to_update, 1); assert(skolem_function_after_replacements != NULL); Aig_Obj_t* new_connection_dag = skolem_function_after_replacements; Aig_Obj_t* current_connection_dag; map::iterator Connections_it = Connections.find(connection_to_update); if(Connections_it == Connections.end()) // dag does not exist for connection_to_update { current_connection_dag = NULL; } else { current_connection_dag = Connections_it->second; assert(current_connection_dag != NULL); } if(current_connection_dag != new_connection_dag) // connection_dag has changed { #ifdef DEBUG_CEGAR cout << "\nConnection dag for " << connection_to_update << " is changed\n"; #endif // avoid unwanted deletion of new_connection_dag Aig_Obj_t* new_connection_dag_CO = Aig_ObjCreateCo( pub_aig_manager, new_connection_dag ); assert(new_connection_dag_CO != NULL); // insert it first Connections[connection_to_update] = new_connection_dag; #ifdef PRINT_SKOLEM_FUNCTIONS string connection_file_name = benchmark_name_without_extension; connection_file_name += connection_to_update; writeFormulaToFile(pub_aig_manager, new_connection_dag, connection_file_name, ".v", 0, 0); #endif } else { #ifdef DEBUG_CEGAR cout << "\nConnection dag for " << connection_to_update << " is not changed\n"; #endif } if(use_incremental_sat_solving) { // create dag connection_to_update = ite(control-variable, new_connection_dag, symbol) // connection_to_update is the connection we have map::iterator I_variable_counter_it = I_variable_counter.find(connection_to_update); Aig_Obj_t* present_connection_object; int next_connection_count; string present_connection_string; if(I_variable_counter_it == I_variable_counter.end()) { next_connection_count = 0; I_variable_counter.insert(make_pair(connection_to_update, next_connection_count)); present_connection_object = obtainObjectOfConnectionString(connection_to_update); assert(present_connection_object != NULL); present_connection_string = connection_to_update; // just for debugging } else { int present_connection_count = I_variable_counter_it->second; next_connection_count = present_connection_count + 1; I_variable_counter[connection_to_update] = next_connection_count; present_connection_string = obtainTVariableString(present_connection_count, connection_to_update); // obtain the string T_{present_connection_count}_{connection_to_update} present_connection_object = obtainExistingObjectOfTemporaryVariableForIncrementalSolving(present_connection_string); assert(present_connection_object != NULL); } string next_connection_string = obtainTVariableString(next_connection_count, connection_to_update); // obtain the string T_{next_connection_count}_{connection_to_update} Aig_Obj_t* next_connection_object = obtainObjectOfTemporaryVariableForIncrementalSolving(next_connection_string); assert(next_connection_object != NULL); string next_control_string = obtainIVariableString(next_connection_count, connection_to_update); // obtain the string I_{next_connection_count}_{connection_to_update} Aig_Obj_t* next_control_object = obtainObjectOfTemporaryVariableForIncrementalSolving(next_control_string); assert(next_control_object != NULL); Aig_Obj_t* connection_increment = createEquivalence(present_connection_object, createIte(next_control_object, new_connection_dag, next_connection_object, pub_aig_manager), pub_aig_manager); assert(connection_increment != NULL); // avoid unwanted deletion of connection_increment Aig_Obj_t* connection_increment_CO = Aig_ObjCreateCo( pub_aig_manager, connection_increment ); assert(connection_increment_CO != NULL); delta_epsilon_i_components.insert(connection_increment); #ifdef DEBUG_CEGAR cout << endl << present_connection_string << " created\n"; #endif #ifdef DEBUG_SKOLEM string present_connection_file_name = benchmark_name_without_extension; present_connection_file_name += present_connection_string; present_connection_file_name += "_increment_"; writeFormulaToFile(pub_aig_manager, connection_increment, present_connection_file_name, ".v", 0, 0); #endif #ifdef ANALYZE_CEGAR cegar_fp = fopen(cegar_file.c_str(), "a+"); assert(cegar_fp != NULL); int size_of_new_connection_dag = computeSize(new_connection_dag, pub_aig_manager); int size_of_connection_increment = computeSize(connection_increment, pub_aig_manager); fprintf(cegar_fp, "\nSize of %s_dag = %d\tSize of %s_increment = %d", connection_to_update.c_str(), size_of_new_connection_dag, connection_to_update.c_str(), size_of_connection_increment); fclose(cegar_fp); #endif }//if(use_incremental_sat_solving) ends here }// Updating the connections ends here }//if(use value based scheme) ends here else { // update the sensitivity list and dependency list for(int skolem_index = bad_index; skolem_index < variable_index; skolem_index++) { // variable_index is sensitive to skolem_index #ifdef DEBUG_SKOLEM cout << "\n" << variable_index << " is sensitive to " << skolem_index << endl; #endif map >::iterator sensitivity_list_it = sensitivity_list.find(skolem_index); if(sensitivity_list_it == sensitivity_list.end()) // entry does not exist for skolem_index { set sensitive_indices; sensitive_indices.insert(variable_index); sensitivity_list.insert(make_pair(skolem_index, sensitive_indices)); } else // entry exists for skolem_index { (sensitivity_list_it->second).insert(variable_index); } map >::iterator dependency_list_it = dependency_list.find(variable_index); if(dependency_list_it == dependency_list.end()) // entry does not exist for variable_index { set dependent_indices; dependent_indices.insert(skolem_index); dependency_list.insert(make_pair(variable_index, dependent_indices)); } else // entry exists for variable_index { (dependency_list_it->second).insert(skolem_index); } #ifdef DEBUG_SKOLEM cout << "\n" << variable_index << " -> " << skolem_index << " inserted into sensitivity_list and dependency_list\n"; #endif } #ifdef DEBUG_CEGAR cout << "\nSensitivity list updated\n"; showMap(sensitivity_list, "sensitivity_list"); #endif #ifdef DEBUG_CEGAR cout << "\nDependency list updated\n"; showMap(dependency_list, "dependency_list"); #endif // Updating the data-structures finished // 3. UPDATE THE SKOLEM FUNCTION AT variable_index #ifdef DEBUG_CEGAR cout << "\nSTEP-3. UPDATE THE SKOLEM FUNCTION AT " << variable_index << endl; #endif // creating the replacement_map #ifdef DEBUG_CEGAR cout << "\ncreating replacement_map" << endl; #endif map replacement_map; for(int subst_index = bad_index; subst_index <= variable_index-1; subst_index++) { // we need to replace occurences of x_subst_index by C_subst_index_variable_index // Getting the object for C_subst_index_variable_index string connection_string = "C_"; char subst_char[100]; sprintf(subst_char, "%d", subst_index); string subst_string(subst_char); connection_string += subst_string; connection_string += "_"; char variable_char[100]; sprintf(variable_char, "%d", variable_index); string variable_string(variable_char); connection_string += variable_string; #ifdef DEBUG_SKOLEM cout << "\nconnection_string = " << connection_string << endl; #endif Aig_Obj_t* connection_object; map::iterator connection_string_to_connection_object_map_it = connection_string_to_connection_object_map.find(connection_string); if(connection_string_to_connection_object_map_it != connection_string_to_connection_object_map.end()) // object for connection_string exists { #ifdef DEBUG_SKOLEM cout << "\nconnection_object exists for this connection_string" << endl; #endif connection_object = connection_string_to_connection_object_map_it->second; assert(connection_object != NULL); } else { // creating new connection #ifdef DEBUG_SKOLEM cout << "\ncreating connection_object for this connection_string" << endl; #endif connection_object = Aig_ObjCreateCi(pub_aig_manager); assert(connection_object != NULL); int connection_id = Aig_ObjId(connection_object); // no need to apply Aig_Regular() as connection_object is CI Ci_id_to_Ci_name_map.insert(make_pair(connection_id, connection_string)); Ci_name_to_Ci_number_map.insert(make_pair(connection_string, number_of_Cis)); connection_string_to_connection_object_map.insert(make_pair(connection_string, connection_object)); number_of_Cis++; } replacement_map.insert(make_pair(subst_index, connection_object)); }// for subst_index from bad_index to variable_index-1 ends here #ifdef DEBUG_CEGAR cout << "\nreplacement_map created\n"; showMap(replacement_map, "replacement_map", pub_aig_manager, var_name_to_var_index_map); #endif // recomputing skolem function for variable at variable_index // new skolem function for variable at variable_index is // old_skolem_function \wedge (~bad_set at bad_index with replacements as per replacement_map // and x_variable_index replaced by 1) #ifdef DEBUG_CEGAR cout << "\nrecomputing skolem function for variable at " << variable_index << endl; #endif Aig_Obj_t* bad_set_obj_at_bad_index; bad_set_obj_at_bad_index = searchOneDimensionalMatrix(BadSets, number_of_vars_to_elim, bad_index); assert(bad_set_obj_at_bad_index != NULL); Aig_Obj_t* bad_set_obj_after_replacements; if(replacement_map.size() > 0) { bad_set_obj_after_replacements = replaceVariablesByFormulas(bad_set_obj_at_bad_index, replacement_map); assert(bad_set_obj_after_replacements != NULL); } else { bad_set_obj_after_replacements = bad_set_obj_at_bad_index; } // we need to replace occurences of x_variable_index by true bad_set_obj_after_replacements = replaceVariableByConstant(bad_set_obj_after_replacements, variable_index, 1); assert(bad_set_obj_after_replacements != NULL); Aig_Obj_t* current_skolem_function; current_skolem_function = searchOneDimensionalMatrix(SkolemFunctions, number_of_vars_to_elim, variable_index); assert(current_skolem_function != NULL); Aig_Obj_t* new_skolem_function; // The new part in the skolem function is // (alpha_i \vee ~Bad after substitutions) Aig_Obj_t* alpha_combined; alpha_combined = searchOneDimensionalMatrix(AlphaCombineds, number_of_vars_to_elim, variable_index); assert(alpha_combined != NULL); Aig_Obj_t* new_component_in_skolem_function; new_component_in_skolem_function = createOr(alpha_combined, createNot(bad_set_obj_after_replacements, pub_aig_manager), pub_aig_manager); assert(new_component_in_skolem_function != NULL); new_skolem_function = createAnd(current_skolem_function, new_component_in_skolem_function, pub_aig_manager); assert(new_skolem_function != NULL); if(new_skolem_function != current_skolem_function) // skolem function is changed { #ifdef DEBUG_CEGAR cout << "\nSkolem function for " << variable_index << " is changed\n"; #endif Aig_Obj_t* new_skolem_function_CO = Aig_ObjCreateCo( pub_aig_manager, new_skolem_function ); assert(new_skolem_function_CO != NULL); // insert the new skolem function insertIntoOneDimensionalMatrix(SkolemFunctions, number_of_vars_to_elim, variable_index, new_skolem_function, true); #ifdef PRINT_SKOLEM_FUNCTIONS string skolem_function_file_name = benchmark_name_without_extension; skolem_function_file_name += "_skolem_function"; writeFormulaToFile(pub_aig_manager, new_skolem_function, skolem_function_file_name, ".v", variable_index, cegar_iteration_number); #endif } else { #ifdef DEBUG_CEGAR cout << "\nSkolem function for " << variable_index << " is not changed\n"; #endif #ifdef PRINT_SKOLEM_FUNCTIONS string skolem_function_file_name = benchmark_name_without_extension; skolem_function_file_name += "_skolem_function"; writeFormulaToFile(pub_aig_manager, new_skolem_function, skolem_function_file_name, ".v", variable_index, cegar_iteration_number); #endif } // skolem function at variable_index updated if(use_incremental_sat_solving) { // create dag (R_i_j = ~bad_set_obj_after_replacements) \wedge (Z_j_k = R_i_j \wedge Z_j_{k-1}) // Obtain string for R_i_j string R_i_j_string = obtainRVariableString(bad_index, variable_index); // obtain the string R_{bad_index}_{variable_index} // check if object for R_i_j_string is already existing; if yes return it; otherwise create, // update temporary_variable_for_incremental_solving_to_object_map and return Aig_Obj_t* R_i_j_object = obtainObjectOfTemporaryVariableForIncrementalSolving(R_i_j_string); assert(R_i_j_object != NULL); Aig_Obj_t* R_i_j_dag = createNot(bad_set_obj_after_replacements, pub_aig_manager); assert(R_i_j_dag != NULL); Aig_Obj_t* R_i_j_increment_part_1 = createEquivalence(R_i_j_object, R_i_j_dag, pub_aig_manager); assert(R_i_j_increment_part_1 != NULL); int present_z_j_k_count = Z_variable_counter[variable_index]; int next_z_j_k_count = present_z_j_k_count + 1; Z_variable_counter[variable_index] = next_z_j_k_count; string present_z_j_k_string = obtainZVariableString(variable_index, present_z_j_k_count); // obtain the string Z_{variable_index}_{present_z_j_k_count} Aig_Obj_t* present_z_j_k_object = obtainExistingObjectOfTemporaryVariableForIncrementalSolving(present_z_j_k_string); assert(present_z_j_k_object != NULL); string next_z_j_k_string = obtainZVariableString(variable_index, next_z_j_k_count); // obtain the string Z_{variable_index}_{next_z_j_k_count} Aig_Obj_t* next_z_j_k_object = obtainObjectOfTemporaryVariableForIncrementalSolving(next_z_j_k_string); assert(next_z_j_k_object != NULL); Aig_Obj_t* R_i_j_increment_part_2 = createEquivalence(present_z_j_k_object, createAnd(R_i_j_object, next_z_j_k_object, pub_aig_manager), pub_aig_manager); assert(R_i_j_increment_part_2 != NULL); Aig_Obj_t* R_i_j_increment = createAnd(R_i_j_increment_part_1, R_i_j_increment_part_2, pub_aig_manager); assert(R_i_j_increment != NULL); Aig_Obj_t* R_i_j_increment_CO = Aig_ObjCreateCo( pub_aig_manager, R_i_j_increment ); assert(R_i_j_increment_CO != NULL); // add CNF of R_i_j_increment into solver pSat_for_exactness_check delta_epsilon_i_components.insert(R_i_j_increment); #ifdef DEBUG_CEGAR cout << endl << R_i_j_string << " and " << next_z_j_k_string << " are created\n"; #endif #ifdef DEBUG_SKOLEM string R_i_j_file_name = benchmark_name_without_extension; R_i_j_file_name += "_R_increment_"; writeFormulaToFile(pub_aig_manager, R_i_j_increment, R_i_j_file_name, ".v", bad_index, variable_index); #endif #ifdef ANALYZE_CEGAR cegar_fp = fopen(cegar_file.c_str(), "a+"); assert(cegar_fp != NULL); int size_of_R_i_j_dag = computeSize(R_i_j_dag, pub_aig_manager); int size_of_R_i_j_increment = computeSize(R_i_j_increment, pub_aig_manager); fprintf(cegar_fp, "\nSize of R_%d_%d_dag = %d\tSize of R_%d_%d_increment = %d", bad_index, variable_index, size_of_R_i_j_dag, bad_index, variable_index, size_of_R_i_j_increment); fclose(cegar_fp); #endif } // 4. UPDATE THE CONNECTIONS #ifdef DEBUG_CEGAR cout << "\nSTEP-4. UPDATE THE CONNECTIONS\n"; #endif #ifdef DEBUG_CEGAR showSet(connections_to_update, "connections_to_update"); #endif #ifdef ANALYZE_CEGAR number_of_connections_updated_in_iteration_in_connection_based_scheme = number_of_connections_updated_in_iteration_in_connection_based_scheme + connections_to_update.size(); #endif // Updating the connections for(set::iterator connections_to_update_it = connections_to_update.begin(); connections_to_update_it != connections_to_update.end(); connections_to_update_it++) { string connection_to_update = *connections_to_update_it; #ifdef DEBUG_CEGAR cout << "\nconnection_to_update = " << connection_to_update << endl; #endif map replacement_map_for_connection_to_update; // we can find the replacement map for connection_to_update using // sensitivity_list and dependency_list obtainReplacementMapForConnection(connection_to_update, replacement_map_for_connection_to_update); // update the data-structures int start_index_of_connection_to_update; int end_index_of_connection_to_update; findStartIndexAndEndIndexOfConnection(connection_to_update, start_index_of_connection_to_update, end_index_of_connection_to_update); assert(start_index_of_connection_to_update < end_index_of_connection_to_update); map >::iterator connections_it_1 = connections_starting_at_skolem_function.find(start_index_of_connection_to_update); if(connections_it_1 == connections_starting_at_skolem_function.end()) { set connections_to_be_recomputed; connections_to_be_recomputed.insert(connection_to_update); connections_starting_at_skolem_function.insert(make_pair(start_index_of_connection_to_update, connections_to_be_recomputed)); } else { (connections_it_1->second).insert(connection_to_update); } map >::iterator connections_it_2 = connections_ending_at_skolem_function.find(end_index_of_connection_to_update); if(connections_it_2 == connections_ending_at_skolem_function.end()) { set changed_connections; changed_connections.insert(connection_to_update); connections_ending_at_skolem_function.insert(make_pair(end_index_of_connection_to_update, changed_connections)); } else { (connections_it_2->second).insert(connection_to_update); } // data-structures updated #ifdef DEBUG_CEGAR cout << "\nreplacement_map_for_connection_to_update created\n"; showMap(replacement_map_for_connection_to_update, "replacement_map_for_connection_to_update", pub_aig_manager, var_name_to_var_index_map); cout << "\nconnections_starting_at_skolem_function updated\n"; showMap(connections_starting_at_skolem_function, "connections_starting_at_skolem_function"); cout << "\nconnections_ending_at_skolem_function\n"; showMap(connections_ending_at_skolem_function, "connections_ending_at_skolem_function"); #endif // Let us now compute the dag for connection_to_update // connection_to_update is C_start_index_of_connection_to_update_...._end_index_of_connection_to_update // Expression for C_start_index_of_connection_to_update_...._end_index_of_connection_to_update is obtained as // skolem_function for start_index_of_connection_to_update with replacements as per replacement_map_for_connection_to_update // and x_end_index_of_connection_to_update replaced by 1 Aig_Obj_t* skolem_function_at_start_index; skolem_function_at_start_index = searchOneDimensionalMatrix(SkolemFunctions, number_of_vars_to_elim, start_index_of_connection_to_update); assert(skolem_function_at_start_index != NULL); Aig_Obj_t* skolem_function_after_replacements; if(replacement_map_for_connection_to_update.size() > 0) { skolem_function_after_replacements = replaceVariablesByFormulas(skolem_function_at_start_index, replacement_map_for_connection_to_update); assert(skolem_function_after_replacements != NULL); } else { skolem_function_after_replacements = skolem_function_at_start_index; } // we need to replace occurences of x_end_index_of_connection_to_update by true skolem_function_after_replacements = replaceVariableByConstant(skolem_function_after_replacements, end_index_of_connection_to_update, 1); assert(skolem_function_after_replacements != NULL); Aig_Obj_t* new_connection_dag = skolem_function_after_replacements; Aig_Obj_t* current_connection_dag; map::iterator Connections_it = Connections.find(connection_to_update); if(Connections_it == Connections.end()) // dag does not exist for connection_to_update { current_connection_dag = NULL; } else { current_connection_dag = Connections_it->second; assert(current_connection_dag != NULL); } if(current_connection_dag != new_connection_dag) // connection_dag has changed { #ifdef DEBUG_CEGAR cout << "\nConnection dag for " << connection_to_update << " is changed\n"; #endif Aig_Obj_t* new_connection_dag_CO = Aig_ObjCreateCo( pub_aig_manager, new_connection_dag ); assert(new_connection_dag_CO != NULL); // insert it first Connections[connection_to_update] = new_connection_dag; #ifdef PRINT_SKOLEM_FUNCTIONS string connection_file_name = benchmark_name_without_extension; connection_file_name += connection_to_update; writeFormulaToFile(pub_aig_manager, new_connection_dag, connection_file_name, ".v", 0, 0); #endif } else { #ifdef DEBUG_CEGAR cout << "\nConnection dag for " << connection_to_update << " is not changed\n"; #endif } if(use_incremental_sat_solving) { // create dag connection_to_update = ite(control-variable, new_connection_dag, symbol) // connection_to_update is the connection we have map::iterator I_variable_counter_it = I_variable_counter.find(connection_to_update); Aig_Obj_t* present_connection_object; int next_connection_count; string present_connection_string; if(I_variable_counter_it == I_variable_counter.end()) { next_connection_count = 0; I_variable_counter.insert(make_pair(connection_to_update, next_connection_count)); present_connection_object = obtainObjectOfConnectionString(connection_to_update); assert(present_connection_object != NULL); present_connection_string = connection_to_update; // just for debugging } else { int present_connection_count = I_variable_counter_it->second; next_connection_count = present_connection_count + 1; I_variable_counter[connection_to_update] = next_connection_count; present_connection_string = obtainTVariableString(present_connection_count, connection_to_update); // obtain the string T_{present_connection_count}_{connection_to_update} present_connection_object = obtainExistingObjectOfTemporaryVariableForIncrementalSolving(present_connection_string); assert(present_connection_object != NULL); } string next_connection_string = obtainTVariableString(next_connection_count, connection_to_update); // obtain the string T_{next_connection_count}_{connection_to_update} Aig_Obj_t* next_connection_object = obtainObjectOfTemporaryVariableForIncrementalSolving(next_connection_string); assert(next_connection_object != NULL); string next_control_string = obtainIVariableString(next_connection_count, connection_to_update); // obtain the string I_{next_connection_count}_{connection_to_update} Aig_Obj_t* next_control_object = obtainObjectOfTemporaryVariableForIncrementalSolving(next_control_string); assert(next_control_object != NULL); Aig_Obj_t* connection_increment = createEquivalence(present_connection_object, createIte(next_control_object, new_connection_dag, next_connection_object, pub_aig_manager), pub_aig_manager); assert(connection_increment != NULL); Aig_Obj_t* connection_increment_CO = Aig_ObjCreateCo( pub_aig_manager, connection_increment ); assert(connection_increment_CO != NULL); delta_epsilon_i_components.insert(connection_increment); #ifdef DEBUG_CEGAR cout << endl << present_connection_string << " created\n"; #endif #ifdef DEBUG_SKOLEM string present_connection_file_name = benchmark_name_without_extension; present_connection_file_name += present_connection_string; present_connection_file_name += "_increment_"; writeFormulaToFile(pub_aig_manager, connection_increment, present_connection_file_name, ".v", 0, 0); #endif #ifdef ANALYZE_CEGAR cegar_fp = fopen(cegar_file.c_str(), "a+"); assert(cegar_fp != NULL); int size_of_new_connection_dag = computeSize(new_connection_dag, pub_aig_manager); int size_of_connection_increment = computeSize(connection_increment, pub_aig_manager); fprintf(cegar_fp, "\nSize of %s_dag = %d\tSize of %s_increment = %d", connection_to_update.c_str(), size_of_new_connection_dag, connection_to_update.c_str(), size_of_connection_increment); fclose(cegar_fp); #endif } }// Updating the connections ends here }// else of if(use value based scheme) ends here } // take each hint ends here #ifdef ANALYZE_CEGAR number_of_connections_in_connection_based_scheme = connection_string_to_connection_object_map.size(); #endif if(use_incremental_sat_solving) { if(apply_uniformity_in_cex_generation && value_based_scheme_is_used) { // create the uniformity condition and insert into delta_epsilon_i_components Aig_Obj_t* uniformity_condition = createUniformityCondition(); // avoid unwanted deletion of uniformity_condition Aig_Obj_t* uniformity_condition_CO = Aig_ObjCreateCo( pub_aig_manager, uniformity_condition ); assert(uniformity_condition_CO != NULL); assert(uniformity_condition != NULL); delta_epsilon_i_components.insert(uniformity_condition); // dags for updated skolem function are created assert(delta_epsilon_i_components.size() > 0); delta_epsilon_i = createAnd(delta_epsilon_i_components, pub_aig_manager); assert(delta_epsilon_i != NULL); // call sat_solver_solve and return the model // Obtain the assumptions vector positive_assumptions_in_exactness_check; vector negative_assumptions_in_exactness_check; obtainAssumptionsInExactnessCheck(positive_assumptions_in_exactness_check, negative_assumptions_in_exactness_check, true, true);// get assumptions such that uniformity_condition is ON assert(positive_assumptions_in_exactness_check.size() != 0); // Use incremental solver call #ifdef DEBUG_CEGAR cout << endl << "Calling SAT-Solver with the uniformity condition\n"; #endif #ifdef DETAILED_RECORD_KEEP unsigned long long int solver_ms; struct timeval solver_start_ms, solver_finish_ms; gettimeofday (&solver_start_ms, NULL); #endif // Give to SAT-Solver and get unsat / sat with model unsigned long long int cnf_time; int formula_size; unsigned long long int simplification_time; bool result_of_exactnesscheck = isExactnessCheckSatisfiable(pub_aig_manager, delta_epsilon_i, Model_of_ExactnessCheck, cnf_time, formula_size, simplification_time, positive_assumptions_in_exactness_check, negative_assumptions_in_exactness_check, pSat_for_exactness_check, IncrementalLabelTableForExactnessCheck, IncrementalLabelCountForExactnessCheck, Ci_name_to_Ci_label_mapForExactnessCheck, Ci_label_to_Ci_name_mapForExactnessCheck); #ifdef DETAILED_RECORD_KEEP gettimeofday (&solver_finish_ms, NULL); solver_ms = solver_finish_ms.tv_sec * 1000 + solver_finish_ms.tv_usec / 1000; solver_ms -= solver_start_ms.tv_sec * 1000 + solver_start_ms.tv_usec / 1000; cout << "\nsolver finished in " << solver_ms << " milliseconds\n"; total_time_in_smt_solver = total_time_in_smt_solver + solver_ms; total_time_in_exactness_checking_in_cegar = total_time_in_exactness_checking_in_cegar + solver_ms; number_of_exactness_checking_in_cegar++; #endif #ifdef RECORD_KEEP fprintf(record_fp, "\t%d\t%d\t%d\t%d", maximum_length_of_connection_in_connection_based_scheme, number_of_connections_in_connection_based_scheme, number_of_connections_updated_in_iteration_in_connection_based_scheme, number_of_literals_dropped_by_unsat_core); number_of_connections_updated_in_iteration_in_connection_based_scheme = 0; fprintf(record_fp, "\n\n%d\t%llu(%llu,%llu)(%d)\t", cegar_iteration_number, solver_ms, cnf_time, simplification_time, formula_size); #endif #ifdef DEBUG_SKOLEM displayModelFromSATSolver(Model_of_ExactnessCheck); cout << endl << "result_of_exactnesscheck = " << result_of_exactnesscheck << endl; #endif removeTemporaryVariablesFromModel(Model_of_ExactnessCheck); #ifdef DEBUG_CEGAR cout << "\nModel after removing temporary variables\n"; displayModelFromSATSolver(Model_of_ExactnessCheck); cout << endl << "result_of_exactnesscheck = " << result_of_exactnesscheck << endl; #endif if(result_of_exactnesscheck) // skolem functions inexact { #ifdef RECORD_KEEP fclose(record_fp); #endif return false; } else // ExactnessCheck unsat with the uniformity condition { // call sat solver without the uniformity conditions // we just need to change the assumptions // Obtain the assumptions positive_assumptions_in_exactness_check.clear(); negative_assumptions_in_exactness_check.clear(); obtainAssumptionsInExactnessCheck(positive_assumptions_in_exactness_check, negative_assumptions_in_exactness_check, true, false);// get assumptions such that all uniformity_conditions are OFF assert(positive_assumptions_in_exactness_check.size() != 0); assert(negative_assumptions_in_exactness_check.size() != 0); // Use incremental solver call #ifdef DEBUG_CEGAR cout << endl << "Calling SAT-Solver without the uniformity condition\n"; #endif #ifdef DETAILED_RECORD_KEEP gettimeofday (&solver_start_ms, NULL); #endif // Give to SAT-Solver and get unsat / sat with model Aig_Obj_t* true_dag = createTrue(pub_aig_manager); result_of_exactnesscheck = isExactnessCheckSatisfiable(pub_aig_manager, true_dag, Model_of_ExactnessCheck, cnf_time, formula_size, simplification_time, positive_assumptions_in_exactness_check, negative_assumptions_in_exactness_check, pSat_for_exactness_check, IncrementalLabelTableForExactnessCheck, IncrementalLabelCountForExactnessCheck, Ci_name_to_Ci_label_mapForExactnessCheck, Ci_label_to_Ci_name_mapForExactnessCheck); #ifdef DETAILED_RECORD_KEEP gettimeofday (&solver_finish_ms, NULL); solver_ms = solver_finish_ms.tv_sec * 1000 + solver_finish_ms.tv_usec / 1000; solver_ms -= solver_start_ms.tv_sec * 1000 + solver_start_ms.tv_usec / 1000; cout << "\nsolver finished in " << solver_ms << " milliseconds\n"; total_time_in_smt_solver = total_time_in_smt_solver + solver_ms; total_time_in_exactness_checking_in_cegar = total_time_in_exactness_checking_in_cegar + solver_ms; number_of_exactness_checking_in_cegar++; #endif #ifdef RECORD_KEEP fprintf(record_fp, "+%llu(%llu,%llu)(%d)\t", solver_ms, cnf_time, simplification_time, formula_size); fclose(record_fp); #endif #ifdef DEBUG_SKOLEM displayModelFromSATSolver(Model_of_ExactnessCheck); cout << endl << "result_of_exactnesscheck = " << result_of_exactnesscheck << endl; #endif removeTemporaryVariablesFromModel(Model_of_ExactnessCheck); #ifdef DEBUG_CEGAR cout << "\nModel after removing temporary variables\n"; displayModelFromSATSolver(Model_of_ExactnessCheck); cout << endl << "result_of_exactnesscheck = " << result_of_exactnesscheck << endl; #endif if(!result_of_exactnesscheck) // ExactnessCheck unsat i.e. skolem functions exact { return true; } else // ExactnessCheck sat i.e. skolem functions inexact { return false; } }// ExactnessCheck unsat with the uniformity condition }//if(apply_uniformity_in_cex_generation && value_based_scheme_is_used) ends here else { // dags for updated skolem function and updated connections are created, assert(delta_epsilon_i_components.size() > 0); delta_epsilon_i = createAnd(delta_epsilon_i_components, pub_aig_manager); assert(delta_epsilon_i != NULL); // call sat_solver_solve and return the model // Obtain the assumptions vector positive_assumptions_in_exactness_check; vector negative_assumptions_in_exactness_check; obtainAssumptionsInExactnessCheck(positive_assumptions_in_exactness_check, negative_assumptions_in_exactness_check, false, false); assert(positive_assumptions_in_exactness_check.size() != 0); // Use incremental solver call #ifdef DEBUG_CEGAR cout << endl << "Calling SAT-Solver under assumptions\n"; #endif #ifdef DETAILED_RECORD_KEEP unsigned long long int solver_ms; struct timeval solver_start_ms, solver_finish_ms; gettimeofday (&solver_start_ms, NULL); #endif // Give to SAT-Solver and get unsat / sat with model unsigned long long int cnf_time; int formula_size; unsigned long long int simplification_time; bool result_of_exactnesscheck = isExactnessCheckSatisfiable(pub_aig_manager, delta_epsilon_i, Model_of_ExactnessCheck, cnf_time, formula_size, simplification_time, positive_assumptions_in_exactness_check, negative_assumptions_in_exactness_check, pSat_for_exactness_check, IncrementalLabelTableForExactnessCheck, IncrementalLabelCountForExactnessCheck, Ci_name_to_Ci_label_mapForExactnessCheck, Ci_label_to_Ci_name_mapForExactnessCheck); #ifdef DETAILED_RECORD_KEEP gettimeofday (&solver_finish_ms, NULL); solver_ms = solver_finish_ms.tv_sec * 1000 + solver_finish_ms.tv_usec / 1000; solver_ms -= solver_start_ms.tv_sec * 1000 + solver_start_ms.tv_usec / 1000; cout << "\nsolver finished in " << solver_ms << " milliseconds\n"; total_time_in_smt_solver = total_time_in_smt_solver + solver_ms; total_time_in_exactness_checking_in_cegar = total_time_in_exactness_checking_in_cegar + solver_ms; number_of_exactness_checking_in_cegar++; #endif #ifdef RECORD_KEEP fprintf(record_fp, "\t%d\t%d\t%d\t%d", maximum_length_of_connection_in_connection_based_scheme, number_of_connections_in_connection_based_scheme, number_of_connections_updated_in_iteration_in_connection_based_scheme, number_of_literals_dropped_by_unsat_core); number_of_connections_updated_in_iteration_in_connection_based_scheme = 0; fprintf(record_fp, "\n\n%d\t%llu(%llu,%llu)(%d)\t", cegar_iteration_number, solver_ms, cnf_time, simplification_time, formula_size); fclose(record_fp); #endif #ifdef DEBUG_SKOLEM displayModelFromSATSolver(Model_of_ExactnessCheck); cout << endl << "result_of_exactnesscheck = " << result_of_exactnesscheck << endl; #endif removeTemporaryVariablesFromModel(Model_of_ExactnessCheck); #ifdef DEBUG_CEGAR cout << "\nModel after removing temporary variables\n"; displayModelFromSATSolver(Model_of_ExactnessCheck); cout << endl << "result_of_exactnesscheck = " << result_of_exactnesscheck << endl; #endif if(!result_of_exactnesscheck) // ExactnessCheck unsat i.e. skolem functions exact { return true; } else // skolem functions inexact { return false; } }// else of if(apply_uniformity_in_cex_generation && value_based_scheme_is_used) ends here }//if(use_incremental_sat_solving) ends here else { // Create the dag for epsilon_i // F(X',Y) \wedge (B1\vee ... \vee B_n \vee B_{n+1}) \wedge // (B_1 = bad_set_1) \wedge ... \wedge (B_n = bad_set_n) \wedge (B_{n+1} = bad_set_{n+1}) \wedge // (x_1 = psi_1) \wedge ... \wedge (x_n = psi_n) \wedge // conjunction of (C_i_j = dags for C_i_j) for all the connections C_i_j // dag for F(X',Y) is already created in renamed_conjunction_of_factors // dag for (B1\vee ... \vee B_n \vee B_{n+1}) is already created in disjunction_of_bad_symbols // dag for (B_1 = bad_set_1) \wedge ... \wedge (B_n = bad_set_n) \wedge (B_{n+1} = bad_set_{n+1}) is already created in B_equivalence_part // Let's first create dag for (x_1 = psi_1) \wedge ... \wedge (x_n = psi_n) Aig_Obj_t* S_equivalence_part; set S_equivalence_objects; for(int var_to_elim_index = 1; var_to_elim_index <= number_of_vars_to_elim; var_to_elim_index++) { // obtaining dag for x_i string var_to_elim = searchVarIndexToVarNameMap(var_index_to_var_name_map, var_to_elim_index); map::iterator Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it = Ci_to_eliminate_name_to_Ci_to_eliminate_object_map.find(var_to_elim); assert(Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it != Ci_to_eliminate_name_to_Ci_to_eliminate_object_map.end()); Aig_Obj_t* var_to_elim_obj = Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it->second; // obtaining \psi_i Aig_Obj_t* skolem_function; skolem_function = searchOneDimensionalMatrix(SkolemFunctions, number_of_vars_to_elim, var_to_elim_index); assert(skolem_function != NULL); Aig_Obj_t* S_equivalence_i = createEquivalence(skolem_function, var_to_elim_obj, pub_aig_manager); S_equivalence_objects.insert(S_equivalence_i); } assert(!S_equivalence_objects.empty()); S_equivalence_part = createAnd(S_equivalence_objects, pub_aig_manager); assert(S_equivalence_part != NULL); // Let's create dag for conjunction of (connection = dag for connection) for all connections Aig_Obj_t* S_connection_part; set S_connection_objects; for(map::iterator connection_string_to_connection_object_map_it = connection_string_to_connection_object_map.begin(); connection_string_to_connection_object_map_it != connection_string_to_connection_object_map.end(); connection_string_to_connection_object_map_it++) { string connection_string = connection_string_to_connection_object_map_it->first; Aig_Obj_t* connection_obj = connection_string_to_connection_object_map_it->second; assert(connection_obj != NULL); map::iterator Connections_it = Connections.find(connection_string); if(Connections_it == Connections.end()) { cout << "\nNo connection_dag for connection " << connection_string << endl; assert(false); } Aig_Obj_t* connection_dag = Connections_it->second; assert(connection_dag != NULL); Aig_Obj_t* S_connection_i = createEquivalence(connection_dag, connection_obj, pub_aig_manager); S_connection_objects.insert(S_connection_i); } assert(!S_connection_objects.empty()); S_connection_part = createAnd(S_connection_objects, pub_aig_manager); assert(S_connection_part != NULL); #ifdef DEBUG_SKOLEM string S_connection_part_file_name = benchmark_name_without_extension; S_connection_part_file_name += "_S_connection_part"; string S_equivalence_part_file_name = benchmark_name_without_extension; S_equivalence_part_file_name += "_S_equivalence_part"; cout << "\nS_connection_part computed\n"; cout << "\nS_equivalence_part computed\n"; writeFormulaToFile(pub_aig_manager, S_connection_part, S_connection_part_file_name, ".v", 0, cegar_iteration_number); writeFormulaToFile(pub_aig_manager, S_equivalence_part, S_equivalence_part_file_name, ".v", 0, cegar_iteration_number); #endif set epsilon_i_objects; assert(renamed_conjunction_of_factors != NULL); epsilon_i_objects.insert(renamed_conjunction_of_factors); assert(disjunction_of_bad_symbols != NULL); epsilon_i_objects.insert(disjunction_of_bad_symbols); assert(B_equivalence_part != NULL); epsilon_i_objects.insert(B_equivalence_part); epsilon_i_objects.insert(S_equivalence_part); epsilon_i_objects.insert(S_connection_part); epsilon_i = createAnd(epsilon_i_objects, pub_aig_manager); assert(epsilon_i != NULL); // Give epsilon_i to SAT-Solver #ifdef DEBUG_CEGAR cout << endl << "Giving epsilon_i to SAT-Solver\n"; #endif #ifdef DETAILED_RECORD_KEEP unsigned long long int solver_ms; struct timeval solver_start_ms, solver_finish_ms; gettimeofday (&solver_start_ms, NULL); #endif // Give to SAT-Solver and get unsat / sat with model unsigned long long int cnf_time; int formula_size; unsigned long long int simplification_time; bool result_of_exactnesscheck = isSat(pub_aig_manager, epsilon_i, Model_of_ExactnessCheck, cnf_time, formula_size, simplification_time); #ifdef DETAILED_RECORD_KEEP gettimeofday (&solver_finish_ms, NULL); solver_ms = solver_finish_ms.tv_sec * 1000 + solver_finish_ms.tv_usec / 1000; solver_ms -= solver_start_ms.tv_sec * 1000 + solver_start_ms.tv_usec / 1000; cout << "\nsolver finished in " << solver_ms << " milliseconds\n"; total_time_in_smt_solver = total_time_in_smt_solver + solver_ms; total_time_in_exactness_checking_in_cegar = total_time_in_exactness_checking_in_cegar + solver_ms; number_of_exactness_checking_in_cegar++; #endif #ifdef RECORD_KEEP fprintf(record_fp, "\t%d\t%d\t%d\t%d", maximum_length_of_connection_in_connection_based_scheme, number_of_connections_in_connection_based_scheme, number_of_connections_updated_in_iteration_in_connection_based_scheme, number_of_literals_dropped_by_unsat_core); number_of_connections_updated_in_iteration_in_connection_based_scheme = 0; fprintf(record_fp, "\n\n%d\t%llu(%llu,%llu)(%d)\t", cegar_iteration_number, solver_ms, cnf_time, simplification_time, formula_size); fclose(record_fp); #endif #ifdef DEBUG_SKOLEM displayModelFromSATSolver(Model_of_ExactnessCheck); cout << endl << "result_of_exactnesscheck = " << result_of_exactnesscheck << endl; #endif #ifdef DEBUG_CEGAR cout << endl << "result_of_exactnesscheck = " << result_of_exactnesscheck << endl; #endif if(!result_of_exactnesscheck) // ExactnessCheck unsat i.e. skolem functions exact { return true; } else // skolem functions inexact { return false; } } //else of if(use_incremental_sat_solving) ends here } // if(cegar_iteration_number > 0) ends here } void AIGBasedSkolem::findConnectionsToUpdate(set &connections_to_update, int variable_index, int bad_index) { connections_to_update.clear(); set connections_ending_at_variable_index; for(int subst_index = bad_index; subst_index <= variable_index-1; subst_index++) { // Creating the string for C_subst_index_variable_index string connection_string = "C_"; char subst_char[100]; sprintf(subst_char, "%d", subst_index); string subst_string(subst_char); connection_string += subst_string; connection_string += "_"; char variable_char[100]; sprintf(variable_char, "%d", variable_index); string variable_string(variable_char); connection_string += variable_string; if(apply_optimization_on_connection_finding && Connections.find(connection_string) != Connections.end()) { // connection subst_index --> variable_index is already existing // hence no need to create connections ending at variable_index going through subst_index and // no need to create connections going through variable_index going through subst_index // they are already there continue; } connections_ending_at_variable_index.insert(connection_string); set connections_ending_at_subst_index; map >::iterator connections_ending_at_skolem_function_it = connections_ending_at_skolem_function.find(subst_index); if(connections_ending_at_skolem_function_it != connections_ending_at_skolem_function.end()) // there are some connections ending at subst_index { connections_ending_at_subst_index = connections_ending_at_skolem_function_it->second; } for(set::iterator connections_ending_at_subst_index_it = connections_ending_at_subst_index.begin(); connections_ending_at_subst_index_it != connections_ending_at_subst_index.end(); connections_ending_at_subst_index_it++) { string connection_ending_at_subst_index = *connections_ending_at_subst_index_it; // let's extend this connection so that it ends at variable_index string connection_extended_to_variable_index = connection_ending_at_subst_index; connection_extended_to_variable_index += "_"; connection_extended_to_variable_index += variable_string; connections_ending_at_variable_index.insert(connection_extended_to_variable_index); } } if(!connections_ending_at_variable_index.empty()) { set_union(connections_to_update.begin(), connections_to_update.end(), connections_ending_at_variable_index.begin(), connections_ending_at_variable_index.end(),inserter(connections_to_update, connections_to_update.begin())); } #ifdef DEBUG_SKOLEM showSet(connections_ending_at_variable_index, "connections_ending_at_variable_index"); #endif set connections_starting_at_variable_index; map >::iterator connections_starting_at_skolem_function_it = connections_starting_at_skolem_function.find(variable_index); if(connections_starting_at_skolem_function_it != connections_starting_at_skolem_function.end()) // there are some connections starting at variable_index { connections_starting_at_variable_index = connections_starting_at_skolem_function_it->second; } if(!connections_starting_at_variable_index.empty()) { set_union(connections_to_update.begin(), connections_to_update.end(), connections_starting_at_variable_index.begin(), connections_starting_at_variable_index.end(),inserter(connections_to_update, connections_to_update.begin())); } #ifdef DEBUG_SKOLEM showSet(connections_starting_at_variable_index, "connections_starting_at_variable_index"); #endif set connections_going_through_variable_index; for(set::iterator connections_starting_at_variable_index_it = connections_starting_at_variable_index.begin(); connections_starting_at_variable_index_it != connections_starting_at_variable_index.end(); connections_starting_at_variable_index_it++) { string connection_starting_at_variable_index = *connections_starting_at_variable_index_it; for(set::iterator connections_ending_at_variable_index_it = connections_ending_at_variable_index.begin(); connections_ending_at_variable_index_it != connections_ending_at_variable_index.end(); connections_ending_at_variable_index_it++) { string connection_ending_at_variable_index = *connections_ending_at_variable_index_it; string connection_to_update; connection_to_update = mergeConnections(connection_ending_at_variable_index, connection_starting_at_variable_index); connections_going_through_variable_index.insert(connection_to_update); } } if(!connections_going_through_variable_index.empty()) { set_union(connections_to_update.begin(), connections_to_update.end(), connections_going_through_variable_index.begin(), connections_going_through_variable_index.end(),inserter(connections_to_update, connections_to_update.begin())); } #ifdef DEBUG_SKOLEM showSet(connections_going_through_variable_index, "connections_going_through_variable_index"); #endif } void AIGBasedSkolem::obtainReplacementMapForConnection(string connection, map &replacement_map_for_connection) { vector points_in_connection; findPointsInConnection(connection, points_in_connection); #ifdef DEBUG_SKOLEM showVector(points_in_connection, "points_in_connection"); #endif #ifdef ANALYZE_CEGAR int length_of_connection = points_in_connection.size(); if(length_of_connection > maximum_length_of_connection_in_connection_based_scheme) { maximum_length_of_connection_in_connection_based_scheme = length_of_connection; } #endif int skolem_index, variable_index; skolem_index = points_in_connection[0]; variable_index = points_in_connection[points_in_connection.size()-1]; // avoid the skolem_index (first point) and variable_index (last point) // from the vector points_in_connection points_in_connection.erase(points_in_connection.begin()); points_in_connection.erase(points_in_connection.begin() + points_in_connection.size() - 1); #ifdef DEBUG_SKOLEM cout << "\nskolem_index = " << skolem_index << "\tvariable_index = " << variable_index << endl; showVector(points_in_connection, "points_in_connection"); #endif for(int subst_index = skolem_index+1; subst_index < variable_index; subst_index++) { // we need to replace occurences of x_subst_index by appropriate connection // if it is not in points_in_connection // we need to replace occurences of x_subst_index by 1 // otherwise #ifdef DEBUG_SKOLEM cout << "\nsubst_index = " << subst_index << endl; #endif string variable_to_replace = searchVarIndexToVarNameMap(var_index_to_var_name_map, subst_index); Aig_Obj_t* symbol_to_replace; if(subst_index == points_in_connection[0]) { symbol_to_replace = createTrue(pub_aig_manager); points_in_connection.erase(points_in_connection.begin()); #ifdef DEBUG_SKOLEM cout << "\nreplace by true\n"; #endif } else { // let's form the connection_string and then the connection object string connection_string = "C_"; char subst_char[100]; sprintf(subst_char, "%d", subst_index); string subst_string(subst_char); connection_string += subst_string; connection_string += "_"; for(int point_location = 0; point_location < points_in_connection.size(); point_location++) { int point = points_in_connection[point_location]; char point_char[100]; sprintf(point_char, "%d", point); string point_string(point_char); connection_string += point_string; connection_string += "_"; } char variable_char[100]; sprintf(variable_char, "%d", variable_index); string variable_string(variable_char); connection_string += variable_string; Aig_Obj_t* connection_object; map::iterator connection_string_to_connection_object_map_it = connection_string_to_connection_object_map.find(connection_string); if(connection_string_to_connection_object_map_it != connection_string_to_connection_object_map.end()) // object for connection_string exists { #ifdef DEBUG_SKOLEM cout << "\nconnection_object exists for this connection_string" << endl; #endif connection_object = connection_string_to_connection_object_map_it->second; assert(connection_object != NULL); } else { // creating new connection #ifdef DEBUG_SKOLEM cout << "\ncreating connection_object for this connection_string" << endl; #endif connection_object = Aig_ObjCreateCi(pub_aig_manager); assert(connection_object != NULL); int connection_id = Aig_ObjId(connection_object); // no need to apply Aig_Regular() as connection_object is CI Ci_id_to_Ci_name_map.insert(make_pair(connection_id, connection_string)); Ci_name_to_Ci_number_map.insert(make_pair(connection_string, number_of_Cis)); connection_string_to_connection_object_map.insert(make_pair(connection_string, connection_object)); number_of_Cis++; } symbol_to_replace = connection_object; #ifdef DEBUG_SKOLEM cout << "\nreplace by " << connection_string << endl; #endif }//else of if(subst_index == points_in_connection[0]) replacement_map_for_connection.insert(make_pair(variable_to_replace, symbol_to_replace)); }// for each subst_index ends here map >::iterator dependency_list_it = dependency_list.find(skolem_index); if(dependency_list_it != dependency_list.end()) { set dependents = dependency_list_it->second; for(set::iterator dependents_it = dependents.begin(); dependents_it != dependents.end(); dependents_it++) { int dependent = *dependents_it; // create existing connection string existing_connection = "C_"; char dependent_char[100]; sprintf(dependent_char, "%d", dependent); string dependent_string(dependent_char); existing_connection += dependent_string; existing_connection += "_"; char skolem_char[100]; sprintf(skolem_char, "%d", skolem_index); string skolem_string(skolem_char); existing_connection += skolem_string; string connection_string; connection_string = mergeConnections(existing_connection, connection); // replace existing_connection --> connection_string string variable_to_replace = existing_connection; Aig_Obj_t* connection_object; map::iterator connection_string_to_connection_object_map_it = connection_string_to_connection_object_map.find(connection_string); if(connection_string_to_connection_object_map_it != connection_string_to_connection_object_map.end()) // object for connection_string exists { #ifdef DEBUG_SKOLEM cout << "\nconnection_object exists for this connection_string" << endl; #endif connection_object = connection_string_to_connection_object_map_it->second; assert(connection_object != NULL); } else { // creating new connection #ifdef DEBUG_SKOLEM cout << "\ncreating connection_object for this connection_string" << endl; #endif connection_object = Aig_ObjCreateCi(pub_aig_manager); assert(connection_object != NULL); int connection_id = Aig_ObjId(connection_object); // no need to apply Aig_Regular() as connection_object is CI Ci_id_to_Ci_name_map.insert(make_pair(connection_id, connection_string)); Ci_name_to_Ci_number_map.insert(make_pair(connection_string, number_of_Cis)); connection_string_to_connection_object_map.insert(make_pair(connection_string, connection_object)); number_of_Cis++; } Aig_Obj_t* symbol_to_replace = connection_object; #ifdef DEBUG_SKOLEM cout << "\nreplace " << existing_connection << " by " << connection_string << endl; #endif replacement_map_for_connection.insert(make_pair(variable_to_replace, symbol_to_replace)); }// for each dependent ends here }// if there are dependents ends here }// function ends here void AIGBasedSkolem::findPointsInConnection(string connection, vector &points_in_connection) { int index = connection.find("_"); assert(index != string::npos); string C = connection.substr(0, index); assert(C == "C"); string points_part = connection.substr(index+1); while(true) { string point_string; index = points_part.find("_"); if(index == string::npos) { // No more points; this is the last point point_string = points_part; int point = atoi(point_string.c_str()); points_in_connection.push_back(point); break; } else { point_string = points_part.substr(0, index); points_part = points_part.substr(index+1); int point = atoi(point_string.c_str()); points_in_connection.push_back(point); } }//while(true) ends here }// function ends here void AIGBasedSkolem::findStartIndexAndEndIndexOfConnection(string connection, int &start_index_of_connection, int &end_index_of_connection) { vector points_in_connection; findPointsInConnection(connection, points_in_connection); start_index_of_connection = points_in_connection[0]; end_index_of_connection = points_in_connection[points_in_connection.size()-1]; } Aig_Obj_t* AIGBasedSkolem::replaceVariablesByFormulas(Aig_Obj_t* OriginalFormula, map &replacement_map) { Aig_Obj_t* original_formula = OriginalFormula; for(map::iterator map_it = replacement_map.begin(); map_it != replacement_map.end(); map_it++) { string var_to_replace = map_it->first; Aig_Obj_t* formula_to_substitute = map_it->second; assert(original_formula != NULL); assert(formula_to_substitute != NULL); Aig_Obj_t* replaced_formula = replaceVariableByFormula(original_formula, var_to_replace, formula_to_substitute); original_formula = replaced_formula; } return original_formula; } Aig_Obj_t* AIGBasedSkolem::replaceVariableByFormula(Aig_Obj_t* OriginalFormula, string var_to_replace, Aig_Obj_t* FormulaToSubstitute) { #ifdef RECORD_KEEP number_of_compose_operations_for_variable++; #endif #ifdef DETAILED_RECORD_KEEP unsigned long long int step_ms; struct timeval step_start_ms, step_finish_ms; gettimeofday (&step_start_ms, NULL); #endif // sanity checks assert(OriginalFormula != NULL); assert(FormulaToSubstitute != NULL); Aig_Obj_t* ReplacedFormula = ReplaceLeafByExpression(OriginalFormula, var_to_replace, FormulaToSubstitute, pub_aig_manager); // AIG Manager API Call assert(ReplacedFormula != NULL); #ifdef DETAILED_RECORD_KEEP gettimeofday (&step_finish_ms, NULL); step_ms = step_finish_ms.tv_sec * 1000 + step_finish_ms.tv_usec / 1000; step_ms -= step_start_ms.tv_sec * 1000 + step_start_ms.tv_usec / 1000; ComposeTime += step_ms; #endif #ifdef PRINT_VERY_DETAILED_RECORDS_ON_SCREEN cout << "\nreplaceVariableByFormula finished in " << step_ms << " milliseconds\n"; #endif return ReplacedFormula; } string AIGBasedSkolem::mergeConnections(string start_connection, string end_connection) { string new_connection; // find the points in start_connection and end_connection vector points_in_start_connection; findPointsInConnection(start_connection, points_in_start_connection); vector points_in_end_connection; findPointsInConnection(end_connection, points_in_end_connection); assert(points_in_start_connection[points_in_start_connection.size()-1] == points_in_end_connection[0]); // merge the connections // create existing connection new_connection = "C_"; for(int point_location = 0; point_location < points_in_start_connection.size(); point_location++) { int point = points_in_start_connection[point_location]; char point_char[100]; sprintf(point_char, "%d", point); string point_string(point_char); new_connection += point_string; new_connection += "_"; } for(int point_location = 1; point_location < points_in_end_connection.size(); point_location++) { int point = points_in_end_connection[point_location]; char point_char[100]; sprintf(point_char, "%d", point); string point_string(point_char); new_connection += point_string; if(point_location < points_in_end_connection.size()-1) { new_connection += "_"; } } return new_connection; } string AIGBasedSkolem::obtainZVariableString(int var_to_elim_index, int z_i_count) { // Return the string Z_{var_to_elim_index}_{z_i_count} string Z_string = "Z_"; char var_char[100]; sprintf(var_char, "%d", var_to_elim_index); string var_string(var_char); Z_string += var_string; Z_string += "_"; char count_char[100]; sprintf(count_char, "%d", z_i_count); string count_string(count_char); Z_string += count_string; return Z_string; } string AIGBasedSkolem::obtainRVariableString(int bad_index, int variable_index) { // Return the string Z_{bad_index}_{variable_index} string R_string = "R_"; char bad_char[100]; sprintf(bad_char, "%d", bad_index); string bad_string(bad_char); R_string += bad_string; R_string += "_"; char variable_char[100]; sprintf(variable_char, "%d", variable_index); string variable_string(variable_char); R_string += variable_string; return R_string; } string AIGBasedSkolem::obtainTVariableString(int connection_i_j_count, string connection) { // Return the string T_{connection_i_j_count}_{connection} string T_string = "T_"; char connection_i_j_count_char[100]; sprintf(connection_i_j_count_char, "%d", connection_i_j_count); string connection_i_j_count_string(connection_i_j_count_char); T_string += connection_i_j_count_string; T_string += "_"; T_string += connection; return T_string; } string AIGBasedSkolem::obtainIVariableString(int connection_i_j_count, string connection) { // Return the string I_{connection_i_j_count}_{connection} string T_string = "I_"; char connection_i_j_count_char[100]; sprintf(connection_i_j_count_char, "%d", connection_i_j_count); string connection_i_j_count_string(connection_i_j_count_char); T_string += connection_i_j_count_string; T_string += "_"; T_string += connection; return T_string; } Aig_Obj_t* AIGBasedSkolem::obtainObjectOfConnectionString(string connection_string) { // check if object for connection_string is already existing in connection_string_to_connection_object_map Aig_Obj_t* connection_object; map::iterator connection_string_to_connection_object_map_it = connection_string_to_connection_object_map.find(connection_string); if(connection_string_to_connection_object_map_it != connection_string_to_connection_object_map.end()) // object for connection_string exists { connection_object = connection_string_to_connection_object_map_it->second; assert(connection_object != NULL); } else { // creating new connection object connection_object = Aig_ObjCreateCi(pub_aig_manager); assert(connection_object != NULL); int connection_id = Aig_ObjId(connection_object); Ci_id_to_Ci_name_map.insert(make_pair(connection_id, connection_string)); Ci_name_to_Ci_number_map.insert(make_pair(connection_string, number_of_Cis)); connection_string_to_connection_object_map.insert(make_pair(connection_string, connection_object)); number_of_Cis++; } return connection_object; } Aig_Obj_t* AIGBasedSkolem::obtainObjectOfTemporaryVariableForIncrementalSolving(string temporary_variable_string) { // check if object for temporary_variable_string is already existing in temporary_variable_for_incremental_solving_to_object_map Aig_Obj_t* temporary_variable_object; map::iterator temporary_variable_for_incremental_solving_to_object_map_it = temporary_variable_for_incremental_solving_to_object_map.find(temporary_variable_string); if(temporary_variable_for_incremental_solving_to_object_map_it != temporary_variable_for_incremental_solving_to_object_map.end()) // object for temporary_variable_string exists { temporary_variable_object = temporary_variable_for_incremental_solving_to_object_map_it->second; assert(temporary_variable_object != NULL); } else { // creating new variable object temporary_variable_object = Aig_ObjCreateCi(pub_aig_manager); assert(temporary_variable_object != NULL); int temporary_variable_object_id = Aig_ObjId(temporary_variable_object); Ci_id_to_Ci_name_map.insert(make_pair(temporary_variable_object_id, temporary_variable_string)); Ci_name_to_Ci_number_map.insert(make_pair(temporary_variable_string, number_of_Cis)); temporary_variable_for_incremental_solving_to_object_map.insert(make_pair(temporary_variable_string, temporary_variable_object)); number_of_Cis++; } return temporary_variable_object; } Aig_Obj_t* AIGBasedSkolem::obtainExistingObjectOfTemporaryVariableForIncrementalSolving(string temporary_variable_string) { // check if object for temporary_variable_string is already existing in temporary_variable_for_incremental_solving_to_object_map Aig_Obj_t* temporary_variable_object; map::iterator temporary_variable_for_incremental_solving_to_object_map_it = temporary_variable_for_incremental_solving_to_object_map.find(temporary_variable_string); if(temporary_variable_for_incremental_solving_to_object_map_it != temporary_variable_for_incremental_solving_to_object_map.end()) // object for temporary_variable_string exists { temporary_variable_object = temporary_variable_for_incremental_solving_to_object_map_it->second; assert(temporary_variable_object != NULL); } else { cout << "\nError in function AIGBasedSkolem::obtainExistingObjectOfTemporaryVariableForIncrementalSolving!! No object exists for " << temporary_variable_string << endl; assert(false); } return temporary_variable_object; } void AIGBasedSkolem::obtainAssumptionsInExactnessCheck(vector &positive_assumptions_in_exactness_check, vector &negative_assumptions_in_exactness_check, bool apply_uniformity, bool enable_uniformity_condition) { // positive_assumptions_in_exactness_check includes // Z_i_j for each i = variable_to_eliminate and j = Z_variable_counter[i] // k_I_c for each c = connection and k = I_variable_counter[connection] // negative_assumptions_in_exactness_check includes // k_I_c for each c = connection and (k >=0 and k < I_variable_counter[connection]) for(int var_to_elim_index = 1; var_to_elim_index <= number_of_vars_to_elim; var_to_elim_index++) { map::iterator Z_variable_counter_it = Z_variable_counter.find(var_to_elim_index); assert(Z_variable_counter_it != Z_variable_counter.end()); int z_i_count = Z_variable_counter_it->second; string z_i_string = obtainZVariableString(var_to_elim_index, z_i_count); // obtain the string Z_{var_to_elim_index}_{z_i_count} Aig_Obj_t* z_i_object = obtainExistingObjectOfTemporaryVariableForIncrementalSolving(z_i_string); assert(z_i_object != NULL); positive_assumptions_in_exactness_check.push_back(z_i_object); } for(map::iterator connection_string_to_connection_object_map_it = connection_string_to_connection_object_map.begin(); connection_string_to_connection_object_map_it != connection_string_to_connection_object_map.end(); connection_string_to_connection_object_map_it++) { string connection_string = connection_string_to_connection_object_map_it->first; map::iterator I_variable_counter_it = I_variable_counter.find(connection_string); assert(I_variable_counter_it != I_variable_counter.end()); int present_connection_count = I_variable_counter_it->second; string present_control_string = obtainIVariableString(present_connection_count, connection_string); Aig_Obj_t* present_control_object = obtainExistingObjectOfTemporaryVariableForIncrementalSolving(present_control_string); assert(present_control_object != NULL); positive_assumptions_in_exactness_check.push_back(present_control_object); for(int old_connection_count = 0; old_connection_count < present_connection_count; old_connection_count++) { string old_control_string = obtainIVariableString(old_connection_count, connection_string); Aig_Obj_t* old_control_object = obtainExistingObjectOfTemporaryVariableForIncrementalSolving(old_control_string); assert(old_control_object != NULL); negative_assumptions_in_exactness_check.push_back(old_control_object); } } if(apply_uniformity) { for(int uniformity_index = 1; uniformity_index < uniformity_condition_counter-1; uniformity_index++) { string uniformity_string = obtainQVariableString(uniformity_index); Aig_Obj_t* uniformity_object = obtainExistingObjectOfTemporaryVariableForIncrementalSolving(uniformity_string); assert(uniformity_object != NULL); negative_assumptions_in_exactness_check.push_back(uniformity_object); } string uniformity_string = obtainQVariableString(uniformity_condition_counter-1); Aig_Obj_t* uniformity_object = obtainExistingObjectOfTemporaryVariableForIncrementalSolving(uniformity_string); assert(uniformity_object != NULL); if(enable_uniformity_condition) { positive_assumptions_in_exactness_check.push_back(uniformity_object); } else { negative_assumptions_in_exactness_check.push_back(uniformity_object); } }//if(apply_uniformity_in_cex_generation) } void AIGBasedSkolem::removeTemporaryVariablesFromModel(map &Model_of_ExactnessCheck) { map Model_of_ExactnessCheck_Cleaned; for(map::iterator assignment_it = Model_of_ExactnessCheck.begin(); assignment_it != Model_of_ExactnessCheck.end(); assignment_it++) { string Ci_name = assignment_it->first; int Ci_value = assignment_it->second; if(temporary_variable_for_incremental_solving_to_object_map.find(Ci_name) == temporary_variable_for_incremental_solving_to_object_map.end()) { Model_of_ExactnessCheck_Cleaned.insert(make_pair(Ci_name, Ci_value)); } } Model_of_ExactnessCheck = Model_of_ExactnessCheck_Cleaned; } void AIGBasedSkolem::replaceConnectionsByFormulas_In_Multi_Point_Connections() { for(int var_to_elim_index = 1; var_to_elim_index <= number_of_vars_to_elim; var_to_elim_index++) { #ifdef DEBUG_SKOLEM cout << "\nvar_to_elim_index = " << var_to_elim_index << endl; #endif Aig_Obj_t* skolem_function_i; skolem_function_i = searchOneDimensionalMatrix(SkolemFunctions, number_of_vars_to_elim, var_to_elim_index); assert(skolem_function_i != NULL); #ifdef DEBUG_SKOLEM writeFormulaToFile(pub_aig_manager, skolem_function_i, "skolemfunction_before_replaceConnections", ".v", var_to_elim_index, 0); #endif map >::iterator connections_ending_at_skolem_function_it = connections_ending_at_skolem_function.find(var_to_elim_index); if(connections_ending_at_skolem_function_it == connections_ending_at_skolem_function.end()) // there are no connections ending at var_to_elim_index { // skolem_function_i is not dependent on any other variable's skolem function // no need to do anything #ifdef DEBUG_SKOLEM cout << "\nskolem_function_" << var_to_elim_index << " is not dependent on any other variable's skolem function " << endl; #endif continue; } else { set connections_ending_at_var_to_elim_index_set = connections_ending_at_skolem_function_it->second; assert(var_to_elim_index >= 3); list connections_ending_at_var_to_elim_index_list; // sorted based on starting location of connection sortConnectionsBasedOnStartingLocation(connections_ending_at_var_to_elim_index_set, connections_ending_at_var_to_elim_index_list); connections_ending_at_var_to_elim_index_list.reverse(); #ifdef DEBUG_SKOLEM cout << "\nconnections_ending_at_var_to_elim_index_list\n"; showList(connections_ending_at_var_to_elim_index_list); #endif for(list::iterator connections_ending_it = connections_ending_at_var_to_elim_index_list.begin(); connections_ending_it != connections_ending_at_var_to_elim_index_list.end(); connections_ending_it++) { string connection_string = *connections_ending_it; int start_index; int end_index; findStartIndexAndEndIndexOfConnection(connection_string, start_index, end_index); assert(end_index == var_to_elim_index); #ifdef DEBUG_SKOLEM cout << "\nstart_index = " << start_index << endl; #endif assert(start_index <= var_to_elim_index-1); if(start_index < var_to_elim_index-1) { #ifdef DEBUG_SKOLEM cout << "\nLet's obtain final dag for " << connection_string << endl; #endif // Obtaining final dag for connection_string // and inserting it into Connections // Let's obtain the present dag for connection_string Aig_Obj_t* present_connection_dag; map::iterator Connections_it = Connections.find(connection_string); assert(Connections_it != Connections.end()); present_connection_dag = Connections_it->second; assert(present_connection_dag != NULL); // obtain the connection_dag after replacing the connections and update Connections Aig_Obj_t* changed_connection_dag; changed_connection_dag = obtainFormulaWithoutConnections(present_connection_dag); assert(changed_connection_dag != NULL); Connections[connection_string] = changed_connection_dag; } }// for ends here #ifdef DEBUG_SKOLEM cout << "\nLet's obtain final dag for skolem_function_" << var_to_elim_index << endl; #endif // Obtaining final dag for skolem_function_var_to_elim_index // and inserting it into SkolemFunctions Aig_Obj_t* changed_skolem_function_i; changed_skolem_function_i = obtainFormulaWithoutConnections(skolem_function_i); assert(changed_skolem_function_i != NULL); insertIntoOneDimensionalMatrix(SkolemFunctions, number_of_vars_to_elim, var_to_elim_index, changed_skolem_function_i, true); #ifdef DEBUG_SKOLEM writeFormulaToFile(pub_aig_manager, changed_skolem_function_i, "skolemfunction_after_replaceConnections", ".v", var_to_elim_index, 0); #endif }//else ends here }// for ends here } void AIGBasedSkolem::sortConnectionsBasedOnStartingLocation(set &unsorted_connections_set, list &sorted_connections_list) { map > local_connections_map_for_sorting; for(set::iterator unsorted_connections_set_it = unsorted_connections_set.begin(); unsorted_connections_set_it != unsorted_connections_set.end(); unsorted_connections_set_it++) { string connection_string = *unsorted_connections_set_it; int start_index; int end_index; findStartIndexAndEndIndexOfConnection(connection_string, start_index, end_index); assert(start_index <= end_index-1); map >::iterator local_connections_map_for_sorting_it = local_connections_map_for_sorting.find(start_index); if(local_connections_map_for_sorting_it == local_connections_map_for_sorting.end()) { set connections_for_start_index; connections_for_start_index.insert(connection_string); local_connections_map_for_sorting.insert(make_pair(start_index, connections_for_start_index)); } else { (local_connections_map_for_sorting_it->second).insert(connection_string); } } for(map >::iterator local_connections_map_for_sorting_it = local_connections_map_for_sorting.begin(); local_connections_map_for_sorting_it != local_connections_map_for_sorting.end(); local_connections_map_for_sorting_it++) { set connections_for_start_index = local_connections_map_for_sorting_it->second; for(set::iterator connections_for_start_index_it = connections_for_start_index.begin(); connections_for_start_index_it != connections_for_start_index.end(); connections_for_start_index_it++) { string connection_for_start_index = *connections_for_start_index_it; sorted_connections_list.push_back(connection_for_start_index); } } } bool AIGBasedSkolem::checkIfSkolemFunctionsAreExact_using_Value_Based_Scheme(map &Model_of_ExactnessCheck, map &Refinement_Hint_To_Eliminate_This_CEX, list &VariablesToEliminate) { #ifdef RECORD_KEEP string record_file; record_file = logfile_prefix; record_file += "skolem_function_generation_details.txt"; FILE* record_fp = fopen(record_file.c_str(), "a+"); assert(record_fp != NULL); #endif if(cegar_iteration_number == 0) { Aig_Obj_t* epsilon_zero; cout << "\nCreating epsilon_zero\n"; // Create the dag for epsilon_zero: // F(X',Y) \wedge (B1\vee ... \vee B_n \vee B_{n+1}) \wedge // (B_1 = bad_set_1) \wedge ... \wedge (B_n = bad_set_n) \wedge (B_{n+1} = bad_set_{n+1}) \wedge // (x_1 = psi_1) \wedge ... \wedge (x_n = psi_n) // dag for F(X',Y) is already created in renamed_conjunction_of_factors // dag for (B1\vee ... \vee B_n \vee B_{n+1}) is already created in disjunction_of_bad_symbols // Let's first create dag for (B_1 = bad_set_1) \wedge ... \wedge (B_n = bad_set_n) \wedge (B_{n+1} = bad_set_{n+1}) set B_equivalence_objects; for(int bad_location_index = 1; bad_location_index <= number_of_vars_to_elim+1; bad_location_index++) { // Let bad_location_index be i // Obtaining dag for bad_set_i Aig_Obj_t* bad_set_obj; bad_set_obj = searchOneDimensionalMatrix(BadSets, number_of_vars_to_elim+1, bad_location_index); assert(bad_set_obj != NULL); // Obtaining dag for B_i map::iterator B_i_index_to_B_i_object_map_iterator = B_i_index_to_B_i_object_map.find(bad_location_index); assert(B_i_index_to_B_i_object_map_iterator != B_i_index_to_B_i_object_map.end()); Aig_Obj_t* B_obj = B_i_index_to_B_i_object_map_iterator->second; Aig_Obj_t* B_equivalence_i = createEquivalence(bad_set_obj, B_obj, pub_aig_manager); B_equivalence_objects.insert(B_equivalence_i); } assert(!B_equivalence_objects.empty()); B_equivalence_part = createAnd(B_equivalence_objects, pub_aig_manager); assert(B_equivalence_part != NULL); // Let's create dag for (x_1 = psi_1) \wedge ... \wedge (x_n = psi_n) Aig_Obj_t* S_equivalence_part; set S_equivalence_objects; for(int var_to_elim_index = 1; var_to_elim_index <= number_of_vars_to_elim; var_to_elim_index++) { // obtaining dag for x_i string var_to_elim = searchVarIndexToVarNameMap(var_index_to_var_name_map, var_to_elim_index); map::iterator Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it = Ci_to_eliminate_name_to_Ci_to_eliminate_object_map.find(var_to_elim); assert(Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it != Ci_to_eliminate_name_to_Ci_to_eliminate_object_map.end()); Aig_Obj_t* var_to_elim_obj = Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it->second; // obtaining \psi_i Aig_Obj_t* skolem_function; if(use_incremental_sat_solving) { skolem_function = searchOneDimensionalMatrix(SkolemFunctions, number_of_vars_to_elim, var_to_elim_index); assert(skolem_function != NULL); // initialize Z_variable_counter[var_to_elim_index] to 0 Z_variable_counter.insert(make_pair(var_to_elim_index, 0)); int z_i_count = Z_variable_counter[var_to_elim_index]; // 0 here string z_i_string = obtainZVariableString(var_to_elim_index, z_i_count); // obtain the string Z_{var_to_elim_index}_0 // check if object for z_i_string is already existing; if yes return it; otherwise create, // update temporary_variable_for_incremental_solving_to_object_map and return Aig_Obj_t* z_i_object = obtainObjectOfTemporaryVariableForIncrementalSolving(z_i_string); assert(z_i_object != NULL); Aig_Obj_t* alpha_combined_i; alpha_combined_i = searchOneDimensionalMatrix(AlphaCombineds, number_of_vars_to_elim, var_to_elim_index); assert(alpha_combined_i != NULL); Aig_Obj_t* z_i_increment = createOr(alpha_combined_i, z_i_object, pub_aig_manager); assert(z_i_increment != NULL); skolem_function = createAnd(skolem_function, z_i_increment, pub_aig_manager); assert(skolem_function != NULL); } else { skolem_function = searchOneDimensionalMatrix(SkolemFunctions, number_of_vars_to_elim, var_to_elim_index); assert(skolem_function != NULL); } Aig_Obj_t* S_equivalence_i = createEquivalence(skolem_function, var_to_elim_obj, pub_aig_manager); S_equivalence_objects.insert(S_equivalence_i); } assert(!S_equivalence_objects.empty()); S_equivalence_part = createAnd(S_equivalence_objects, pub_aig_manager); assert(S_equivalence_part != NULL); #ifdef DEBUG_SKOLEM string B_equivalence_part_file_name = benchmark_name_without_extension; B_equivalence_part_file_name += "_B_equivalence_part"; string S_equivalence_part_file_name = benchmark_name_without_extension; S_equivalence_part_file_name += "_S_equivalence_part"; cout << "\nB_equivalence_part computed\n"; cout << "\nS_equivalence_part computed\n"; writeFormulaToFile(pub_aig_manager, B_equivalence_part, B_equivalence_part_file_name, ".v", 0, 0); writeFormulaToFile(pub_aig_manager, S_equivalence_part, S_equivalence_part_file_name, ".v", 0, 0); #endif set epsilon_zero_objects; epsilon_zero_objects.insert(renamed_conjunction_of_factors); epsilon_zero_objects.insert(disjunction_of_bad_symbols); epsilon_zero_objects.insert(S_equivalence_part); epsilon_zero_objects.insert(B_equivalence_part); epsilon_zero = createAnd(epsilon_zero_objects, pub_aig_manager); assert(epsilon_zero != NULL); cout << "\nepsilon_zero created\n"; if(use_incremental_sat_solving) { // Identify labels of Z_1_0 ,..., Z_n_0 and // assume that they are true (in positive_assumptions_in_exactness_check) vector positive_assumptions_in_exactness_check; vector negative_assumptions_in_exactness_check; obtainAssumptionsInExactnessCheck(positive_assumptions_in_exactness_check, negative_assumptions_in_exactness_check, false, false); assert(negative_assumptions_in_exactness_check.size() == 0); assert(positive_assumptions_in_exactness_check.size() != 0); // Use incremental solver call #ifdef DEBUG_CEGAR cout << endl << "Adding clauses of epsilon_zero to SAT-Solver, and calling SAT-Solver\n"; #endif #ifdef DETAILED_RECORD_KEEP unsigned long long int solver_ms; struct timeval solver_start_ms, solver_finish_ms; gettimeofday (&solver_start_ms, NULL); #endif // Give to SAT-Solver and get unsat / sat with model unsigned long long int cnf_time; int formula_size; unsigned long long int simplification_time; bool result_of_exactnesscheck = isExactnessCheckSatisfiable(pub_aig_manager, epsilon_zero, Model_of_ExactnessCheck, cnf_time, formula_size, simplification_time, positive_assumptions_in_exactness_check, negative_assumptions_in_exactness_check, pSat_for_exactness_check, IncrementalLabelTableForExactnessCheck, IncrementalLabelCountForExactnessCheck, Ci_name_to_Ci_label_mapForExactnessCheck, Ci_label_to_Ci_name_mapForExactnessCheck); #ifdef DETAILED_RECORD_KEEP gettimeofday (&solver_finish_ms, NULL); solver_ms = solver_finish_ms.tv_sec * 1000 + solver_finish_ms.tv_usec / 1000; solver_ms -= solver_start_ms.tv_sec * 1000 + solver_start_ms.tv_usec / 1000; cout << "\nsolver finished in " << solver_ms << " milliseconds\n"; total_time_in_smt_solver = total_time_in_smt_solver + solver_ms; total_time_in_exactness_checking_in_cegar = total_time_in_exactness_checking_in_cegar + solver_ms; number_of_exactness_checking_in_cegar++; #endif #ifdef RECORD_KEEP fprintf(record_fp, "\n\n%d\t%llu(%llu,%llu)(%d)\t", cegar_iteration_number, solver_ms, cnf_time, simplification_time, formula_size); fclose(record_fp); #endif #ifdef DEBUG_SKOLEM displayModelFromSATSolver(Model_of_ExactnessCheck); cout << endl << "result_of_exactnesscheck = " << result_of_exactnesscheck << endl; #endif removeTemporaryVariablesFromModel(Model_of_ExactnessCheck); #ifdef DEBUG_CEGAR cout << "\nModel after removing temporary variables\n"; displayModelFromSATSolver(Model_of_ExactnessCheck); cout << endl << "result_of_exactnesscheck = " << result_of_exactnesscheck << endl; #endif if(!result_of_exactnesscheck) // ExactnessCheck unsat i.e. skolem functions exact { return true; } else // skolem functions inexact { return false; } } else { // Use normal solver call // i.e. give epsilon_zero to solver #ifdef DEBUG_CEGAR cout << endl << "Giving epsilon_zero to SAT-Solver\n"; #endif #ifdef DETAILED_RECORD_KEEP unsigned long long int solver_ms; struct timeval solver_start_ms, solver_finish_ms; gettimeofday (&solver_start_ms, NULL); #endif // Give to SAT-Solver and get unsat / sat with model unsigned long long int cnf_time; int formula_size; unsigned long long int simplification_time; bool result_of_exactnesscheck = isSat(pub_aig_manager, epsilon_zero, Model_of_ExactnessCheck, cnf_time, formula_size, simplification_time); #ifdef DETAILED_RECORD_KEEP gettimeofday (&solver_finish_ms, NULL); solver_ms = solver_finish_ms.tv_sec * 1000 + solver_finish_ms.tv_usec / 1000; solver_ms -= solver_start_ms.tv_sec * 1000 + solver_start_ms.tv_usec / 1000; cout << "\nsolver finished in " << solver_ms << " milliseconds\n"; total_time_in_smt_solver = total_time_in_smt_solver + solver_ms; total_time_in_exactness_checking_in_cegar = total_time_in_exactness_checking_in_cegar + solver_ms; number_of_exactness_checking_in_cegar++; #endif #ifdef RECORD_KEEP fprintf(record_fp, "\n\n%d\t%llu(%llu,%llu)(%d)\t", cegar_iteration_number, solver_ms, cnf_time, simplification_time, formula_size); fclose(record_fp); #endif #ifdef DEBUG_SKOLEM displayModelFromSATSolver(Model_of_ExactnessCheck); cout << endl << "result_of_exactnesscheck = " << result_of_exactnesscheck << endl; #endif #ifdef DEBUG_CEGAR cout << endl << "result_of_exactnesscheck = " << result_of_exactnesscheck << endl; #endif if(!result_of_exactnesscheck) // ExactnessCheck unsat i.e. skolem functions exact { return true; } else // skolem functions inexact { return false; } }// else of if(use_incremental_sat_solving) ends here } // if(cegar_iteration_number == 0) ends here else // if(cegar_iteration_number > 0) { Aig_Obj_t* epsilon_i; // for normal sat-solving Aig_Obj_t* delta_epsilon_i; // for incremental sat-solving set delta_epsilon_i_components; #ifdef RECORD_KEEP fprintf(record_fp, "\t"); #endif int number_of_literals_dropped_by_unsat_core = 0; for(map::iterator hint_it = Refinement_Hint_To_Eliminate_This_CEX.begin(); hint_it != Refinement_Hint_To_Eliminate_This_CEX.end(); hint_it++) { // 1. TAKE EACH REFINEMENT HINT #ifdef DEBUG_CEGAR cout << "\nSTEP-1. TAKE EACH REFINEMENT HINT\n"; #endif int variable_index = hint_it->first; int bad_index = hint_it->second; assert(bad_index < variable_index); #ifdef DEBUG_CEGAR cout << "\nThe refinement hint is: variable_index = " << variable_index << ", bad_index = " << bad_index << endl; #endif #ifdef RECORD_KEEP fprintf(record_fp, "%d-->%d,", bad_index, variable_index); #endif #ifdef ANALYZE_CEGAR string cegar_file = "cegar_details.txt"; FILE* cegar_fp = fopen(cegar_file.c_str(), "a+"); assert(cegar_fp != NULL); fprintf(cegar_fp, "\n\nThe refinement hint is: %d-->%d\n", bad_index, variable_index); fclose(cegar_fp); #endif // 2. UPDATE THE DATA-STRUCTURES #ifdef DEBUG_CEGAR cout << "\nSTEP-2. UPDATE THE DATA-STRUCTURES\n"; #endif // copy it to refinement_hints map >::iterator refinement_hint_it = refinement_hints.find(variable_index); if(refinement_hint_it == refinement_hints.end()) // entry does not exist for variable_index { set bad_indices; bad_indices.insert(bad_index); refinement_hints.insert(make_pair(variable_index, bad_indices)); } else // entry exists for variable_index { (refinement_hint_it->second).insert(bad_index); } #ifdef DEBUG_CEGAR cout << "\nThe refinement hint to eliminate this counterexample is copied into refinement hints\n"; showMap(refinement_hints, "refinement_hints"); #endif // Updating the data-structures finished // 3. UPDATE THE SKOLEM FUNCTION AT variable_index #ifdef DEBUG_CEGAR cout << "\nSTEP-3. UPDATE THE SKOLEM FUNCTION AT " << variable_index << endl; #endif Aig_Obj_t* R_i_j_dag; if(use_explicit_values_in_refinement) { // create R_i_j_dag // R_i_j_dag is negation of conjunction // of literals as per values_of_variables_from_var[variable_index] // and values_of_Y_variables // creating the x_replacement_map #ifdef DEBUG_CEGAR cout << "\ncreating x_replacement_map" << endl; #endif map x_replacement_map; map >::iterator values_of_variables_from_var_it = values_of_variables_from_var.find(variable_index); assert(values_of_variables_from_var_it != values_of_variables_from_var.end()); x_replacement_map = values_of_variables_from_var_it->second; #ifdef DEBUG_CEGAR cout << "\nx_replacement_map created\n"; showMap(x_replacement_map, "x_replacement_map"); cout << "\nvalues_of_Y_variables\n"; showYMap(); #endif Aig_Obj_t* bad_set_obj_after_replacements = createAssignment(x_replacement_map); assert(bad_set_obj_after_replacements != NULL); // Obtain R_i_j_dag = ~bad_set_obj_after_replacements R_i_j_dag = createNot(bad_set_obj_after_replacements, pub_aig_manager); assert(R_i_j_dag != NULL); }//if(use_explicit_values_in_refinement) else if(use_generalized_value_based_scheme) { // create R_i_j_dag // R_i_j_dag = (conjunction of alpha's and negation of psi's of variables // from bad to var+1 depending on the values of the variables // => ~bad at bad location) with replacement // as per values_of_variables_from_bad_to_var) \wedge ~(values of // variables from var to the last variable) #ifdef DEBUG_CEGAR cout << "\ncreating replacement_map" << endl; #endif map replacement_map; map >::iterator values_of_variables_from_bad_to_var_it = values_of_variables_from_bad_to_var.find(variable_index); assert(values_of_variables_from_bad_to_var_it != values_of_variables_from_bad_to_var.end()); replacement_map = values_of_variables_from_bad_to_var_it->second; #ifdef DEBUG_CEGAR cout << "\nreplacement_map created\n"; showMap(replacement_map, "replacement_map"); #endif assert(replacement_map.size() > 0); #ifdef DEBUG_CEGAR cout << "\nrecomputing skolem function for variable at " << variable_index << endl; #endif set antecedent_components; for(int antecedent_index = bad_index; antecedent_index < variable_index; antecedent_index++) { map::iterator replacement_map_it = replacement_map.find(antecedent_index); assert(replacement_map_it != replacement_map.end()); int value_of_variable_at_antecedent_index = replacement_map_it->second; Aig_Obj_t* antecedent_component; if(value_of_variable_at_antecedent_index == 1) { // antecedent_component is alpha_combined at antecedent_index #ifdef DEBUG_CEGAR cout << "\nantecedent_component is alpha_combined at " << antecedent_index << endl; #endif antecedent_component = searchOneDimensionalMatrix(AlphaCombineds, number_of_vars_to_elim, antecedent_index); assert(antecedent_component != NULL); #ifdef DEBUG_CEGAR cout << "\nsize of antecedent_component is " << computeSize(antecedent_component, pub_aig_manager) << endl; #endif } else if(value_of_variable_at_antecedent_index == 0) { #ifdef DEBUG_CEGAR cout << "\nantecedent_component is negation of skolem function at " << antecedent_index << endl; #endif // antecedent_component is negation of skolem function at antecedent_index antecedent_component = searchOneDimensionalMatrix(SkolemFunctions, number_of_vars_to_elim, antecedent_index); assert(antecedent_component != NULL); antecedent_component = createNot(antecedent_component, pub_aig_manager); assert(antecedent_component != NULL); #ifdef DEBUG_CEGAR cout << "\nsize of antecedent_component is " << computeSize(antecedent_component, pub_aig_manager) << endl; #endif } else { assert(false); } antecedent_components.insert(antecedent_component); } assert(!antecedent_components.empty()); Aig_Obj_t* antecedent = createAnd(antecedent_components, pub_aig_manager); assert(antecedent != NULL); #ifdef DEBUG_CEGAR cout << "\nantecedent created\n"; cout << "\nsize of antecedent is " << computeSize(antecedent, pub_aig_manager) << endl; #endif #ifdef DEBUG_SKOELM string antecedent_file_name = benchmark_name_without_extension; antecedent_file_name += "_antecedent_"; writeFormulaToFile(pub_aig_manager, antecedent, antecedent_file_name, ".v", bad_index, variable_index); #endif Aig_Obj_t* consequent; consequent = searchOneDimensionalMatrix(BadSets, number_of_vars_to_elim, bad_index); assert(consequent != NULL); consequent = createNot(consequent, pub_aig_manager); assert(consequent != NULL); #ifdef DEBUG_CEGAR cout << "\nconsequent created\n"; cout << "\nsize of consequent is " << computeSize(consequent, pub_aig_manager) << endl; #endif #ifdef DEBUG_SKOELM string consequent_file_name = benchmark_name_without_extension; consequent_file_name += "_consequent_"; writeFormulaToFile(pub_aig_manager, consequent, consequent_file_name, ".v", bad_index, variable_index); #endif Aig_Obj_t* implication; implication = createImplication(antecedent, consequent, pub_aig_manager); assert(implication != NULL); #ifdef DEBUG_CEGAR cout << "\nimplication created\n"; cout << "\nsize of implication is " << computeSize(implication, pub_aig_manager) << endl; #endif #ifdef DEBUG_SKOELM string implication_file_name = benchmark_name_without_extension; implication_file_name += "_implication_"; writeFormulaToFile(pub_aig_manager, implication, implication_file_name, ".v", bad_index, variable_index); #endif Aig_Obj_t* R_i_j_dag_part1 = replaceVariablesByConstants(implication, replacement_map); assert(R_i_j_dag_part1 != NULL); // avoid unwanted deletion of R_i_j_dag_part1 inside createUnsatCoreBasedAssignment Aig_Obj_t* R_i_j_dag_part1_CO = Aig_ObjCreateCo( pub_aig_manager, R_i_j_dag_part1 ); assert(R_i_j_dag_part1_CO != NULL); #ifdef DEBUG_CEGAR cout << "\nR_i_j_dag_part1 created\n"; cout << "\nsize of R_i_j_dag_part1 is " << computeSize(R_i_j_dag_part1, pub_aig_manager) << endl; #endif #ifdef DEBUG_SKOELM string R_i_j_dag_part1_file_name = benchmark_name_without_extension; R_i_j_dag_part1_file_name += "_R_i_j_dag_part1_"; writeFormulaToFile(pub_aig_manager, R_i_j_dag_part1, R_i_j_dag_part1_file_name, ".v", bad_index, variable_index); #endif // create R_i_j_dag_part2 // R_i_j_dag_part2 is negation of conjunction // of literals as per values_of_variables_from_var[variable_index] // and values_of_Y_variables // creating the x_replacement_map #ifdef DEBUG_CEGAR cout << "\ncreating x_replacement_map" << endl; #endif map x_replacement_map; map >::iterator values_of_variables_from_var_it = values_of_variables_from_var.find(variable_index); assert(values_of_variables_from_var_it != values_of_variables_from_var.end()); x_replacement_map = values_of_variables_from_var_it->second; #ifdef DEBUG_CEGAR cout << "\nx_replacement_map created\n"; showMap(x_replacement_map, "x_replacement_map"); cout << "\nvalues_of_Y_variables\n"; showYMap(); #endif Aig_Obj_t* R_i_j_dag_part2; if(use_unsat_core_in_refinement) { R_i_j_dag_part2 = createUnsatCoreBasedAssignment(x_replacement_map, variable_index, number_of_literals_dropped_by_unsat_core); } else { R_i_j_dag_part2 = createAssignment(x_replacement_map); } assert(R_i_j_dag_part2 != NULL); R_i_j_dag_part2 = createNot(R_i_j_dag_part2, pub_aig_manager); assert(R_i_j_dag_part2 != NULL); // avoid unwanted deletion of R_i_j_dag_part2 inside createUnsatCoreBasedAssignment Aig_Obj_t* R_i_j_dag_part2_CO = Aig_ObjCreateCo( pub_aig_manager, R_i_j_dag_part2 ); assert(R_i_j_dag_part2_CO != NULL); #ifdef DEBUG_CEGAR cout << "\nR_i_j_dag_part2 created\n"; cout << "\nsize of R_i_j_dag_part2 is " << computeSize(R_i_j_dag_part2, pub_aig_manager) << endl; #endif #ifdef DEBUG_SKOELM string R_i_j_dag_part2_file_name = benchmark_name_without_extension; R_i_j_dag_part2_file_name += "_R_i_j_dag_part2_"; writeFormulaToFile(pub_aig_manager, R_i_j_dag_part2, R_i_j_dag_part2_file_name, ".v", bad_index, variable_index); #endif // Obtain R_i_j_dag = R_i_j_dag_part1 \wedge R_i_j_dag_part2 R_i_j_dag = createAnd(R_i_j_dag_part1, R_i_j_dag_part2, pub_aig_manager); assert(R_i_j_dag != NULL); // avoid unwanted deletion of R_i_j_dag inside createUnsatCoreBasedAssignment Aig_Obj_t* R_i_j_dag_CO = Aig_ObjCreateCo( pub_aig_manager, R_i_j_dag ); assert(R_i_j_dag_CO != NULL); #ifdef DEBUG_CEGAR analyzeReasonBehindMismatch(bad_index, variable_index, replacement_map, x_replacement_map); #endif }//if(use_generalized_value_based_scheme) ends here else { assert(false); } Aig_Obj_t* current_skolem_function; current_skolem_function = searchOneDimensionalMatrix(SkolemFunctions, number_of_vars_to_elim, variable_index); assert(current_skolem_function != NULL); Aig_Obj_t* new_skolem_function; // The new part in the skolem function is // (alpha_i \vee ~Bad after substitutions) Aig_Obj_t* alpha_combined; alpha_combined = searchOneDimensionalMatrix(AlphaCombineds, number_of_vars_to_elim, variable_index); assert(alpha_combined != NULL); Aig_Obj_t* new_component_in_skolem_function; new_component_in_skolem_function = createOr(alpha_combined, R_i_j_dag, pub_aig_manager); assert(new_component_in_skolem_function != NULL); new_skolem_function = createAnd(current_skolem_function, new_component_in_skolem_function, pub_aig_manager); assert(new_skolem_function != NULL); if(new_skolem_function != current_skolem_function) // skolem function is changed { #ifdef DEBUG_CEGAR cout << "\nSkolem function for " << variable_index << " is changed\n"; cout << "\nsize of Skolem function is " << computeSize(new_skolem_function, pub_aig_manager) << endl; #endif // insert the new skolem function insertIntoOneDimensionalMatrix(SkolemFunctions, number_of_vars_to_elim, variable_index, new_skolem_function, true); #ifdef PRINT_SKOLEM_FUNCTIONS string skolem_function_file_name = benchmark_name_without_extension; skolem_function_file_name += "_skolem_function"; writeFormulaToFile(pub_aig_manager, new_skolem_function, skolem_function_file_name, ".v", variable_index, cegar_iteration_number); #endif } else { #ifdef DEBUG_CEGAR cout << "\nSkolem function for " << variable_index << " is not changed\n"; #endif #ifdef PRINT_SKOLEM_FUNCTIONS string skolem_function_file_name = benchmark_name_without_extension; skolem_function_file_name += "_skolem_function"; writeFormulaToFile(pub_aig_manager, new_skolem_function, skolem_function_file_name, ".v", variable_index, cegar_iteration_number); #endif } // skolem function at variable_index updated if(use_incremental_sat_solving) { // new_skolem_function is an internal node // connect new_skolem_function to a CO, new_skolem_function_CO // to avoid unauthorized cleanup in use_incremental_sat_solving // as we are not using new_skolem_function in sat-solving if(new_skolem_function != current_skolem_function) { Aig_Obj_t* new_skolem_function_CO = Aig_ObjCreateCo( pub_aig_manager, new_skolem_function ); assert(new_skolem_function_CO != NULL); } int present_z_j_k_count = Z_variable_counter[variable_index]; int next_z_j_k_count = present_z_j_k_count + 1; Z_variable_counter[variable_index] = next_z_j_k_count; string present_z_j_k_string = obtainZVariableString(variable_index, present_z_j_k_count); // obtain the string Z_{variable_index}_{present_z_j_k_count} Aig_Obj_t* present_z_j_k_object = obtainExistingObjectOfTemporaryVariableForIncrementalSolving(present_z_j_k_string); assert(present_z_j_k_object != NULL); string next_z_j_k_string = obtainZVariableString(variable_index, next_z_j_k_count); // obtain the string Z_{variable_index}_{next_z_j_k_count} Aig_Obj_t* next_z_j_k_object = obtainObjectOfTemporaryVariableForIncrementalSolving(next_z_j_k_string); assert(next_z_j_k_object != NULL); Aig_Obj_t* R_i_j_increment = createEquivalence(present_z_j_k_object, createAnd(R_i_j_dag, next_z_j_k_object, pub_aig_manager), pub_aig_manager); assert(R_i_j_increment != NULL); // avoid unwanted deletion of R_i_j_increment Aig_Obj_t* R_i_j_increment_CO = Aig_ObjCreateCo( pub_aig_manager, R_i_j_increment ); assert(R_i_j_increment_CO != NULL); // add CNF of R_i_j_increment into solver pSat_for_exactness_check delta_epsilon_i_components.insert(R_i_j_increment); #ifdef DEBUG_CEGAR cout << endl << next_z_j_k_string << " is created\n"; #endif #ifdef DEBUG_SKOLEM string R_i_j_file_name = benchmark_name_without_extension; R_i_j_file_name += "_R_increment_"; writeFormulaToFile(pub_aig_manager, R_i_j_increment, R_i_j_file_name, ".v", bad_index, variable_index); #endif #ifdef ANALYZE_CEGAR cegar_fp = fopen(cegar_file.c_str(), "a+"); assert(cegar_fp != NULL); int size_of_R_i_j_dag = computeSize(R_i_j_dag, pub_aig_manager); int size_of_R_i_j_increment = computeSize(R_i_j_increment, pub_aig_manager); fprintf(cegar_fp, "\nSize of R_%d_%d_dag = %d\tSize of R_%d_%d_increment = %d", bad_index, variable_index, size_of_R_i_j_dag, bad_index, variable_index, size_of_R_i_j_increment); fclose(cegar_fp); #endif } } // take each hint ends here if(use_incremental_sat_solving) { if(apply_uniformity_in_cex_generation) { // create the uniformity condition and insert into delta_epsilon_i_components Aig_Obj_t* uniformity_condition = createUniformityCondition(); // avoid unwanted deletion of uniformity_condition Aig_Obj_t* uniformity_condition_CO = Aig_ObjCreateCo( pub_aig_manager, uniformity_condition ); assert(uniformity_condition_CO != NULL); assert(uniformity_condition != NULL); delta_epsilon_i_components.insert(uniformity_condition); // dags for updated skolem function are created assert(delta_epsilon_i_components.size() > 0); delta_epsilon_i = createAnd(delta_epsilon_i_components, pub_aig_manager); assert(delta_epsilon_i != NULL); // call sat_solver_solve and return the model // Obtain the assumptions vector positive_assumptions_in_exactness_check; vector negative_assumptions_in_exactness_check; obtainAssumptionsInExactnessCheck(positive_assumptions_in_exactness_check, negative_assumptions_in_exactness_check, true, true);// get assumptions such that uniformity_condition is ON assert(positive_assumptions_in_exactness_check.size() != 0); // Use incremental solver call #ifdef DEBUG_CEGAR cout << endl << "Calling SAT-Solver with the uniformity condition\n"; #endif #ifdef DETAILED_RECORD_KEEP unsigned long long int solver_ms; struct timeval solver_start_ms, solver_finish_ms; gettimeofday (&solver_start_ms, NULL); #endif // Give to SAT-Solver and get unsat / sat with model unsigned long long int cnf_time; int formula_size; unsigned long long int simplification_time; bool result_of_exactnesscheck = isExactnessCheckSatisfiable(pub_aig_manager, delta_epsilon_i, Model_of_ExactnessCheck, cnf_time, formula_size, simplification_time, positive_assumptions_in_exactness_check, negative_assumptions_in_exactness_check, pSat_for_exactness_check, IncrementalLabelTableForExactnessCheck, IncrementalLabelCountForExactnessCheck, Ci_name_to_Ci_label_mapForExactnessCheck, Ci_label_to_Ci_name_mapForExactnessCheck); #ifdef DETAILED_RECORD_KEEP gettimeofday (&solver_finish_ms, NULL); solver_ms = solver_finish_ms.tv_sec * 1000 + solver_finish_ms.tv_usec / 1000; solver_ms -= solver_start_ms.tv_sec * 1000 + solver_start_ms.tv_usec / 1000; cout << "\nsolver finished in " << solver_ms << " milliseconds\n"; total_time_in_smt_solver = total_time_in_smt_solver + solver_ms; total_time_in_exactness_checking_in_cegar = total_time_in_exactness_checking_in_cegar + solver_ms; number_of_exactness_checking_in_cegar++; #endif #ifdef RECORD_KEEP fprintf(record_fp, "\t%d\t%d\t%d\t%d", maximum_length_of_connection_in_connection_based_scheme, number_of_connections_in_connection_based_scheme, number_of_connections_updated_in_iteration_in_connection_based_scheme, number_of_literals_dropped_by_unsat_core); number_of_connections_updated_in_iteration_in_connection_based_scheme = 0; fprintf(record_fp, "\n\n%d\t%llu(%llu,%llu)(%d)\t", cegar_iteration_number, solver_ms, cnf_time, simplification_time, formula_size); #endif #ifdef DEBUG_SKOLEM displayModelFromSATSolver(Model_of_ExactnessCheck); cout << endl << "result_of_exactnesscheck = " << result_of_exactnesscheck << endl; #endif removeTemporaryVariablesFromModel(Model_of_ExactnessCheck); #ifdef DEBUG_CEGAR cout << "\nModel after removing temporary variables\n"; displayModelFromSATSolver(Model_of_ExactnessCheck); cout << endl << "result_of_exactnesscheck = " << result_of_exactnesscheck << endl; #endif if(result_of_exactnesscheck) // skolem functions inexact { #ifdef RECORD_KEEP fclose(record_fp); #endif return false; } else // ExactnessCheck unsat with the uniformity condition { // call sat solver without the uniformity conditions // we just need to change the assumptions // Obtain the assumptions positive_assumptions_in_exactness_check.clear(); negative_assumptions_in_exactness_check.clear(); obtainAssumptionsInExactnessCheck(positive_assumptions_in_exactness_check, negative_assumptions_in_exactness_check, true, false);// get assumptions such that all uniformity_conditions are OFF assert(positive_assumptions_in_exactness_check.size() != 0); assert(negative_assumptions_in_exactness_check.size() != 0); // Use incremental solver call #ifdef DEBUG_CEGAR cout << endl << "Calling SAT-Solver without the uniformity condition\n"; #endif #ifdef DETAILED_RECORD_KEEP gettimeofday (&solver_start_ms, NULL); #endif // Give to SAT-Solver and get unsat / sat with model Aig_Obj_t* true_dag = createTrue(pub_aig_manager); result_of_exactnesscheck = isExactnessCheckSatisfiable(pub_aig_manager, true_dag, Model_of_ExactnessCheck, cnf_time, formula_size, simplification_time, positive_assumptions_in_exactness_check, negative_assumptions_in_exactness_check, pSat_for_exactness_check, IncrementalLabelTableForExactnessCheck, IncrementalLabelCountForExactnessCheck, Ci_name_to_Ci_label_mapForExactnessCheck, Ci_label_to_Ci_name_mapForExactnessCheck); #ifdef DETAILED_RECORD_KEEP gettimeofday (&solver_finish_ms, NULL); solver_ms = solver_finish_ms.tv_sec * 1000 + solver_finish_ms.tv_usec / 1000; solver_ms -= solver_start_ms.tv_sec * 1000 + solver_start_ms.tv_usec / 1000; cout << "\nsolver finished in " << solver_ms << " milliseconds\n"; total_time_in_smt_solver = total_time_in_smt_solver + solver_ms; total_time_in_exactness_checking_in_cegar = total_time_in_exactness_checking_in_cegar + solver_ms; number_of_exactness_checking_in_cegar++; #endif #ifdef RECORD_KEEP fprintf(record_fp, "+%llu(%llu,%llu)(%d)\t", solver_ms, cnf_time, simplification_time, formula_size); fclose(record_fp); #endif #ifdef DEBUG_SKOLEM displayModelFromSATSolver(Model_of_ExactnessCheck); cout << endl << "result_of_exactnesscheck = " << result_of_exactnesscheck << endl; #endif removeTemporaryVariablesFromModel(Model_of_ExactnessCheck); #ifdef DEBUG_CEGAR cout << "\nModel after removing temporary variables\n"; displayModelFromSATSolver(Model_of_ExactnessCheck); cout << endl << "result_of_exactnesscheck = " << result_of_exactnesscheck << endl; #endif if(!result_of_exactnesscheck) // ExactnessCheck unsat i.e. skolem functions exact { return true; } else // ExactnessCheck sat i.e. skolem functions inexact { return false; } }// ExactnessCheck unsat with the uniformity condition }//if(apply_uniformity_in_cex_generation) ends here else { // dags for updated skolem function are created assert(delta_epsilon_i_components.size() > 0); delta_epsilon_i = createAnd(delta_epsilon_i_components, pub_aig_manager); assert(delta_epsilon_i != NULL); // call sat_solver_solve and return the model // Obtain the assumptions vector positive_assumptions_in_exactness_check; vector negative_assumptions_in_exactness_check; obtainAssumptionsInExactnessCheck(positive_assumptions_in_exactness_check, negative_assumptions_in_exactness_check, false, false); assert(positive_assumptions_in_exactness_check.size() != 0); assert(negative_assumptions_in_exactness_check.size() == 0); // Use incremental solver call #ifdef DEBUG_CEGAR cout << endl << "Calling SAT-Solver under assumptions\n"; #endif #ifdef DETAILED_RECORD_KEEP unsigned long long int solver_ms; struct timeval solver_start_ms, solver_finish_ms; gettimeofday (&solver_start_ms, NULL); #endif // Give to SAT-Solver and get unsat / sat with model unsigned long long int cnf_time; int formula_size; unsigned long long int simplification_time; bool result_of_exactnesscheck = isExactnessCheckSatisfiable(pub_aig_manager, delta_epsilon_i, Model_of_ExactnessCheck, cnf_time, formula_size, simplification_time, positive_assumptions_in_exactness_check, negative_assumptions_in_exactness_check, pSat_for_exactness_check, IncrementalLabelTableForExactnessCheck, IncrementalLabelCountForExactnessCheck, Ci_name_to_Ci_label_mapForExactnessCheck, Ci_label_to_Ci_name_mapForExactnessCheck); #ifdef DETAILED_RECORD_KEEP gettimeofday (&solver_finish_ms, NULL); solver_ms = solver_finish_ms.tv_sec * 1000 + solver_finish_ms.tv_usec / 1000; solver_ms -= solver_start_ms.tv_sec * 1000 + solver_start_ms.tv_usec / 1000; cout << "\nsolver finished in " << solver_ms << " milliseconds\n"; total_time_in_smt_solver = total_time_in_smt_solver + solver_ms; total_time_in_exactness_checking_in_cegar = total_time_in_exactness_checking_in_cegar + solver_ms; number_of_exactness_checking_in_cegar++; #endif #ifdef RECORD_KEEP fprintf(record_fp, "\t%d\t%d\t%d\t%d", maximum_length_of_connection_in_connection_based_scheme, number_of_connections_in_connection_based_scheme, number_of_connections_updated_in_iteration_in_connection_based_scheme, number_of_literals_dropped_by_unsat_core); number_of_connections_updated_in_iteration_in_connection_based_scheme = 0; fprintf(record_fp, "\n\n%d\t%llu(%llu,%llu)(%d)\t", cegar_iteration_number, solver_ms, cnf_time, simplification_time, formula_size); fclose(record_fp); #endif #ifdef DEBUG_SKOLEM displayModelFromSATSolver(Model_of_ExactnessCheck); cout << endl << "result_of_exactnesscheck = " << result_of_exactnesscheck << endl; #endif removeTemporaryVariablesFromModel(Model_of_ExactnessCheck); #ifdef DEBUG_CEGAR cout << "\nModel after removing temporary variables\n"; displayModelFromSATSolver(Model_of_ExactnessCheck); cout << endl << "result_of_exactnesscheck = " << result_of_exactnesscheck << endl; #endif if(!result_of_exactnesscheck) // ExactnessCheck unsat i.e. skolem functions exact { return true; } else // skolem functions inexact { return false; } }//else of if(apply_uniformity_in_cex_generation) ends here }//if(use_incremental_sat_solving) ends here else { // Create the dag for epsilon_i // F(X',Y) \wedge (B1\vee ... \vee B_n \vee B_{n+1}) \wedge // (B_1 = bad_set_1) \wedge ... \wedge (B_n = bad_set_n) \wedge (B_{n+1} = bad_set_{n+1}) \wedge // (x_1 = psi_1) \wedge ... \wedge (x_n = psi_n) // dag for F(X',Y) is already created in renamed_conjunction_of_factors // dag for (B1\vee ... \vee B_n \vee B_{n+1}) is already created in disjunction_of_bad_symbols // dag for (B_1 = bad_set_1) \wedge ... \wedge (B_n = bad_set_n) \wedge (B_{n+1} = bad_set_{n+1}) is already created in B_equivalence_part // Let's first create dag for (x_1 = psi_1) \wedge ... \wedge (x_n = psi_n) Aig_Obj_t* S_equivalence_part; set S_equivalence_objects; for(int var_to_elim_index = 1; var_to_elim_index <= number_of_vars_to_elim; var_to_elim_index++) { // obtaining dag for x_i string var_to_elim = searchVarIndexToVarNameMap(var_index_to_var_name_map, var_to_elim_index); map::iterator Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it = Ci_to_eliminate_name_to_Ci_to_eliminate_object_map.find(var_to_elim); assert(Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it != Ci_to_eliminate_name_to_Ci_to_eliminate_object_map.end()); Aig_Obj_t* var_to_elim_obj = Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it->second; // obtaining \psi_i Aig_Obj_t* skolem_function; skolem_function = searchOneDimensionalMatrix(SkolemFunctions, number_of_vars_to_elim, var_to_elim_index); assert(skolem_function != NULL); Aig_Obj_t* S_equivalence_i = createEquivalence(skolem_function, var_to_elim_obj, pub_aig_manager); S_equivalence_objects.insert(S_equivalence_i); } assert(!S_equivalence_objects.empty()); S_equivalence_part = createAnd(S_equivalence_objects, pub_aig_manager); assert(S_equivalence_part != NULL); #ifdef DEBUG_SKOLEM string S_equivalence_part_file_name = benchmark_name_without_extension; S_equivalence_part_file_name += "_S_equivalence_part"; cout << "\nS_equivalence_part computed\n"; writeFormulaToFile(pub_aig_manager, S_equivalence_part, S_equivalence_part_file_name, ".v", 0, cegar_iteration_number); #endif set epsilon_i_objects; assert(renamed_conjunction_of_factors != NULL); epsilon_i_objects.insert(renamed_conjunction_of_factors); assert(disjunction_of_bad_symbols != NULL); epsilon_i_objects.insert(disjunction_of_bad_symbols); assert(B_equivalence_part != NULL); epsilon_i_objects.insert(B_equivalence_part); epsilon_i_objects.insert(S_equivalence_part); epsilon_i = createAnd(epsilon_i_objects, pub_aig_manager); assert(epsilon_i != NULL); // Give epsilon_i to SAT-Solver #ifdef DEBUG_CEGAR cout << endl << "Giving epsilon_i to SAT-Solver\n"; #endif #ifdef DETAILED_RECORD_KEEP unsigned long long int solver_ms; struct timeval solver_start_ms, solver_finish_ms; gettimeofday (&solver_start_ms, NULL); #endif // Give to SAT-Solver and get unsat / sat with model unsigned long long int cnf_time; int formula_size; unsigned long long int simplification_time; bool result_of_exactnesscheck = isSat(pub_aig_manager, epsilon_i, Model_of_ExactnessCheck, cnf_time, formula_size, simplification_time); #ifdef DETAILED_RECORD_KEEP gettimeofday (&solver_finish_ms, NULL); solver_ms = solver_finish_ms.tv_sec * 1000 + solver_finish_ms.tv_usec / 1000; solver_ms -= solver_start_ms.tv_sec * 1000 + solver_start_ms.tv_usec / 1000; cout << "\nsolver finished in " << solver_ms << " milliseconds\n"; total_time_in_smt_solver = total_time_in_smt_solver + solver_ms; total_time_in_exactness_checking_in_cegar = total_time_in_exactness_checking_in_cegar + solver_ms; number_of_exactness_checking_in_cegar++; #endif #ifdef RECORD_KEEP fprintf(record_fp, "\t%d\t%d\t%d\t%d", maximum_length_of_connection_in_connection_based_scheme, number_of_connections_in_connection_based_scheme, number_of_connections_updated_in_iteration_in_connection_based_scheme, number_of_literals_dropped_by_unsat_core); number_of_connections_updated_in_iteration_in_connection_based_scheme = 0; fprintf(record_fp, "\n\n%d\t%llu(%llu,%llu)(%d)\t", cegar_iteration_number, solver_ms, cnf_time, simplification_time, formula_size); fclose(record_fp); #endif #ifdef DEBUG_SKOLEM displayModelFromSATSolver(Model_of_ExactnessCheck); cout << endl << "result_of_exactnesscheck = " << result_of_exactnesscheck << endl; #endif #ifdef DEBUG_CEGAR cout << endl << "result_of_exactnesscheck = " << result_of_exactnesscheck << endl; #endif if(!result_of_exactnesscheck) // ExactnessCheck unsat i.e. skolem functions exact { return true; } else // skolem functions inexact { return false; } } //else of if(use_incremental_sat_solving) ends here } // if(cegar_iteration_number > 0) ends here } Aig_Obj_t* AIGBasedSkolem::replaceVariablesByConstants(Aig_Obj_t* OriginalFormula, map &replacement_map) { Aig_Obj_t* original_formula = OriginalFormula; for(map::iterator map_it = replacement_map.begin(); map_it != replacement_map.end(); map_it++) { int var_index_to_replace = map_it->first; int constant_to_substitute = map_it->second; assert(original_formula != NULL); assert(constant_to_substitute == 0 || constant_to_substitute == 1); Aig_Obj_t* replaced_formula = replaceVariableByConstant(original_formula, var_index_to_replace, constant_to_substitute); original_formula = replaced_formula; } return original_formula; } Aig_Obj_t* AIGBasedSkolem::createAssignment(map &x_replacement_map) { set assignment_objects; for(map::iterator yvalues_it = values_of_Y_variables.begin(); yvalues_it != values_of_Y_variables.end(); yvalues_it++) { string variable_name = yvalues_it->first; int variable_value = yvalues_it->second; Aig_Obj_t* variable_object; map::iterator Ci_name_to_Ci_object_map_it = Ci_name_to_Ci_object_map.find(variable_name); if(Ci_name_to_Ci_object_map_it == Ci_name_to_Ci_object_map.end()) { cout << "\nNo entry for " << variable_name << " in Ci_name_to_Ci_object_map\n"; assert(false); } variable_object = Ci_name_to_Ci_object_map_it->second; if(variable_value == 0) // variable_value is false { // negate variable_object variable_object = createNot(variable_object, pub_aig_manager); } assignment_objects.insert(variable_object); } for(map::iterator x_replacement_map_it = x_replacement_map.begin(); x_replacement_map_it != x_replacement_map.end(); x_replacement_map_it++) { int variable_index = x_replacement_map_it->first; int variable_value = x_replacement_map_it->second; string variable_name = searchVarIndexToVarNameMap(var_index_to_var_name_map, variable_index); Aig_Obj_t* variable_object; map::iterator Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it = Ci_to_eliminate_name_to_Ci_to_eliminate_object_map.find(variable_name); assert(Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it != Ci_to_eliminate_name_to_Ci_to_eliminate_object_map.end()); variable_object = Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it->second; if(variable_value == 0) // variable_value is false { // negate variable_object variable_object = createNot(variable_object, pub_aig_manager); } assignment_objects.insert(variable_object); } assert(!assignment_objects.empty()); Aig_Obj_t* assignment = createAnd(assignment_objects, pub_aig_manager); assert(assignment != NULL); return assignment; } void AIGBasedSkolem::analyzeReasonBehindMismatch(int bad_index, int variable_index, map &bad_to_var_replacement_map, map &below_var_replacement_map) { map variable_to_value_map; for(map::iterator yvalues_it = values_of_Y_variables.begin(); yvalues_it != values_of_Y_variables.end(); yvalues_it++) { bool bool_value; if(yvalues_it->second == 1) { bool_value = true; } else { bool_value = false; } variable_to_value_map.insert(make_pair(yvalues_it->first, bool_value)); } for(int var_to_elim_index = number_of_vars_to_elim; var_to_elim_index > variable_index; var_to_elim_index--) { string var_to_elim = searchVarIndexToVarNameMap(var_index_to_var_name_map, var_to_elim_index); int value = below_var_replacement_map[var_to_elim_index]; bool bool_value; if(value == 1) { bool_value = true; } else { bool_value = false; } variable_to_value_map.insert(make_pair(var_to_elim, bool_value)); } for(int var_to_elim_index = variable_index; var_to_elim_index >= bad_index; var_to_elim_index--) { string var_to_elim = searchVarIndexToVarNameMap(var_index_to_var_name_map, var_to_elim_index); int value = bad_to_var_replacement_map[var_to_elim_index]; bool bool_value; if(value == 1) { bool_value = true; } else { bool_value = false; } variable_to_value_map.insert(make_pair(var_to_elim, bool_value)); } for(int var_to_elim_index = bad_index; var_to_elim_index <= variable_index; var_to_elim_index++) { Aig_Obj_t* alpha_i; alpha_i = searchOneDimensionalMatrix(AlphaCombineds, number_of_vars_to_elim, var_to_elim_index); assert(alpha_i != NULL); bool value_of_alpha_i = evaluateFormulaOfCi(alpha_i, variable_to_value_map); Aig_Obj_t* gamma_i; gamma_i = searchOneDimensionalMatrix(GammaCombineds, number_of_vars_to_elim, var_to_elim_index); assert(gamma_i != NULL); bool value_of_gamma_i = evaluateFormulaOfCi(gamma_i, variable_to_value_map); Aig_Obj_t* skolem_i; skolem_i = searchOneDimensionalMatrix(SkolemFunctions, number_of_vars_to_elim, var_to_elim_index); assert(skolem_i != NULL); bool value_of_skolem_i = evaluateFormulaOfCi(skolem_i, variable_to_value_map); cout << "\n" << "x[" << var_to_elim_index << "] = " << bad_to_var_replacement_map[var_to_elim_index]; cout << "\t" << "alpha[" << var_to_elim_index << "] = " << value_of_alpha_i; cout << "\t" << "gamma[" << var_to_elim_index << "] = " << value_of_gamma_i; cout << "\t" << "skolem[" << var_to_elim_index << "] = " << value_of_skolem_i; } } Aig_Obj_t* AIGBasedSkolem::createUnsatCoreBasedAssignment(map &x_replacement_map, int one_variable_index, int &number_of_literals_dropped_by_unsat_core) { set positive_variables; set negative_variables; for(map::iterator yvalues_it = values_of_Y_variables.begin(); yvalues_it != values_of_Y_variables.end(); yvalues_it++) { string variable_name = yvalues_it->first; int variable_value = yvalues_it->second; Aig_Obj_t* variable_object; map::iterator Ci_name_to_Ci_object_map_it = Ci_name_to_Ci_object_map.find(variable_name); assert(Ci_name_to_Ci_object_map_it != Ci_name_to_Ci_object_map.end()); variable_object = Ci_name_to_Ci_object_map_it->second; if(variable_value == 0) // variable_value is false { negative_variables.insert(variable_object); } else { positive_variables.insert(variable_object); } number_of_literals_dropped_by_unsat_core++; } for(map::iterator x_replacement_map_it = x_replacement_map.begin(); x_replacement_map_it != x_replacement_map.end(); x_replacement_map_it++) { int variable_index = x_replacement_map_it->first; int variable_value = x_replacement_map_it->second; string variable_name = searchVarIndexToVarNameMap(var_index_to_var_name_map, variable_index); Aig_Obj_t* variable_object; map::iterator Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it = Ci_to_eliminate_name_to_Ci_to_eliminate_object_map.find(variable_name); assert(Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it != Ci_to_eliminate_name_to_Ci_to_eliminate_object_map.end()); variable_object = Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it->second; if(variable_value == 0) // variable_value is false { negative_variables.insert(variable_object); } else { positive_variables.insert(variable_object); } number_of_literals_dropped_by_unsat_core++; } string one_variable_name = searchVarIndexToVarNameMap(var_index_to_var_name_map, one_variable_index); Aig_Obj_t* one_variable_object; map::iterator Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it = Ci_to_eliminate_name_to_Ci_to_eliminate_object_map.find(one_variable_name); assert(Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it != Ci_to_eliminate_name_to_Ci_to_eliminate_object_map.end()); one_variable_object = Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it->second; positive_variables.insert(one_variable_object); set variables_in_unsat_core; unsatCore(pub_aig_manager, conjunction_of_factors, positive_variables, negative_variables, variables_in_unsat_core); assert(!variables_in_unsat_core.empty()); //#ifdef DEBUG_CEGAR showSet(variables_in_unsat_core, "variables_in_unsat_core"); //#endif //#ifdef DEBUG_CEGAR cout << "\nvariables_in_unsat_core intersect variables_in_assignment\n"; //#endif set assignment_objects; for(map::iterator yvalues_it = values_of_Y_variables.begin(); yvalues_it != values_of_Y_variables.end(); yvalues_it++) { string variable_name = yvalues_it->first; int variable_value = yvalues_it->second; if(variables_in_unsat_core.find(variable_name) == variables_in_unsat_core.end())//not in unsat core { continue; } //#ifdef DEBUG_CEGAR cout << endl << variable_name << " with value " << variable_value << endl; //#endif Aig_Obj_t* variable_object; map::iterator Ci_name_to_Ci_object_map_it = Ci_name_to_Ci_object_map.find(variable_name); assert(Ci_name_to_Ci_object_map_it != Ci_name_to_Ci_object_map.end()); variable_object = Ci_name_to_Ci_object_map_it->second; if(variable_value == 0) // variable_value is false { // negate variable_object variable_object = createNot(variable_object, pub_aig_manager); } assignment_objects.insert(variable_object); number_of_literals_dropped_by_unsat_core--; } for(map::iterator x_replacement_map_it = x_replacement_map.begin(); x_replacement_map_it != x_replacement_map.end(); x_replacement_map_it++) { int variable_index = x_replacement_map_it->first; int variable_value = x_replacement_map_it->second; string variable_name = searchVarIndexToVarNameMap(var_index_to_var_name_map, variable_index); if(variables_in_unsat_core.find(variable_name) == variables_in_unsat_core.end())//not in unsat core { continue; } //#ifdef DEBUG_CEGAR cout << endl << variable_name << " with value " << variable_value << endl; //#endif Aig_Obj_t* variable_object; map::iterator Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it = Ci_to_eliminate_name_to_Ci_to_eliminate_object_map.find(variable_name); assert(Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it != Ci_to_eliminate_name_to_Ci_to_eliminate_object_map.end()); variable_object = Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it->second; if(variable_value == 0) // variable_value is false { // negate variable_object variable_object = createNot(variable_object, pub_aig_manager); } assignment_objects.insert(variable_object); number_of_literals_dropped_by_unsat_core--; } assert(!assignment_objects.empty()); Aig_Obj_t* assignment = createAnd(assignment_objects, pub_aig_manager); assert(assignment != NULL); bool crosscheck_unsat_core_computation = false; if(crosscheck_unsat_core_computation) { Aig_Obj_t* crosscheck_unsat_core_dag = createAnd(assignment, one_variable_object, pub_aig_manager); crosscheck_unsat_core_dag = createAnd(crosscheck_unsat_core_dag, conjunction_of_factors, pub_aig_manager); map Temp_Model; unsigned long long int temp_cnf_time; int temp_formula_size; unsigned long long int temp_simplification_time; bool sat_of_crosscheck_unsat_core_dag = isSat(pub_aig_manager, crosscheck_unsat_core_dag, Temp_Model, temp_cnf_time, temp_formula_size, temp_simplification_time); assert(!sat_of_crosscheck_unsat_core_dag); cout << "\ncrosscheck succeeded\n"; } return assignment; } Aig_Obj_t* AIGBasedSkolem::createUniformityCondition() { string Pi_string = obtainPVariableString(uniformity_condition_counter); // obtain the string P_i Aig_Obj_t* Pi_object = obtainObjectOfTemporaryVariableForIncrementalSolving(Pi_string); // create object P_i assert(Pi_object != NULL); string Qi_string = obtainQVariableString(uniformity_condition_counter); // obtain the string Q_i Aig_Obj_t* Qi_object = obtainObjectOfTemporaryVariableForIncrementalSolving(Qi_string); // create object Q_i assert(Qi_object != NULL); uniformity_condition_counter++; string Piplus1_string = obtainPVariableString(uniformity_condition_counter); // obtain the string P_{i+1} Aig_Obj_t* Piplus1_object = obtainObjectOfTemporaryVariableForIncrementalSolving(Piplus1_string); // create object P_{i+1} assert(Piplus1_object != NULL); // create dag for Ui i.e. the actual uniformity-imposing condition Aig_Obj_t* Ui_dag = createUniformityConditionDag(); assert(Ui_dag != NULL); // create dag for "Pi_object = ite(Qi_object, Ui_dag, Piplus1_object)" Aig_Obj_t* uniformity_condition = createEquivalence(Pi_object, createIte(Qi_object, Ui_dag, Piplus1_object, pub_aig_manager), pub_aig_manager); assert(uniformity_condition != NULL); if(uniformity_condition_counter == 2) // for the first uniformity-imposing condition { uniformity_condition = createAnd(uniformity_condition, Pi_object, pub_aig_manager); assert(uniformity_condition != NULL); } #ifdef DEBUG_CEGAR cout << endl << "dag for " << Pi_string << " created\n"; #endif #ifdef DEBUG_SKOLEM string uniformity_condition_file_name = benchmark_name_without_extension; uniformity_condition_file_name += "_uniformity_condition_"; writeFormulaToFile(pub_aig_manager, uniformity_condition, uniformity_condition_file_name, ".v", uniformity_condition_counter-1, 0); #endif return uniformity_condition; } string AIGBasedSkolem::obtainPVariableString(int p_count) { // Return the string P_{p_count} string P_string = "P_"; char p_count_char[100]; sprintf(p_count_char, "%d", p_count); string p_count_string(p_count_char); P_string += p_count_string; return P_string; } string AIGBasedSkolem::obtainQVariableString(int p_count) { // Return the string Q_{p_count} string Q_string = "Q_"; char p_count_char[100]; sprintf(p_count_char, "%d", p_count); string p_count_string(p_count_char); Q_string += p_count_string; return Q_string; } Aig_Obj_t* AIGBasedSkolem::createUniformityConditionDag() { // choose N random pairs of (a_i, b_i) variables from X'\union Y, // i.e. from the support of F(X', Y). // return conjunction of equalities/disequalities(choice is random) between a_i and b_i assert(renamed_conjunction_of_factors != NULL); set X_New_Y; computeSupport(renamed_conjunction_of_factors, X_New_Y, pub_aig_manager); int X_New_Y_Size; X_New_Y_Size = X_New_Y.size(); double temp = (fraction_of_variables_in_uniformity_condition * X_New_Y_Size); int number_of_variables_to_choose = (int) temp; if (temp - (double) number_of_variables_to_choose >= 0.5) { number_of_variables_to_choose++; } if(number_of_variables_to_choose % 2 == 1) // to keep number_of_variables_to_choose as even { number_of_variables_to_choose--; } #ifdef DEBUG_SKOLEM cout << "\nnumber_of_variables_to_choose = " << number_of_variables_to_choose << endl; #endif // Let us randomly choose 'number_of_variables_to_choose' variables from X_New_Y vector X_New_Y_Vector(X_New_Y.begin(), X_New_Y.end()); set indices_chosen; int maximum_index = X_New_Y_Size - 1; #ifdef DEBUG_SKOLEM cout << "\nmaximum_index = " << maximum_index << endl; #endif srand(time(NULL)); for(int var_it = 0; var_it < number_of_variables_to_choose; var_it++) { //choose a variable from X_New_Y randomly int index_chosen; do { index_chosen = (int) ((rand0to1) * maximum_index); }while(indices_chosen.find(index_chosen) != indices_chosen.end()); #ifdef DEBUG_SKOLEM cout << "\nindex_chosen = " << index_chosen << endl; #endif assert(index_chosen >= 0 && index_chosen <= maximum_index); indices_chosen.insert(index_chosen); } vector variables_chosen; #ifdef DEBUG_SKOLEM cout << "\nvariables_chosen\n"; #endif for(set::iterator indices_chosen_it = indices_chosen.begin(); indices_chosen_it != indices_chosen.end(); indices_chosen_it++) { int index_chosen = *indices_chosen_it; assert(index_chosen >= 0 && index_chosen <= maximum_index); string variable_chosen = X_New_Y_Vector[index_chosen]; variables_chosen.push_back(variable_chosen); #ifdef DEBUG_SKOLEM cout << variable_chosen << endl; #endif } assert(variables_chosen.size() == number_of_variables_to_choose); Aig_Obj_t* UniformityConditionDag; set UniformityConditionDagComponents; int first_variable_it = 0; int second_variable_it = 1; #ifdef DEBUG_SKOLEM cout << "\nPairs of variables\n"; #endif while( first_variable_it <= number_of_variables_to_choose-2) { string first_variable = variables_chosen[first_variable_it]; string second_variable = variables_chosen[second_variable_it]; #ifdef DEBUG_SKOLEM cout << "( " << first_variable <<", " << second_variable << " )\n"; #endif Aig_Obj_t* first_object; Aig_Obj_t* second_object; map::iterator name_object_map_it = Ci_name_to_Ci_object_map.find(first_variable); if(name_object_map_it != Ci_name_to_Ci_object_map.end()) { first_object = name_object_map_it->second; } else { name_object_map_it = Ci_to_eliminate_renamed_name_to_Ci_to_eliminate_renamed_object_map.find(first_variable); assert(name_object_map_it != Ci_to_eliminate_renamed_name_to_Ci_to_eliminate_renamed_object_map.end()); first_object = name_object_map_it->second; } name_object_map_it = Ci_name_to_Ci_object_map.find(second_variable); if(name_object_map_it != Ci_name_to_Ci_object_map.end()) { second_object = name_object_map_it->second; } else { name_object_map_it = Ci_to_eliminate_renamed_name_to_Ci_to_eliminate_renamed_object_map.find(second_variable); assert(name_object_map_it != Ci_to_eliminate_renamed_name_to_Ci_to_eliminate_renamed_object_map.end()); second_object = name_object_map_it->second; } // toss a coin to decide between disquality and equality between first_object and second_object Aig_Obj_t* constraint_on_variables; if ((rand0to1) > 0.5) { #ifdef DEBUG_SKOLEM cout << "\nconstraint chosen is equality\n"; #endif constraint_on_variables = createEquivalence(first_object, second_object, pub_aig_manager); } else { #ifdef DEBUG_SKOLEM cout << "\nconstraint chosen is disequality\n"; #endif constraint_on_variables = createExor(first_object, second_object, pub_aig_manager); } assert(constraint_on_variables != NULL); UniformityConditionDagComponents.insert(constraint_on_variables); first_variable_it = first_variable_it + 2; second_variable_it = second_variable_it + 2; } UniformityConditionDag = createAnd(UniformityConditionDagComponents, pub_aig_manager); assert(UniformityConditionDag != NULL); #ifdef DEBUG_SKOLEM string uniformity_condition_dag_file_name = benchmark_name_without_extension; uniformity_condition_dag_file_name += "_uniformity_condition_dag_"; writeFormulaToFile(pub_aig_manager, UniformityConditionDag, uniformity_condition_dag_file_name, ".v", uniformity_condition_counter-1, 0); #endif return UniformityConditionDag; } Aig_Obj_t* AIGBasedSkolem::computeInitialSkolemFunctionsAndCannotBeSets(int var_to_elim_index) { Aig_Obj_t* skolem_function; set skolem_function_components; set cannot_be_one_set_for_var_to_elim_index; set cannot_be_zero_set_for_var_to_elim_index; Aig_Obj_t* skolem_function_part1; Aig_Obj_t* skolem_function_part2; set skolem_function_part1_components; set skolem_function_part2_components; for(set::iterator factor_it = FactorsWithVariable.begin(); factor_it != FactorsWithVariable.end(); factor_it++) { int factor_index = *factor_it; #ifdef DEBUG_SKOLEM cout << "\nfactor_index = " << factor_index << endl; #endif Aig_Obj_t* neg_cofactor_1 = computeNegatedCofactorOne(var_to_elim_index, factor_index); assert(neg_cofactor_1 != NULL); sizes_of_cannot_be_one_elements_of_variable.push_back(computeSize(neg_cofactor_1, pub_aig_manager)); // connecting to some output to avoid unwanted deletion Aig_Obj_t* neg_cofactor_1_CO = Aig_ObjCreateCo(pub_aig_manager, neg_cofactor_1 ); assert(neg_cofactor_1_CO != NULL); Aig_Obj_t* neg_cofactor_0 = computeNegatedCofactorZero(var_to_elim_index, factor_index); assert(neg_cofactor_0 != NULL); sizes_of_cannot_be_zero_elements_of_variable.push_back(computeSize(neg_cofactor_0, pub_aig_manager)); // connect to some output to avoid unwanted deletion Aig_Obj_t* neg_cofactor_0_CO = Aig_ObjCreateCo(pub_aig_manager, neg_cofactor_0 ); assert(neg_cofactor_0_CO != NULL); #ifdef DEBUG_SKOLEM writeFormulaToFile(pub_aig_manager, neg_cofactor_1, "neg_cofactor_1", ".v", var_to_elim_index, factor_index); writeFormulaToFile(pub_aig_manager, neg_cofactor_0, "neg_cofactor_0", ".v", var_to_elim_index, factor_index); #endif // Allocate strings and objects for the dags neg_cofactor_1 and neg_cofactor_0 string cannot_be_one_string; Aig_Obj_t* cannot_be_one_object; allocateStringAndObjectToCannotBeDag(1, neg_cofactor_1, cannot_be_one_string, cannot_be_one_object); string cannot_be_zero_string; Aig_Obj_t* cannot_be_zero_object; allocateStringAndObjectToCannotBeDag(0, neg_cofactor_0, cannot_be_zero_string, cannot_be_zero_object); #ifdef DEBUG_SKOLEM show_cannot_be_string_to_cannot_be_object_map(); show_cannot_be_object_to_cannot_be_dag_map(); #endif // Insert the objects in respective cannot-be-sets cannot_be_one_set_for_var_to_elim_index.insert(cannot_be_one_object); cannot_be_zero_set_for_var_to_elim_index.insert(cannot_be_zero_object); if(use_initial_cannot_be_zero_in_psi_in_mu_based_scheme_in_cegar) { // Insert the cannot-be-1 dag into the skolem_function_part1_components skolem_function_part1_components.insert(neg_cofactor_1); // Insert the cannot-be-0 dag into the skolem_function_part2_components skolem_function_part2_components.insert(neg_cofactor_0); } else { // Insert the cannot-be-1 dag into the skolem_function_components skolem_function_components.insert(neg_cofactor_1); } }// for each factor ends here if(checkTimeOut()) // check for time-out { cout << "\nWarning!!Time-out inside the function AIGBasedSkolem::computeInitialSkolemFunctionsAndCannotBeSets\n"; timed_out = true; // timed_out flag set return NULL; } map >::iterator cannot_be_one_set_it = cannot_be_one_set.find(var_to_elim_index); assert(cannot_be_one_set_it == cannot_be_one_set.end()); cannot_be_one_set.insert(make_pair(var_to_elim_index, cannot_be_one_set_for_var_to_elim_index)); map >::iterator cannot_be_zero_set_it = cannot_be_zero_set.find(var_to_elim_index); assert(cannot_be_zero_set_it == cannot_be_zero_set.end()); cannot_be_zero_set.insert(make_pair(var_to_elim_index, cannot_be_zero_set_for_var_to_elim_index)); if(use_initial_cannot_be_zero_in_psi_in_mu_based_scheme_in_cegar) { // Let's compute the skolem_function // skolem_function is // disjunction of elements in cannot_be_one_set_for_var_to_elim_index \vee // negation of (disjunction of elements in cannot_be_one_set_for_var_to_elim_index) if(cannot_be_one_set_for_var_to_elim_index.empty()) // no condition under which it can't be 1 // i.e. it can be 1 always { skolem_function_part1 = createTrue(pub_aig_manager); } else { skolem_function_part1 = createOr(skolem_function_part1_components, pub_aig_manager); skolem_function_part1 = createNot(skolem_function_part1, pub_aig_manager); } assert(skolem_function_part1 != NULL); if(cannot_be_zero_set_for_var_to_elim_index.empty()) // no condition under which it can't be 0 // i.e. it can be 0 always { skolem_function_part2 = createFalse(pub_aig_manager); } else { skolem_function_part2 = createOr(skolem_function_part2_components, pub_aig_manager); } assert(skolem_function_part2 != NULL); skolem_function = createOr(skolem_function_part2, skolem_function_part1, pub_aig_manager); assert(skolem_function != NULL); // connect to some output to avoid unwanted deletion Aig_Obj_t* skolem_function_part2_CO = Aig_ObjCreateCo(pub_aig_manager, skolem_function_part2 ); assert(skolem_function_part2_CO != NULL); Aig_Obj_t* skolem_function_CO = Aig_ObjCreateCo(pub_aig_manager, skolem_function ); assert(skolem_function_CO != NULL); } else { // Let's compute the skolem_function // skolem_function is negation of (disjunction of elements in cannot_be_one_set_for_var_to_elim_index) if(cannot_be_one_set_for_var_to_elim_index.empty()) // no condition under which it can't be 1 // i.e. it can be 1 always { skolem_function = createTrue(pub_aig_manager); } else { skolem_function = createOr(skolem_function_components, pub_aig_manager); skolem_function = createNot(skolem_function, pub_aig_manager); } assert(skolem_function != NULL); // connect to some output to avoid unwanted deletion Aig_Obj_t* skolem_function_CO = Aig_ObjCreateCo(pub_aig_manager, skolem_function ); assert(skolem_function_CO != NULL); } #ifdef DEBUG_SKOLEM cout << "\nabstract skolem_function computed\n"; #endif #ifdef PRINT_SKOLEM_FUNCTIONS string skolem_function_file_name = benchmark_name_without_extension; skolem_function_file_name += "_skolem_function"; writeFormulaToFile(pub_aig_manager, skolem_function, skolem_function_file_name, ".v", var_to_elim_index, cegar_iteration_number); #endif // Enter into matrix insertIntoOneDimensionalMatrix(SkolemFunctions, number_of_vars_to_elim, var_to_elim_index, skolem_function, false); if(use_initial_cannot_be_zero_in_psi_in_mu_based_scheme_in_cegar) { // Compute ICb0_k in terms of objects and as dag // These will be required while recomputing the Skolem functions // Let's compute these right now, since later on these sets will get changed // we already have ICb0_k dag; let's insert it map::iterator initial_cannot_be_zero_dags_it = initial_cannot_be_zero_dags.find(var_to_elim_index); assert(initial_cannot_be_zero_dags_it == initial_cannot_be_zero_dags.end()); initial_cannot_be_zero_dags.insert(make_pair(var_to_elim_index, skolem_function_part2)); // Let's compute the ICb0_k object Aig_Obj_t* initial_cannot_be_zero_object; if(cannot_be_zero_set_for_var_to_elim_index.empty()) // no condition under which it can't be 0 // i.e. it can be 0 always { initial_cannot_be_zero_object = createFalse(pub_aig_manager); } else { initial_cannot_be_zero_object = createOr(cannot_be_zero_set_for_var_to_elim_index, pub_aig_manager); } assert(initial_cannot_be_zero_object != NULL); // connect to some output to avoid unwanted deletion Aig_Obj_t* initial_cannot_be_zero_object_CO = Aig_ObjCreateCo(pub_aig_manager, initial_cannot_be_zero_object ); assert(initial_cannot_be_zero_object_CO != NULL); // let's insert it map::iterator initial_cannot_be_zero_objects_it = initial_cannot_be_zero_objects.find(var_to_elim_index); assert(initial_cannot_be_zero_objects_it == initial_cannot_be_zero_objects.end()); initial_cannot_be_zero_objects.insert(make_pair(var_to_elim_index, initial_cannot_be_zero_object)); } if(use_disjunction_of_bads_in_mu_based_scheme_in_cegar) { // Compute Badsets if(var_to_elim_index < number_of_vars_to_elim) // No need to compute Bad_{n+1} { set alpha_components; set beta_components; for(set::iterator factor_it = FactorsWithVariable.begin(); factor_it != FactorsWithVariable.end(); factor_it++) { int factor_index = *factor_it; #ifdef DEBUG_SKOLEM cout << "\nfactor_index = " << factor_index << endl; #endif // Suppose j = factor_index // Get alpha_i_j and beta_i_j Aig_Obj_t* alpha_i_j; alpha_i_j = computeAlpha(var_to_elim_index, factor_index); assert(alpha_i_j != NULL); #ifdef DEBUG_SKOLEM writeFormulaToFile(pub_aig_manager, alpha_i_j, "alpha", ".v", var_to_elim_index, factor_index); cout << "\nalpha_" << var_to_elim_index << "_" << factor_index << " obtained\n"; #endif Aig_Obj_t* beta_i_j; beta_i_j = computeBeta(var_to_elim_index, factor_index); assert(beta_i_j != NULL); #ifdef DEBUG_SKOLEM writeFormulaToFile(pub_aig_manager, beta_i_j, "beta", ".v", var_to_elim_index, factor_index); cout << "\nbeta_" << var_to_elim_index << "_" << factor_index << " obtained\n"; #endif alpha_components.insert(alpha_i_j); beta_components.insert(beta_i_j); }// for each factor ends here if(checkTimeOut()) // check for time-out { cout << "\nWarning!!Time-out inside the function AIGBasedSkolem::computeInitialSkolemFunctionsAndCannotBeSets\n"; timed_out = true; // timed_out flag set return NULL; } Aig_Obj_t* alpha_part; if(alpha_components.size() == 0) // we should return false in this case (as per defn. of alpha) { alpha_part = createFalse(pub_aig_manager); assert(alpha_part != NULL); } else { alpha_part = createOr(alpha_components, pub_aig_manager); assert(alpha_part != NULL); } Aig_Obj_t* beta_part; if(beta_components.size() == 0) // we should return false in this case (as per defn. of beta) { beta_part = createFalse(pub_aig_manager); assert(beta_part != NULL); } else { beta_part = createOr(beta_components, pub_aig_manager); assert(beta_part != NULL); } Aig_Obj_t* bad_set_for_next_var; bad_set_for_next_var = createAnd(alpha_part, beta_part, pub_aig_manager); assert(bad_set_for_next_var != NULL); // connect to some output to avoid unwanted deletion Aig_Obj_t* bad_set_for_next_var_CO = Aig_ObjCreateCo(pub_aig_manager, bad_set_for_next_var ); assert(bad_set_for_next_var_CO != NULL); #ifdef DEBUG_SKOLEM cout << "\nbad_set_" << var_to_elim_index+1 << " computed\n"; writeFormulaToFile(pub_aig_manager, bad_set_for_next_var, "bad_set", ".v", var_to_elim_index+1, cegar_iteration_number); #endif // Enter into matrix insertIntoOneDimensionalMatrix(BadSets, number_of_vars_to_elim, var_to_elim_index+1, bad_set_for_next_var, false); CorrectionPartSize = computeSize(bad_set_for_next_var, pub_aig_manager); } else { CorrectionPartSize = -1; } #ifdef PRINT_VERY_DETAILED_RECORDS_ON_SCREEN cout << "\nsize of bad_set_" << var_to_elim_index+1 << " is " << CorrectionPartSize << endl; #endif if(checkTimeOut()) // check for time-out { cout << "\nWarning!!Time-out inside the function AIGBasedSkolem::computeInitialSkolemFunctionsAndCannotBeSets\n"; timed_out = true; // timed_out flag set return NULL; } }//if(use_disjunction_of_bads_in_mu_based_scheme_in_cegar) ends here return skolem_function; } void AIGBasedSkolem::allocateStringAndObjectToCannotBeDag(int kind_of_cannot_be, Aig_Obj_t* cannot_be_dag, string &cannot_be_string, Aig_Obj_t* &cannot_be_object) { // create the cannot_be_string if(kind_of_cannot_be == 1) { cannot_be_string = "sigma_"; cannot_be_one_count++; char count_char[100]; sprintf(count_char, "%d", cannot_be_one_count); string count_string(count_char); cannot_be_string += count_string; } else if(kind_of_cannot_be == 0) { cannot_be_string = "eta_"; cannot_be_zero_count++; char count_char[100]; sprintf(count_char, "%d", cannot_be_zero_count); string count_string(count_char); cannot_be_string += count_string; } else { cout << "\nUnknown value " << kind_of_cannot_be << " for kind_of_cannot_be in AIGBasedSkolem::allocateStringAndObjectToCannotBeDag\n"; assert(false); } // ensure that cannot_be_object does not exist map::iterator cannot_be_string_to_cannot_be_object_map_it = cannot_be_string_to_cannot_be_object_map.find(cannot_be_string); assert(cannot_be_string_to_cannot_be_object_map_it == cannot_be_string_to_cannot_be_object_map.end()); // creating cannot_be_object and allocating cannot_be_string --> cannot_be_object cannot_be_object = Aig_ObjCreateCi(pub_aig_manager); assert(cannot_be_object != NULL); int cannot_be_object_id = Aig_ObjId(cannot_be_object); Ci_id_to_Ci_name_map.insert(make_pair(cannot_be_object_id, cannot_be_string)); Ci_name_to_Ci_number_map.insert(make_pair(cannot_be_string, number_of_Cis)); cannot_be_string_to_cannot_be_object_map.insert(make_pair(cannot_be_string, cannot_be_object)); number_of_Cis++; // creating cannot_be_object --> cannot_be_dag cannot_be_object_to_cannot_be_dag_map.insert(make_pair(cannot_be_object, cannot_be_dag)); } bool AIGBasedSkolem::checkIfSkolemFunctionsAreExact_using_Generic_Skolem_Functions(map &Model_of_ExactnessCheck, map &Refinement_Hint_Of_CannotBe_One_To_Eliminate_This_CEX, map &Refinement_Hint_Of_CannotBe_Zero_To_Eliminate_This_CEX, list &VariablesToEliminate) { #ifdef RECORD_KEEP string record_file; record_file = logfile_prefix; record_file += "skolem_function_generation_details.txt"; FILE* record_fp = fopen(record_file.c_str(), "a+"); assert(record_fp != NULL); #endif if(cegar_iteration_number == 0) { Aig_Obj_t* epsilon_zero; // Create the dag for epsilon_zero: // F(X',Y) \wedge // (x_1 = psi_1) \wedge ... \wedge (x_n = psi_n) \wedge // ~F(X, Y) if use_disjunction_of_bads_in_mu_based_scheme_in_cegar = false // (disjunction of bads) if use_disjunction_of_bads_in_mu_based_scheme_in_cegar = true // dag for F(X',Y) is already created in renamed_conjunction_of_factors // dag for F(X, Y) is already created in conjunction_of_factors // we need to create psi_i as the negation of disjunction of elements in cannot-be-one-set[i] // Let's first create dag for (Cb_one_1 = dag for Cb_one_1) \wedge ... \wedge (Cb_one_l = dag for Cb_one_l) \wedge // (Cb_zero_1 = dag for Cb_zero_1) \wedge ... \wedge (Cb_zero_s = dag for Cb_zero_s) // in Cb_part Aig_Obj_t* Cb_part; set Cb_objects; for(map::iterator cannot_be_object_to_cannot_be_dag_map_it = cannot_be_object_to_cannot_be_dag_map.begin(); cannot_be_object_to_cannot_be_dag_map_it != cannot_be_object_to_cannot_be_dag_map.end(); cannot_be_object_to_cannot_be_dag_map_it++) { Aig_Obj_t* cannot_be_object = cannot_be_object_to_cannot_be_dag_map_it->first; assert(cannot_be_object != NULL); Aig_Obj_t* cannot_be_dag = cannot_be_object_to_cannot_be_dag_map_it->second; assert(cannot_be_dag != NULL); Aig_Obj_t* Cb_equivalence = createEquivalence(cannot_be_object, cannot_be_dag, pub_aig_manager); Cb_objects.insert(Cb_equivalence); } assert(!Cb_objects.empty()); Cb_part = createAnd(Cb_objects, pub_aig_manager); assert(Cb_part != NULL); // connect to some output to avoid unwanted deletion Aig_Obj_t* Cb_part_CO = Aig_ObjCreateCo(pub_aig_manager, Cb_part ); assert(Cb_part_CO != NULL); // Let's create dag for (x_1 = psi_1) \wedge ... \wedge (x_n = psi_n) Aig_Obj_t* S_equivalence_part; set S_equivalence_objects; if(use_initial_cannot_be_zero_in_psi_in_mu_based_scheme_in_cegar) { // we need to create psi_i as disjunction of elements in initial_cannot_be_zero_objects[i] // \vee negation of disjunction of elements in cannot-be-one-set[i] for(map >::iterator cannot_be_one_set_it = cannot_be_one_set.begin(); cannot_be_one_set_it != cannot_be_one_set.end(); cannot_be_one_set_it++) { int var_to_elim_index = cannot_be_one_set_it->first; // obtaining dag for x_i string var_to_elim = searchVarIndexToVarNameMap(var_index_to_var_name_map, var_to_elim_index); map::iterator Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it = Ci_to_eliminate_name_to_Ci_to_eliminate_object_map.find(var_to_elim); assert(Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it != Ci_to_eliminate_name_to_Ci_to_eliminate_object_map.end()); Aig_Obj_t* var_to_elim_obj = Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it->second; // obtaining \psi_i_part2 Aig_Obj_t* psi_i_part2; set psi_i_part2_components = cannot_be_one_set_it->second; if(psi_i_part2_components.empty()) { psi_i_part2 = createTrue(pub_aig_manager); } else { psi_i_part2 = createOr(psi_i_part2_components, pub_aig_manager); psi_i_part2 = createNot(psi_i_part2, pub_aig_manager); } assert(psi_i_part2 != NULL); // initialize Z_variable_counter[var_to_elim_index] to 0 Z_variable_counter.insert(make_pair(var_to_elim_index, 0)); int z_i_count = Z_variable_counter[var_to_elim_index]; // 0 here string z_i_string = obtainZVariableString(var_to_elim_index, z_i_count); // obtain the string Z_{var_to_elim_index}_0 // check if object for z_i_string is already existing; if yes return it; otherwise create, // update temporary_variable_for_incremental_solving_to_object_map and return Aig_Obj_t* z_i_object = obtainObjectOfTemporaryVariableForIncrementalSolving(z_i_string); assert(z_i_object != NULL); psi_i_part2 = createAnd(psi_i_part2, z_i_object, pub_aig_manager); assert(psi_i_part2 != NULL); // obtaining \psi_i_part1 Aig_Obj_t* psi_i_part1; map::iterator initial_cannot_be_zero_objects_it = initial_cannot_be_zero_objects.find(var_to_elim_index); assert(initial_cannot_be_zero_objects_it != initial_cannot_be_zero_objects.end()); psi_i_part1 = initial_cannot_be_zero_objects_it->second; assert(psi_i_part1 != NULL); // obtaining \psi_i Aig_Obj_t* psi_i; psi_i = createOr(psi_i_part1, psi_i_part2, pub_aig_manager); assert(psi_i != NULL); Aig_Obj_t* S_equivalence_i = createEquivalence(var_to_elim_obj, psi_i, pub_aig_manager); S_equivalence_objects.insert(S_equivalence_i); } } else { for(map >::iterator cannot_be_one_set_it = cannot_be_one_set.begin(); cannot_be_one_set_it != cannot_be_one_set.end(); cannot_be_one_set_it++) { int var_to_elim_index = cannot_be_one_set_it->first; // obtaining dag for x_i string var_to_elim = searchVarIndexToVarNameMap(var_index_to_var_name_map, var_to_elim_index); map::iterator Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it = Ci_to_eliminate_name_to_Ci_to_eliminate_object_map.find(var_to_elim); assert(Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it != Ci_to_eliminate_name_to_Ci_to_eliminate_object_map.end()); Aig_Obj_t* var_to_elim_obj = Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it->second; // obtaining \psi_i Aig_Obj_t* psi_i; set psi_i_components = cannot_be_one_set_it->second; if(psi_i_components.empty()) { psi_i = createTrue(pub_aig_manager); } else { psi_i = createOr(psi_i_components, pub_aig_manager); psi_i = createNot(psi_i, pub_aig_manager); } assert(psi_i != NULL); // initialize Z_variable_counter[var_to_elim_index] to 0 Z_variable_counter.insert(make_pair(var_to_elim_index, 0)); int z_i_count = Z_variable_counter[var_to_elim_index]; // 0 here string z_i_string = obtainZVariableString(var_to_elim_index, z_i_count); // obtain the string Z_{var_to_elim_index}_0 // check if object for z_i_string is already existing; if yes return it; otherwise create, // update temporary_variable_for_incremental_solving_to_object_map and return Aig_Obj_t* z_i_object = obtainObjectOfTemporaryVariableForIncrementalSolving(z_i_string); assert(z_i_object != NULL); psi_i = createAnd(psi_i, z_i_object, pub_aig_manager); assert(psi_i != NULL); Aig_Obj_t* S_equivalence_i = createEquivalence(var_to_elim_obj, psi_i, pub_aig_manager); S_equivalence_objects.insert(S_equivalence_i); } }//else ends here assert(!S_equivalence_objects.empty()); S_equivalence_part = createAnd(S_equivalence_objects, pub_aig_manager); assert(S_equivalence_part != NULL); // connect to some output to avoid unwanted deletion Aig_Obj_t* S_equivalence_part_CO = Aig_ObjCreateCo(pub_aig_manager, S_equivalence_part ); assert(S_equivalence_part_CO != NULL); #ifdef DEBUG_SKOLEM string Cb_part_file_name = benchmark_name_without_extension; Cb_part_file_name += "_Cb_part"; string S_equivalence_part_file_name = benchmark_name_without_extension; S_equivalence_part_file_name += "_S_equivalence_part"; cout << "\nCb_part computed\n"; cout << "\nS_equivalence_part computed\n"; writeFormulaToFile(pub_aig_manager, Cb_part, Cb_part_file_name, ".v", cegar_iteration_number, 0); writeFormulaToFile(pub_aig_manager, S_equivalence_part, S_equivalence_part_file_name, ".v", cegar_iteration_number, 0); #endif Aig_Obj_t* negated_conjunction_of_factors; if(use_disjunction_of_bads_in_mu_based_scheme_in_cegar) { set B_equivalence_objects; for(int bad_location_index = 1; bad_location_index <= number_of_vars_to_elim; bad_location_index++) { // Let bad_location_index be i // Obtaining dag for bad_set_i Aig_Obj_t* bad_set_obj; bad_set_obj = searchOneDimensionalMatrix(BadSets, number_of_vars_to_elim, bad_location_index); assert(bad_set_obj != NULL); // Obtaining dag for B_i map::iterator B_i_index_to_B_i_object_map_iterator = B_i_index_to_B_i_object_map.find(bad_location_index); assert(B_i_index_to_B_i_object_map_iterator != B_i_index_to_B_i_object_map.end()); Aig_Obj_t* B_obj = B_i_index_to_B_i_object_map_iterator->second; Aig_Obj_t* B_equivalence_i = createEquivalence(bad_set_obj, B_obj, pub_aig_manager); B_equivalence_objects.insert(B_equivalence_i); } assert(!B_equivalence_objects.empty()); Aig_Obj_t* B_equivalence_part = createAnd(B_equivalence_objects, pub_aig_manager); assert(B_equivalence_part != NULL); negated_conjunction_of_factors = createAnd(disjunction_of_bad_symbols, B_equivalence_part, pub_aig_manager); #ifdef DEBUG_SKOLEM string B_equivalence_part_file_name = benchmark_name_without_extension; B_equivalence_part_file_name += "_B_equivalence_part"; cout << "\nB_equivalence_part computed\n"; writeFormulaToFile(pub_aig_manager, B_equivalence_part, B_equivalence_part_file_name, ".v", cegar_iteration_number, 0); #endif } else { negated_conjunction_of_factors = createNot(conjunction_of_factors, pub_aig_manager); assert(negated_conjunction_of_factors != NULL); } set epsilon_zero_objects; epsilon_zero_objects.insert(renamed_conjunction_of_factors); epsilon_zero_objects.insert(negated_conjunction_of_factors); epsilon_zero_objects.insert(S_equivalence_part); epsilon_zero_objects.insert(Cb_part); epsilon_zero = createAnd(epsilon_zero_objects, pub_aig_manager); assert(epsilon_zero != NULL); // connect to some output to avoid unwanted deletion Aig_Obj_t* epsilon_zero_CO = Aig_ObjCreateCo(pub_aig_manager, epsilon_zero ); assert(epsilon_zero_CO != NULL); // Identify labels of Z_1_0 ,..., Z_n_0 and // assume that they are true (in positive_assumptions_in_exactness_check) vector positive_assumptions_in_exactness_check; vector negative_assumptions_in_exactness_check; obtainAssumptionsInExactnessCheck_using_Generic_Skolem_Functions(positive_assumptions_in_exactness_check); assert(positive_assumptions_in_exactness_check.size() != 0); // Use incremental solver call #ifdef DEBUG_CEGAR cout << endl << "Adding clauses of epsilon_zero to SAT-Solver, and calling SAT-Solver\n"; #endif #ifdef DETAILED_RECORD_KEEP unsigned long long int solver_ms; struct timeval solver_start_ms, solver_finish_ms; gettimeofday (&solver_start_ms, NULL); #endif // Give to SAT-Solver and get unsat / sat with model unsigned long long int cnf_time; int formula_size; unsigned long long int simplification_time; bool result_of_exactnesscheck = isExactnessCheckSatisfiable(pub_aig_manager, epsilon_zero, Model_of_ExactnessCheck, cnf_time, formula_size, simplification_time, positive_assumptions_in_exactness_check, negative_assumptions_in_exactness_check, pSat_for_exactness_check, IncrementalLabelTableForExactnessCheck, IncrementalLabelCountForExactnessCheck, Ci_name_to_Ci_label_mapForExactnessCheck, Ci_label_to_Ci_name_mapForExactnessCheck); #ifdef DETAILED_RECORD_KEEP gettimeofday (&solver_finish_ms, NULL); solver_ms = solver_finish_ms.tv_sec * 1000 + solver_finish_ms.tv_usec / 1000; solver_ms -= solver_start_ms.tv_sec * 1000 + solver_start_ms.tv_usec / 1000; cout << "\nsolver finished in " << solver_ms << " milliseconds\n"; total_time_in_smt_solver = total_time_in_smt_solver + solver_ms; total_time_in_exactness_checking_in_cegar = total_time_in_exactness_checking_in_cegar + solver_ms; number_of_exactness_checking_in_cegar++; #endif #ifdef RECORD_KEEP fprintf(record_fp, "\t%llu(%llu,%llu)(%d)", solver_ms, cnf_time, simplification_time, formula_size); fclose(record_fp); #endif #ifdef DEBUG_SKOLEM displayModelFromSATSolver(Model_of_ExactnessCheck); cout << endl << "result_of_exactnesscheck = " << result_of_exactnesscheck << endl; #endif removeTemporaryVariablesFromModel(Model_of_ExactnessCheck); #ifdef DEBUG_CEGAR cout << "\nModel after removing temporary variables\n"; displayModelFromSATSolver(Model_of_ExactnessCheck); cout << endl << "result_of_exactnesscheck = " << result_of_exactnesscheck << endl; #endif if(!result_of_exactnesscheck) // ExactnessCheck unsat i.e. skolem functions exact { return true; } else // skolem functions inexact { return false; } } // if(cegar_iteration_number == 0) ends here else // if(cegar_iteration_number > 0) { #ifdef DEBUG_CEGAR show_present_refinement_hint(Refinement_Hint_Of_CannotBe_One_To_Eliminate_This_CEX, Refinement_Hint_Of_CannotBe_Zero_To_Eliminate_This_CEX); #endif Aig_Obj_t* delta_epsilon_i; // Create the dag for delta_epsilon_i: // (o_j = dag_j) \wedge ;for each o_j added in Refinement_Hint_Of_CannotBe_One_To_Eliminate_This_CEX // (Z_i_k = Z_i_{k+1} \wedge o_j) \wedge // (o_l = dag_l) ;for each o_l added in Refinement_Hint_Of_CannotBe_Zero_To_Eliminate_This_CEX Aig_Obj_t* Cb_part; set Cb_objects; Aig_Obj_t* Z_part; set Z_objects; for(map::iterator hint_it = Refinement_Hint_Of_CannotBe_One_To_Eliminate_This_CEX.begin(); hint_it != Refinement_Hint_Of_CannotBe_One_To_Eliminate_This_CEX.end(); hint_it++) { int destination = hint_it->first; Aig_Obj_t* new_cannot_be_one_object_at_destination = hint_it->second; map::iterator cannot_be_object_to_cannot_be_dag_map_it = cannot_be_object_to_cannot_be_dag_map.find(new_cannot_be_one_object_at_destination); assert(cannot_be_object_to_cannot_be_dag_map_it != cannot_be_object_to_cannot_be_dag_map.end()); Aig_Obj_t* new_cannot_be_one_dag_at_destination = cannot_be_object_to_cannot_be_dag_map_it->second; Aig_Obj_t* Cb_one_equivalence = createEquivalence(new_cannot_be_one_object_at_destination, new_cannot_be_one_dag_at_destination, pub_aig_manager); assert(Cb_one_equivalence != NULL); Cb_objects.insert(Cb_one_equivalence); int present_z_j_k_count = Z_variable_counter[destination]; int next_z_j_k_count = present_z_j_k_count + 1; Z_variable_counter[destination] = next_z_j_k_count; string present_z_j_k_string = obtainZVariableString(destination, present_z_j_k_count); // obtain the string Z_{destination}_{present_z_j_k_count} Aig_Obj_t* present_z_j_k_object = obtainExistingObjectOfTemporaryVariableForIncrementalSolving(present_z_j_k_string); assert(present_z_j_k_object != NULL); string next_z_j_k_string = obtainZVariableString(destination, next_z_j_k_count); // obtain the string Z_{destination}_{next_z_j_k_count} Aig_Obj_t* next_z_j_k_object = obtainObjectOfTemporaryVariableForIncrementalSolving(next_z_j_k_string); assert(next_z_j_k_object != NULL); Aig_Obj_t* R_i_j_increment = createEquivalence(present_z_j_k_object, createAnd(createNot(new_cannot_be_one_object_at_destination, pub_aig_manager), next_z_j_k_object, pub_aig_manager), pub_aig_manager); assert(R_i_j_increment != NULL); Z_objects.insert(R_i_j_increment); } for(map::iterator hint_it = Refinement_Hint_Of_CannotBe_Zero_To_Eliminate_This_CEX.begin(); hint_it != Refinement_Hint_Of_CannotBe_Zero_To_Eliminate_This_CEX.end(); hint_it++) { int destination = hint_it->first; Aig_Obj_t* new_cannot_be_zero_object_at_destination = hint_it->second; map::iterator cannot_be_object_to_cannot_be_dag_map_it = cannot_be_object_to_cannot_be_dag_map.find(new_cannot_be_zero_object_at_destination); assert(cannot_be_object_to_cannot_be_dag_map_it != cannot_be_object_to_cannot_be_dag_map.end()); Aig_Obj_t* new_cannot_be_zero_dag_at_destination = cannot_be_object_to_cannot_be_dag_map_it->second; Aig_Obj_t* Cb_zero_equivalence = createEquivalence(new_cannot_be_zero_object_at_destination, new_cannot_be_zero_dag_at_destination, pub_aig_manager); assert(Cb_zero_equivalence != NULL); Cb_objects.insert(Cb_zero_equivalence); } assert(!Cb_objects.empty()); Cb_part = createAnd(Cb_objects, pub_aig_manager); assert(Cb_part != NULL); // connect to some output to avoid unwanted deletion Aig_Obj_t* Cb_part_CO = Aig_ObjCreateCo(pub_aig_manager, Cb_part ); assert(Cb_part_CO != NULL); assert(!Z_objects.empty()); Z_part = createAnd(Z_objects, pub_aig_manager); assert(Z_part != NULL); // connect to some output to avoid unwanted deletion Aig_Obj_t* Z_part_CO = Aig_ObjCreateCo(pub_aig_manager, Z_part ); assert(Z_part_CO != NULL); #ifdef DEBUG_SKOLEM string Cb_part_file_name = benchmark_name_without_extension; Cb_part_file_name += "_Cb_part"; string Z_part_file_name = benchmark_name_without_extension; Z_part_file_name += "_Z_part"; cout << "\nCb_part computed\n"; cout << "\nZ_part computed\n"; writeFormulaToFile(pub_aig_manager, Cb_part, Cb_part_file_name, ".v", cegar_iteration_number, 0); writeFormulaToFile(pub_aig_manager, Z_part, Z_part_file_name, ".v", cegar_iteration_number, 0); #endif delta_epsilon_i = createAnd(Cb_part, Z_part, pub_aig_manager); assert(delta_epsilon_i != NULL); // connect to some output to avoid unwanted deletion Aig_Obj_t* delta_epsilon_i_CO = Aig_ObjCreateCo(pub_aig_manager, delta_epsilon_i ); assert(delta_epsilon_i_CO != NULL); // Identify labels of Z_1_k ,..., Z_n_k and // assume that they are true (in positive_assumptions_in_exactness_check) vector positive_assumptions_in_exactness_check; vector negative_assumptions_in_exactness_check; obtainAssumptionsInExactnessCheck_using_Generic_Skolem_Functions(positive_assumptions_in_exactness_check); assert(positive_assumptions_in_exactness_check.size() != 0); // Use incremental solver call #ifdef DEBUG_CEGAR cout << endl << "Adding clauses of delta_epsilon_i to SAT-Solver, and calling SAT-Solver\n"; #endif #ifdef DETAILED_RECORD_KEEP unsigned long long int solver_ms; struct timeval solver_start_ms, solver_finish_ms; gettimeofday (&solver_start_ms, NULL); #endif // Give to SAT-Solver and get unsat / sat with model unsigned long long int cnf_time; int formula_size; unsigned long long int simplification_time; bool result_of_exactnesscheck = isExactnessCheckSatisfiable(pub_aig_manager, delta_epsilon_i, Model_of_ExactnessCheck, cnf_time, formula_size, simplification_time, positive_assumptions_in_exactness_check, negative_assumptions_in_exactness_check, pSat_for_exactness_check, IncrementalLabelTableForExactnessCheck, IncrementalLabelCountForExactnessCheck, Ci_name_to_Ci_label_mapForExactnessCheck, Ci_label_to_Ci_name_mapForExactnessCheck); #ifdef DETAILED_RECORD_KEEP gettimeofday (&solver_finish_ms, NULL); solver_ms = solver_finish_ms.tv_sec * 1000 + solver_finish_ms.tv_usec / 1000; solver_ms -= solver_start_ms.tv_sec * 1000 + solver_start_ms.tv_usec / 1000; cout << "\nsolver finished in " << solver_ms << " milliseconds\n"; total_time_in_smt_solver = total_time_in_smt_solver + solver_ms; total_time_in_exactness_checking_in_cegar = total_time_in_exactness_checking_in_cegar + solver_ms; number_of_exactness_checking_in_cegar++; #endif #ifdef RECORD_KEEP fprintf(record_fp, "\t%llu(%llu,%llu)(%d)", solver_ms, cnf_time, simplification_time, formula_size); fclose(record_fp); #endif #ifdef DEBUG_SKOLEM displayModelFromSATSolver(Model_of_ExactnessCheck); cout << endl << "result_of_exactnesscheck = " << result_of_exactnesscheck << endl; #endif removeTemporaryVariablesFromModel(Model_of_ExactnessCheck); #ifdef DEBUG_CEGAR cout << "\nModel after removing temporary variables\n"; displayModelFromSATSolver(Model_of_ExactnessCheck); cout << endl << "result_of_exactnesscheck = " << result_of_exactnesscheck << endl; #endif if(!result_of_exactnesscheck) // ExactnessCheck unsat i.e. skolem functions exact { return true; } else // skolem functions inexact { return false; } } // if(cegar_iteration_number > 0) ends here } void AIGBasedSkolem::obtainAssumptionsInExactnessCheck_using_Generic_Skolem_Functions(vector &positive_assumptions_in_exactness_check) { // positive_assumptions_in_exactness_check includes // Z_i_j for each i = variable_to_eliminate and j = Z_variable_counter[i] for(int var_to_elim_index = 1; var_to_elim_index <= number_of_vars_to_elim; var_to_elim_index++) { map::iterator Z_variable_counter_it = Z_variable_counter.find(var_to_elim_index); assert(Z_variable_counter_it != Z_variable_counter.end()); int z_i_count = Z_variable_counter_it->second; string z_i_string = obtainZVariableString(var_to_elim_index, z_i_count); // obtain the string Z_{var_to_elim_index}_{z_i_count} Aig_Obj_t* z_i_object = obtainExistingObjectOfTemporaryVariableForIncrementalSolving(z_i_string); assert(z_i_object != NULL); positive_assumptions_in_exactness_check.push_back(z_i_object); } } void AIGBasedSkolem::refineSkolemFunctions_using_Generic_Skolem_Functions(map &Model_of_ExactnessCheck, map &Refinement_Hint_Of_CannotBe_One_To_Eliminate_This_CEX, map &Refinement_Hint_Of_CannotBe_Zero_To_Eliminate_This_CEX) { #ifdef RECORD_KEEP string record_file; record_file = logfile_prefix; record_file += "skolem_function_generation_details.txt"; FILE* record_fp = fopen(record_file.c_str(), "a+"); assert(record_fp != NULL); #endif // For easy of processing let's create map XValues; // XValues[i] gives value of x_i map cannot_be_object_to_value_map; // maps object of eta_j or sigma_j to value map cannot_be_one_set_values; // cannot_be_one_set_values[i] gives value of cannot_be_one_set_values_i map cannot_be_zero_set_values; // cannot_be_zero_set_values[i] gives value of cannot_be_zero_set_values_i for(int var_to_elim_index = 1; var_to_elim_index <= number_of_vars_to_elim; var_to_elim_index++) { string var_to_elim = searchVarIndexToVarNameMap(var_index_to_var_name_map, var_to_elim_index); map::iterator Model_of_ExactnessCheck_it; Model_of_ExactnessCheck_it = Model_of_ExactnessCheck.find(var_to_elim); assert(Model_of_ExactnessCheck_it != Model_of_ExactnessCheck.end()); XValues.insert(make_pair(var_to_elim_index, Model_of_ExactnessCheck_it->second)); } for(map::iterator model_it = Model_of_ExactnessCheck.begin(); model_it != Model_of_ExactnessCheck.end(); model_it++) { string variable_name = model_it->first; int variable_value = model_it->second; map::iterator cannot_be_string_to_cannot_be_object_map_it = cannot_be_string_to_cannot_be_object_map.find(variable_name); if(cannot_be_string_to_cannot_be_object_map_it != cannot_be_string_to_cannot_be_object_map.end()) { Aig_Obj_t* cannot_be_object = cannot_be_string_to_cannot_be_object_map_it->second; cannot_be_object_to_value_map.insert(make_pair(cannot_be_object, variable_value)); } } for(map >::iterator cannot_be_one_set_it = cannot_be_one_set.begin(); cannot_be_one_set_it != cannot_be_one_set.end(); cannot_be_one_set_it++) { int var_to_elim_index = cannot_be_one_set_it->first; set cannot_be_one_set_of_variable = cannot_be_one_set_it->second; int value_of_cannot_be_one_set_of_variable = 0; for(set::iterator cannot_be_one_set_of_variable_it = cannot_be_one_set_of_variable.begin(); cannot_be_one_set_of_variable_it != cannot_be_one_set_of_variable.end(); cannot_be_one_set_of_variable_it++) { Aig_Obj_t* cannot_be_one_set_object_of_variable = *cannot_be_one_set_of_variable_it; map::iterator cannot_be_object_to_value_map_it = cannot_be_object_to_value_map.find(cannot_be_one_set_object_of_variable); assert(cannot_be_object_to_value_map_it != cannot_be_object_to_value_map.end()); int value_of_cannot_be_one_set_object_of_variable = cannot_be_object_to_value_map_it->second; if(value_of_cannot_be_one_set_object_of_variable == 1) { value_of_cannot_be_one_set_of_variable = value_of_cannot_be_one_set_object_of_variable; break; } } cannot_be_one_set_values.insert(make_pair(var_to_elim_index, value_of_cannot_be_one_set_of_variable)); } for(map >::iterator cannot_be_zero_set_it = cannot_be_zero_set.begin(); cannot_be_zero_set_it != cannot_be_zero_set.end(); cannot_be_zero_set_it++) { int var_to_elim_index = cannot_be_zero_set_it->first; set cannot_be_zero_set_of_variable = cannot_be_zero_set_it->second; int value_of_cannot_be_zero_set_of_variable = 0; for(set::iterator cannot_be_zero_set_of_variable_it = cannot_be_zero_set_of_variable.begin(); cannot_be_zero_set_of_variable_it != cannot_be_zero_set_of_variable.end(); cannot_be_zero_set_of_variable_it++) { Aig_Obj_t* cannot_be_zero_set_object_of_variable = *cannot_be_zero_set_of_variable_it; map::iterator cannot_be_object_to_value_map_it = cannot_be_object_to_value_map.find(cannot_be_zero_set_object_of_variable); assert(cannot_be_object_to_value_map_it != cannot_be_object_to_value_map.end()); int value_of_cannot_be_zero_set_object_of_variable = cannot_be_object_to_value_map_it->second; if(value_of_cannot_be_zero_set_object_of_variable == 1) { value_of_cannot_be_zero_set_of_variable = value_of_cannot_be_zero_set_object_of_variable; break; } } cannot_be_zero_set_values.insert(make_pair(var_to_elim_index, value_of_cannot_be_zero_set_of_variable)); } #ifdef DEBUG_CEGAR cout << endl; for(int var_to_elim_index = 1; var_to_elim_index <= number_of_vars_to_elim; var_to_elim_index++) { cout << endl << "XValues[" << var_to_elim_index << "] = " << XValues[var_to_elim_index]; } cout << endl; for(int var_to_elim_index = 1; var_to_elim_index <= number_of_vars_to_elim; var_to_elim_index++) { cout << endl << "cannot_be_one_set_values[" << var_to_elim_index << "] = " << cannot_be_one_set_values[var_to_elim_index]; } cout << endl; for(int var_to_elim_index = 1; var_to_elim_index <= number_of_vars_to_elim; var_to_elim_index++) { cout << endl << "cannot_be_zero_set_values[" << var_to_elim_index << "] = " << cannot_be_zero_set_values[var_to_elim_index]; } cout << endl; #endif // find origin = largest l s.t. both cannot_be_one_set_values[l] and cannot_be_zero_set_values[l] are true int origin = number_of_vars_to_elim; for(int var_to_elim_index = number_of_vars_to_elim; var_to_elim_index >= 1; var_to_elim_index--) { if(cannot_be_one_set_values[var_to_elim_index] == 1 && cannot_be_zero_set_values[var_to_elim_index] == 1) { origin = var_to_elim_index; break; } } assert(origin <= number_of_vars_to_elim-1); #ifdef DEBUG_CEGAR cout << "\norigin = " << origin << endl; #endif int number_of_cannot_be_one_elements_in_initial_mu; int number_of_cannot_be_zero_elements_in_initial_mu; int size_of_initial_mu; Aig_Obj_t* mu; mu = obtain_initial_mu(origin, cannot_be_object_to_value_map, number_of_cannot_be_one_elements_in_initial_mu, number_of_cannot_be_zero_elements_in_initial_mu, size_of_initial_mu); assert(mu != NULL); #ifdef RECORD_KEEP fprintf(record_fp, "\t(x@%d,%d+%d,%d)", origin, number_of_cannot_be_one_elements_in_initial_mu, number_of_cannot_be_zero_elements_in_initial_mu, size_of_initial_mu); #endif #ifdef DEBUG_CEGAR string mu_file_name = benchmark_name_without_extension; mu_file_name += "_mu"; cout << "\nInitial mu computed\n"; writeFormulaToFile(pub_aig_manager, mu, mu_file_name, ".v", cegar_iteration_number, origin); #endif int destination = origin + 1; #ifdef DEBUG_CEGAR cout << "\ndestination = " << destination << endl; #endif while(destination <= number_of_vars_to_elim) { if(!formulaFreeOfVariable(mu, destination)) // mu has x_destination in support { #ifdef DEBUG_SKOLEM cout << "\nmu has x_" << destination << " in its support\n"; #endif if(XValues[destination] == 1) // x_destination == 1 { #ifdef DEBUG_SKOLEM cout << "\nx_" << destination << " == 1\n"; #endif // assert (mu[x_destination --> 1]) // Let's obtain mu[x_destination --> 1] Aig_Obj_t* new_cannot_be_one_dag_at_destination; new_cannot_be_one_dag_at_destination = replaceVariableByConstant(mu, destination, 1); assert(new_cannot_be_one_dag_at_destination != NULL); // connecting to some output to avoid unwanted deletion Aig_Obj_t* new_cannot_be_one_dag_at_destination_CO = Aig_ObjCreateCo(pub_aig_manager, new_cannot_be_one_dag_at_destination); assert(new_cannot_be_one_dag_at_destination_CO != NULL); // First allocate string and object to new_cannot_be_one_dag_at_destination string cannot_be_one_string_at_destination; Aig_Obj_t* cannot_be_one_object_at_destination; allocateStringAndObjectToCannotBeDag(1, new_cannot_be_one_dag_at_destination, cannot_be_one_string_at_destination, cannot_be_one_object_at_destination); #ifdef DEBUG_SKOLEM cout << "\nnew_cannot_be_one_dag_at_destination for x_" << destination << " is obtained\n"; string new_cannot_be_one_dag_at_destination_file_name = benchmark_name_without_extension; new_cannot_be_one_dag_at_destination_file_name += "_new_cannot_be_one_dag_at_destination"; writeFormulaToFile(pub_aig_manager, new_cannot_be_one_dag_at_destination, new_cannot_be_one_dag_at_destination_file_name, ".v", destination, cegar_iteration_number); show_cannot_be_string_to_cannot_be_object_map(); show_cannot_be_object_to_cannot_be_dag_map(); #endif // Insert new_cannot_be_one_object_at_destination into cannot_be_one_set at destination cannot_be_one_set[destination].insert(cannot_be_one_object_at_destination); // Insert new_cannot_be_one_object_at_destination into Refinement_Hint_Of_CannotBe_One_To_Eliminate_This_CEX Refinement_Hint_Of_CannotBe_One_To_Eliminate_This_CEX.insert(make_pair(destination, cannot_be_one_object_at_destination)); #ifdef DEBUG_CEGAR cout << "\ncannot_be_one_set for x_" << destination << " is modified\n"; #endif // Conjoin ~new_cannot_be_one_object_at_destination to skolem_function at destination Aig_Obj_t* current_skolem_function_at_destination; current_skolem_function_at_destination = searchOneDimensionalMatrix(SkolemFunctions, number_of_vars_to_elim, destination); assert(current_skolem_function_at_destination != NULL); Aig_Obj_t* new_skolem_function_at_destination; if(use_initial_cannot_be_zero_in_psi_in_mu_based_scheme_in_cegar) { new_skolem_function_at_destination = createSkolemFunction_In_Mu_Based_Scheme_With_Optimizations(destination); // new_skolem_function_at_destination can be created from // cannot_be_one_set[destination] and initial_cannot_be_zero_dags[destination] } else { new_skolem_function_at_destination = createAnd(current_skolem_function_at_destination, createNot(new_cannot_be_one_dag_at_destination, pub_aig_manager), pub_aig_manager); } assert(new_skolem_function_at_destination != NULL); if(new_skolem_function_at_destination != current_skolem_function_at_destination) // skolem function is changed { // connecting to some output to avoid unwanted deletion Aig_Obj_t* new_skolem_function_at_destination_CO = Aig_ObjCreateCo( pub_aig_manager, new_skolem_function_at_destination); assert(new_skolem_function_at_destination_CO != NULL); // insert the new skolem function insertIntoOneDimensionalMatrix(SkolemFunctions, number_of_vars_to_elim, destination, new_skolem_function_at_destination, true); #ifdef DEBUG_CEGAR cout << "\nSkolem function for x_" << destination << " is modified\n"; string skolem_function_file_name = benchmark_name_without_extension; skolem_function_file_name += "_skolem_function"; writeFormulaToFile(pub_aig_manager, new_skolem_function_at_destination, skolem_function_file_name, ".v", destination, cegar_iteration_number); #endif } if(cannot_be_zero_set_values[destination] == 1) // Cb0_destination is true { #ifdef DEBUG_SKOLEM cout << "\ncannot_be_zero_set[" << destination << "] == 1\n"; #endif int number_of_cannot_be_zero_elements_that_are_true; int size_of_changed_mu; int size_of_new_element_added_to_cannot_be_one_set; int size_of_disjunction_of_true_cannot_be_zero_dags; Aig_Obj_t* disjunction_of_true_cannot_be_zero_dags = obtain_disjunction_of_true_cannot_be_zero_dags(destination, cannot_be_object_to_value_map, new_cannot_be_one_dag_at_destination, number_of_cannot_be_zero_elements_that_are_true); assert(disjunction_of_true_cannot_be_zero_dags != NULL); mu = createAnd(new_cannot_be_one_dag_at_destination, disjunction_of_true_cannot_be_zero_dags, pub_aig_manager); assert(mu != NULL); size_of_changed_mu = computeSize(mu, pub_aig_manager); size_of_new_element_added_to_cannot_be_one_set = computeSize(new_cannot_be_one_dag_at_destination, pub_aig_manager); size_of_disjunction_of_true_cannot_be_zero_dags = computeSize(disjunction_of_true_cannot_be_zero_dags, pub_aig_manager); #ifdef RECORD_KEEP fprintf(record_fp, "\t(x@%d=1,%d,%d,%d,%d)", destination, size_of_new_element_added_to_cannot_be_one_set, number_of_cannot_be_zero_elements_that_are_true, size_of_disjunction_of_true_cannot_be_zero_dags, size_of_changed_mu); #endif #ifdef DEBUG_CEGAR mu_file_name = benchmark_name_without_extension; mu_file_name += "_mu"; cout << "\nmu updated\n"; writeFormulaToFile(pub_aig_manager, mu, mu_file_name, ".v", cegar_iteration_number, destination); #endif } else { #ifdef DEBUG_SKOLEM cout << "\ncannot_be_zero_set[" << destination << "] == 0; refinement finished\n"; #endif int size_of_new_element_added_to_cannot_be_one_set; size_of_new_element_added_to_cannot_be_one_set = computeSize(new_cannot_be_one_dag_at_destination, pub_aig_manager); #ifdef RECORD_KEEP fprintf(record_fp, "\t(x@%d=1,%d,-,-)", destination, size_of_new_element_added_to_cannot_be_one_set); #endif break; } }// if(x_destination == 1) ends here else // if(x_destination == 0) { #ifdef DEBUG_SKOLEM cout << "\nx_" << destination << " == 0\n"; #endif // assert (mu[x_destination --> 0]) // Let's obtain mu[x_destination --> 0] Aig_Obj_t* new_cannot_be_zero_dag_at_destination; new_cannot_be_zero_dag_at_destination = replaceVariableByConstant(mu, destination, 0); assert(new_cannot_be_zero_dag_at_destination != NULL); // connecting to some output to avoid unwanted deletion Aig_Obj_t* new_cannot_be_zero_dag_at_destination_CO = Aig_ObjCreateCo(pub_aig_manager, new_cannot_be_zero_dag_at_destination); assert(new_cannot_be_zero_dag_at_destination_CO != NULL); int number_of_cannot_be_one_elements_that_are_true; int size_of_changed_mu; int size_of_new_element_added_to_cannot_be_zero_set; int size_of_disjunction_of_true_cannot_be_one_dags; if(accumulate_formulae_in_cbzero_in_cegar) { #ifdef DEBUG_SKOLEM cout << "\naccumulate_formulae_in_cbzero_in_cegar is true\n"; #endif // First allocate string and object to new_cannot_be_zero_dag_at_destination string cannot_be_zero_string_at_destination; Aig_Obj_t* cannot_be_zero_object_at_destination; allocateStringAndObjectToCannotBeDag(1, new_cannot_be_zero_dag_at_destination, cannot_be_zero_string_at_destination, cannot_be_zero_object_at_destination); #ifdef DEBUG_SKOLEM cout << "\nnew_cannot_be_zero_dag_at_destination for x_" << destination << " is obtained\n"; string new_cannot_be_zero_dag_at_destination_file_name = benchmark_name_without_extension; new_cannot_be_zero_dag_at_destination_file_name += "_new_cannot_be_zero_dag_at_destination"; writeFormulaToFile(pub_aig_manager, new_cannot_be_zero_dag_at_destination, new_cannot_be_zero_dag_at_destination_file_name, ".v", destination, cegar_iteration_number); show_cannot_be_string_to_cannot_be_object_map(); show_cannot_be_object_to_cannot_be_dag_map(); #endif // Insert new_cannot_be_zero_object_at_destination into cannot_be_zero_set at destination cannot_be_zero_set[destination].insert(cannot_be_zero_object_at_destination); // Insert new_cannot_be_zero_object_at_destination into Refinement_Hint_Of_CannotBe_Zero_To_Eliminate_This_CEX Refinement_Hint_Of_CannotBe_Zero_To_Eliminate_This_CEX.insert(make_pair(destination, cannot_be_zero_object_at_destination)); #ifdef DEBUG_CEGAR cout << "\ncannot_be_zero_set for x_" << destination << " is modified\n"; #endif size_of_new_element_added_to_cannot_be_zero_set = computeSize(new_cannot_be_zero_dag_at_destination, pub_aig_manager); } else { #ifdef DEBUG_SKOLEM cout << "\naccumulate_formulae_in_cbzero_in_cegar is false\n"; #endif size_of_new_element_added_to_cannot_be_zero_set = -1; } assert(cannot_be_one_set_values[destination] == 1); // Cb1_destination is true #ifdef DEBUG_SKOLEM cout << "\ncannot_be_one_set[" << destination << "] == 1\n"; #endif Aig_Obj_t* disjunction_of_true_cannot_be_one_dags = obtain_disjunction_of_true_cannot_be_one_dags(destination, cannot_be_object_to_value_map, new_cannot_be_zero_dag_at_destination, number_of_cannot_be_one_elements_that_are_true); assert(disjunction_of_true_cannot_be_one_dags != NULL); mu = createAnd(new_cannot_be_zero_dag_at_destination, disjunction_of_true_cannot_be_one_dags, pub_aig_manager); assert(mu != NULL); size_of_changed_mu = computeSize(mu, pub_aig_manager); size_of_disjunction_of_true_cannot_be_one_dags = computeSize(disjunction_of_true_cannot_be_one_dags, pub_aig_manager); #ifdef RECORD_KEEP fprintf(record_fp, "\t(x@%d=0,%d,%d,%d,%d)", destination, size_of_new_element_added_to_cannot_be_zero_set, number_of_cannot_be_one_elements_that_are_true, size_of_disjunction_of_true_cannot_be_one_dags, size_of_changed_mu); #endif #ifdef DEBUG_CEGAR mu_file_name = benchmark_name_without_extension; mu_file_name += "_mu"; cout << "\nmu updated\n"; writeFormulaToFile(pub_aig_manager, mu, mu_file_name, ".v", cegar_iteration_number, destination); #endif }// if(x_destination == 0) ends here }// mu has x_destination in support ends here destination = destination + 1; }// while(destination <= number_of_vars_to_elim) ends here assert(destination <= number_of_vars_to_elim); #ifdef RECORD_KEEP fclose(record_fp); #endif }// function ends here Aig_Obj_t* AIGBasedSkolem::obtain_initial_mu(int origin, map &cannot_be_object_to_value_map, int &number_of_cannot_be_one_elements_selected, int &number_of_cannot_be_zero_elements_selected, int &size_of_initial_mu) { int number_of_cannot_be_one_elements = 0; int number_of_cannot_be_zero_elements = 0; set dags_from_cannot_be_one_set; set dags_from_cannot_be_zero_set; map >::iterator cannot_be_one_set_it = cannot_be_one_set.find(origin); assert(cannot_be_one_set_it != cannot_be_one_set.end()); set cannot_be_one_set_of_variable = cannot_be_one_set_it->second; for(set::iterator cannot_be_one_set_of_variable_it = cannot_be_one_set_of_variable.begin(); cannot_be_one_set_of_variable_it != cannot_be_one_set_of_variable.end(); cannot_be_one_set_of_variable_it++) { Aig_Obj_t* cannot_be_one_set_object_of_variable = *cannot_be_one_set_of_variable_it; map::iterator cannot_be_object_to_cannot_be_dag_map_it = cannot_be_object_to_cannot_be_dag_map.find(cannot_be_one_set_object_of_variable); assert(cannot_be_object_to_cannot_be_dag_map_it != cannot_be_object_to_cannot_be_dag_map.end()); Aig_Obj_t* cannot_be_one_set_dag_of_variable = cannot_be_object_to_cannot_be_dag_map_it->second; map::iterator cannot_be_object_to_value_map_it = cannot_be_object_to_value_map.find(cannot_be_one_set_object_of_variable); assert(cannot_be_object_to_value_map_it != cannot_be_object_to_value_map.end()); int value_of_cannot_be_one_set_object_of_variable = cannot_be_object_to_value_map_it->second; if(value_of_cannot_be_one_set_object_of_variable == 1) { dags_from_cannot_be_one_set.insert(cannot_be_one_set_dag_of_variable); number_of_cannot_be_one_elements++; } } map >::iterator cannot_be_zero_set_it = cannot_be_zero_set.find(origin); assert(cannot_be_zero_set_it != cannot_be_zero_set.end()); set cannot_be_zero_set_of_variable = cannot_be_zero_set_it->second; for(set::iterator cannot_be_zero_set_of_variable_it = cannot_be_zero_set_of_variable.begin(); cannot_be_zero_set_of_variable_it != cannot_be_zero_set_of_variable.end(); cannot_be_zero_set_of_variable_it++) { Aig_Obj_t* cannot_be_zero_set_object_of_variable = *cannot_be_zero_set_of_variable_it; map::iterator cannot_be_object_to_cannot_be_dag_map_it = cannot_be_object_to_cannot_be_dag_map.find(cannot_be_zero_set_object_of_variable); assert(cannot_be_object_to_cannot_be_dag_map_it != cannot_be_object_to_cannot_be_dag_map.end()); Aig_Obj_t* cannot_be_zero_set_dag_of_variable = cannot_be_object_to_cannot_be_dag_map_it->second; map::iterator cannot_be_object_to_value_map_it = cannot_be_object_to_value_map.find(cannot_be_zero_set_object_of_variable); assert(cannot_be_object_to_value_map_it != cannot_be_object_to_value_map.end()); int value_of_cannot_be_zero_set_object_of_variable = cannot_be_object_to_value_map_it->second; if(value_of_cannot_be_zero_set_object_of_variable == 1) { dags_from_cannot_be_zero_set.insert(cannot_be_zero_set_dag_of_variable); number_of_cannot_be_zero_elements++; } } assert(!dags_from_cannot_be_one_set.empty()); assert(!dags_from_cannot_be_zero_set.empty()); Aig_Obj_t* cannot_be_one_part_of_mu; Aig_Obj_t* cannot_be_zero_part_of_mu; if(select_cannot_be_elements_based_on_supports) { // select only one element from cannot-be one and cannot-be zero sets s.t. support of mu is minimum #ifdef DEBUG_SKOLEM cout << "\nselecting only one element from cannot-be one and cannot-be zero sets s.t. support of mu is minimum\n"; #endif // first select the cannot-be-one element with minimum support set::iterator dags_from_cannot_be_one_set_it = dags_from_cannot_be_one_set.begin(); Aig_Obj_t* cannot_be_one_dag_selected = *dags_from_cannot_be_one_set_it; set support_of_cannot_be_one_dag_selected; set yin_support_of_cannot_be_one_dag_selected; if(avoid_y_variables_in_select_cannot_be_elements_based_on_supports) { set temp_support_of_cannot_be_one_dag_selected; computeSupport(cannot_be_one_dag_selected, temp_support_of_cannot_be_one_dag_selected, pub_aig_manager); set_difference(temp_support_of_cannot_be_one_dag_selected.begin(), temp_support_of_cannot_be_one_dag_selected.end(), variables_not_quantified.begin(), variables_not_quantified.end(),inserter(support_of_cannot_be_one_dag_selected, support_of_cannot_be_one_dag_selected.begin())); set_difference(temp_support_of_cannot_be_one_dag_selected.begin(), temp_support_of_cannot_be_one_dag_selected.end(), variables_quantified.begin(), variables_quantified.end(),inserter(yin_support_of_cannot_be_one_dag_selected, yin_support_of_cannot_be_one_dag_selected.begin())); } else { computeSupport(cannot_be_one_dag_selected, support_of_cannot_be_one_dag_selected, pub_aig_manager); } int size_of_support_of_cannot_be_one_dag_selected = support_of_cannot_be_one_dag_selected.size(); int size_of_yin_support_of_cannot_be_one_dag_selected = yin_support_of_cannot_be_one_dag_selected.size(); #ifdef DEBUG_SKOLEM showSet(support_of_cannot_be_one_dag_selected, "support_of_cannot_be_one_dag_selected"); showSet(yin_support_of_cannot_be_one_dag_selected, "yin_support_of_cannot_be_one_dag_selected"); #endif dags_from_cannot_be_one_set_it++; for(;dags_from_cannot_be_one_set_it != dags_from_cannot_be_one_set.end(); dags_from_cannot_be_one_set_it++) { Aig_Obj_t* cannot_be_one_dag = *dags_from_cannot_be_one_set_it; set support_of_cannot_be_one_dag; set yin_support_of_cannot_be_one_dag; if(avoid_y_variables_in_select_cannot_be_elements_based_on_supports) { set temp_support_of_cannot_be_one_dag; computeSupport(cannot_be_one_dag, temp_support_of_cannot_be_one_dag, pub_aig_manager); set_difference(temp_support_of_cannot_be_one_dag.begin(), temp_support_of_cannot_be_one_dag.end(), variables_not_quantified.begin(), variables_not_quantified.end(),inserter(support_of_cannot_be_one_dag, support_of_cannot_be_one_dag.begin())); set_difference(temp_support_of_cannot_be_one_dag.begin(), temp_support_of_cannot_be_one_dag.end(), variables_quantified.begin(), variables_quantified.end(),inserter(yin_support_of_cannot_be_one_dag, yin_support_of_cannot_be_one_dag.begin())); } else { computeSupport(cannot_be_one_dag, support_of_cannot_be_one_dag, pub_aig_manager); } int size_of_support_of_cannot_be_one_dag = support_of_cannot_be_one_dag.size(); int size_of_yin_support_of_cannot_be_one_dag = yin_support_of_cannot_be_one_dag.size(); #ifdef DEBUG_SKOLEM showSet(support_of_cannot_be_one_dag, "support_of_cannot_be_one_dag"); showSet(yin_support_of_cannot_be_one_dag, "yin_support_of_cannot_be_one_dag"); #endif if(size_of_support_of_cannot_be_one_dag < size_of_support_of_cannot_be_one_dag_selected || (size_of_support_of_cannot_be_one_dag == size_of_support_of_cannot_be_one_dag_selected && size_of_yin_support_of_cannot_be_one_dag < size_of_yin_support_of_cannot_be_one_dag_selected) ) { cannot_be_one_dag_selected = cannot_be_one_dag; support_of_cannot_be_one_dag_selected = support_of_cannot_be_one_dag; yin_support_of_cannot_be_one_dag_selected = yin_support_of_cannot_be_one_dag; size_of_support_of_cannot_be_one_dag_selected = size_of_support_of_cannot_be_one_dag; size_of_yin_support_of_cannot_be_one_dag_selected = size_of_yin_support_of_cannot_be_one_dag; } #ifdef DEBUG_SKOLEM showSet(support_of_cannot_be_one_dag_selected, "support_of_cannot_be_one_dag_selected"); showSet(yin_support_of_cannot_be_one_dag_selected, "yin_support_of_cannot_be_one_dag_selected"); #endif } // now select the cannot-be-zero element with minimum (support \union support of selected cannot-be-one element) set::iterator dags_from_cannot_be_zero_set_it = dags_from_cannot_be_zero_set.begin(); Aig_Obj_t* cannot_be_zero_dag_selected = *dags_from_cannot_be_zero_set_it; set support_of_cannot_be_zero_dag_selected; set yin_support_of_cannot_be_zero_dag_selected; if(avoid_y_variables_in_select_cannot_be_elements_based_on_supports) { set temp_support_of_cannot_be_zero_dag_selected; computeSupport(cannot_be_zero_dag_selected, temp_support_of_cannot_be_zero_dag_selected, pub_aig_manager); set_difference(temp_support_of_cannot_be_zero_dag_selected.begin(), temp_support_of_cannot_be_zero_dag_selected.end(), variables_not_quantified.begin(), variables_not_quantified.end(),inserter(support_of_cannot_be_zero_dag_selected, support_of_cannot_be_zero_dag_selected.begin())); set_difference(temp_support_of_cannot_be_zero_dag_selected.begin(), temp_support_of_cannot_be_zero_dag_selected.end(), variables_quantified.begin(), variables_quantified.end(),inserter(yin_support_of_cannot_be_zero_dag_selected, yin_support_of_cannot_be_zero_dag_selected.begin())); } else { computeSupport(cannot_be_zero_dag_selected, support_of_cannot_be_zero_dag_selected, pub_aig_manager); } set union_support_selected; set_union(support_of_cannot_be_one_dag_selected.begin(), support_of_cannot_be_one_dag_selected.end(), support_of_cannot_be_zero_dag_selected.begin(), support_of_cannot_be_zero_dag_selected.end(),inserter(union_support_selected, union_support_selected.begin())); int size_of_union_support_selected = union_support_selected.size(); set yin_union_support_selected; set_union(yin_support_of_cannot_be_one_dag_selected.begin(), yin_support_of_cannot_be_one_dag_selected.end(), yin_support_of_cannot_be_zero_dag_selected.begin(), yin_support_of_cannot_be_zero_dag_selected.end(),inserter(yin_union_support_selected, yin_union_support_selected.begin())); int size_of_yin_union_support_selected = yin_union_support_selected.size(); #ifdef DEBUG_SKOLEM showSet(support_of_cannot_be_zero_dag_selected, "support_of_cannot_be_zero_dag_selected"); showSet(union_support_selected, "union_support_selected"); showSet(yin_union_support_selected, "yin_union_support_selected"); #endif dags_from_cannot_be_zero_set_it++; for(;dags_from_cannot_be_zero_set_it != dags_from_cannot_be_zero_set.end(); dags_from_cannot_be_zero_set_it++) { Aig_Obj_t* cannot_be_zero_dag = *dags_from_cannot_be_zero_set_it; set support_of_cannot_be_zero_dag; set yin_support_of_cannot_be_zero_dag; if(avoid_y_variables_in_select_cannot_be_elements_based_on_supports) { set temp_support_of_cannot_be_zero_dag; computeSupport(cannot_be_zero_dag, temp_support_of_cannot_be_zero_dag, pub_aig_manager); set_difference(temp_support_of_cannot_be_zero_dag.begin(), temp_support_of_cannot_be_zero_dag.end(), variables_not_quantified.begin(), variables_not_quantified.end(),inserter(support_of_cannot_be_zero_dag, support_of_cannot_be_zero_dag.begin())); set_difference(temp_support_of_cannot_be_zero_dag.begin(), temp_support_of_cannot_be_zero_dag.end(), variables_quantified.begin(), variables_quantified.end(),inserter(yin_support_of_cannot_be_zero_dag, yin_support_of_cannot_be_zero_dag.begin())); } else { computeSupport(cannot_be_zero_dag, support_of_cannot_be_zero_dag, pub_aig_manager); } set union_support; set_union(support_of_cannot_be_one_dag_selected.begin(), support_of_cannot_be_one_dag_selected.end(), support_of_cannot_be_zero_dag.begin(), support_of_cannot_be_zero_dag.end(),inserter(union_support, union_support.begin())); int size_of_union_support = union_support.size(); set yin_union_support; set_union(yin_support_of_cannot_be_one_dag_selected.begin(), yin_support_of_cannot_be_one_dag_selected.end(), yin_support_of_cannot_be_zero_dag.begin(), yin_support_of_cannot_be_zero_dag.end(),inserter(yin_union_support, yin_union_support.begin())); int size_of_yin_union_support = yin_union_support.size(); #ifdef DEBUG_SKOLEM showSet(support_of_cannot_be_zero_dag, "support_of_cannot_be_zero_dag"); showSet(union_support, "union_support"); showSet(yin_union_support, "yin_union_support"); #endif if(size_of_union_support < size_of_union_support_selected || (size_of_union_support == size_of_union_support_selected && size_of_yin_union_support < size_of_yin_union_support_selected) ) { cannot_be_zero_dag_selected = cannot_be_zero_dag; support_of_cannot_be_zero_dag_selected = support_of_cannot_be_zero_dag; yin_support_of_cannot_be_zero_dag_selected = yin_support_of_cannot_be_zero_dag; size_of_union_support_selected = size_of_union_support; size_of_yin_union_support_selected = size_of_yin_union_support; } #ifdef DEBUG_SKOLEM showSet(support_of_cannot_be_zero_dag_selected, "support_of_cannot_be_zero_dag_selected"); showSet(union_support_selected, "union_support_selected"); showSet(yin_union_support_selected, "yin_union_support_selected"); #endif } cannot_be_one_part_of_mu = cannot_be_one_dag_selected; cannot_be_zero_part_of_mu = cannot_be_zero_dag_selected; number_of_cannot_be_one_elements_selected = 1; number_of_cannot_be_zero_elements_selected = 1; } else //take disjunction of all dags in cannot-be one/zero parts { cannot_be_one_part_of_mu = createOr(dags_from_cannot_be_one_set, pub_aig_manager); cannot_be_zero_part_of_mu = createOr(dags_from_cannot_be_zero_set, pub_aig_manager); number_of_cannot_be_one_elements_selected = number_of_cannot_be_one_elements; number_of_cannot_be_zero_elements_selected = number_of_cannot_be_zero_elements; } assert(cannot_be_one_part_of_mu != NULL); assert(cannot_be_zero_part_of_mu != NULL); Aig_Obj_t* mu; mu = createAnd(cannot_be_one_part_of_mu, cannot_be_zero_part_of_mu, pub_aig_manager); assert(mu != NULL); size_of_initial_mu = computeSize(mu, pub_aig_manager); return mu; } Aig_Obj_t* AIGBasedSkolem::obtain_disjunction_of_true_cannot_be_zero_dags(int destination, map &cannot_be_object_to_value_map, Aig_Obj_t* cofactor_of_mu, int &number_of_cannot_be_zero_elements_that_are_true_selected) { int number_of_cannot_be_zero_elements_that_are_true = 0; set dags_from_cannot_be_zero_set; map >::iterator cannot_be_zero_set_it = cannot_be_zero_set.find(destination); assert(cannot_be_zero_set_it != cannot_be_zero_set.end()); set cannot_be_zero_set_of_variable = cannot_be_zero_set_it->second; for(set::iterator cannot_be_zero_set_of_variable_it = cannot_be_zero_set_of_variable.begin(); cannot_be_zero_set_of_variable_it != cannot_be_zero_set_of_variable.end(); cannot_be_zero_set_of_variable_it++) { Aig_Obj_t* cannot_be_zero_set_object_of_variable = *cannot_be_zero_set_of_variable_it; map::iterator cannot_be_object_to_cannot_be_dag_map_it = cannot_be_object_to_cannot_be_dag_map.find(cannot_be_zero_set_object_of_variable); assert(cannot_be_object_to_cannot_be_dag_map_it != cannot_be_object_to_cannot_be_dag_map.end()); Aig_Obj_t* cannot_be_zero_set_dag_of_variable = cannot_be_object_to_cannot_be_dag_map_it->second; map::iterator cannot_be_object_to_value_map_it = cannot_be_object_to_value_map.find(cannot_be_zero_set_object_of_variable); assert(cannot_be_object_to_value_map_it != cannot_be_object_to_value_map.end()); int value_of_cannot_be_zero_set_object_of_variable = cannot_be_object_to_value_map_it->second; if(value_of_cannot_be_zero_set_object_of_variable == 1) { dags_from_cannot_be_zero_set.insert(cannot_be_zero_set_dag_of_variable); number_of_cannot_be_zero_elements_that_are_true++; } } assert(!dags_from_cannot_be_zero_set.empty()); Aig_Obj_t* cannot_be_zero_part_of_mu; if(select_cannot_be_elements_based_on_supports) { // select the cannot-be-zero element with minimum (support \union support of cofactor_zero_of_mu) set support_of_cofactor_of_mu; set yin_support_of_cofactor_of_mu; if(avoid_y_variables_in_select_cannot_be_elements_based_on_supports) { set temp_support_of_cofactor_of_mu; computeSupport(cofactor_of_mu, temp_support_of_cofactor_of_mu, pub_aig_manager); set_difference(temp_support_of_cofactor_of_mu.begin(), temp_support_of_cofactor_of_mu.end(), variables_not_quantified.begin(), variables_not_quantified.end(),inserter(support_of_cofactor_of_mu, support_of_cofactor_of_mu.begin())); set_difference(temp_support_of_cofactor_of_mu.begin(), temp_support_of_cofactor_of_mu.end(), variables_quantified.begin(), variables_quantified.end(),inserter(yin_support_of_cofactor_of_mu, yin_support_of_cofactor_of_mu.begin())); } else { computeSupport(cofactor_of_mu, support_of_cofactor_of_mu, pub_aig_manager); } set::iterator dags_from_cannot_be_zero_set_it = dags_from_cannot_be_zero_set.begin(); Aig_Obj_t* cannot_be_zero_dag_selected = *dags_from_cannot_be_zero_set_it; set support_of_cannot_be_zero_dag_selected; set yin_support_of_cannot_be_zero_dag_selected; if(avoid_y_variables_in_select_cannot_be_elements_based_on_supports) { set temp_support_of_cannot_be_zero_dag_selected; computeSupport(cannot_be_zero_dag_selected, temp_support_of_cannot_be_zero_dag_selected, pub_aig_manager); set_difference(temp_support_of_cannot_be_zero_dag_selected.begin(), temp_support_of_cannot_be_zero_dag_selected.end(), variables_not_quantified.begin(), variables_not_quantified.end(),inserter(support_of_cannot_be_zero_dag_selected, support_of_cannot_be_zero_dag_selected.begin())); set_difference(temp_support_of_cannot_be_zero_dag_selected.begin(), temp_support_of_cannot_be_zero_dag_selected.end(), variables_quantified.begin(), variables_quantified.end(),inserter(yin_support_of_cannot_be_zero_dag_selected, yin_support_of_cannot_be_zero_dag_selected.begin())); } else { computeSupport(cannot_be_zero_dag_selected, support_of_cannot_be_zero_dag_selected, pub_aig_manager); } set union_support_selected; set_union(support_of_cofactor_of_mu.begin(), support_of_cofactor_of_mu.end(), support_of_cannot_be_zero_dag_selected.begin(), support_of_cannot_be_zero_dag_selected.end(),inserter(union_support_selected, union_support_selected.begin())); int size_of_union_support_selected = union_support_selected.size(); set yin_union_support_selected; set_union(yin_support_of_cofactor_of_mu.begin(), yin_support_of_cofactor_of_mu.end(), yin_support_of_cannot_be_zero_dag_selected.begin(), yin_support_of_cannot_be_zero_dag_selected.end(),inserter(yin_union_support_selected, yin_union_support_selected.begin())); int yin_size_of_union_support_selected = yin_union_support_selected.size(); #ifdef DEBUG_SKOLEM showSet(support_of_cofactor_of_mu, "support_of_cofactor_of_mu"); showSet(support_of_cannot_be_zero_dag_selected, "support_of_cannot_be_zero_dag_selected"); showSet(union_support_selected, "union_support_selected"); showSet(yin_union_support_selected, "yin_union_support_selected"); #endif dags_from_cannot_be_zero_set_it++; for(;dags_from_cannot_be_zero_set_it != dags_from_cannot_be_zero_set.end(); dags_from_cannot_be_zero_set_it++) { Aig_Obj_t* cannot_be_zero_dag = *dags_from_cannot_be_zero_set_it; set support_of_cannot_be_zero_dag; set yin_support_of_cannot_be_zero_dag; if(avoid_y_variables_in_select_cannot_be_elements_based_on_supports) { set temp_support_of_cannot_be_zero_dag; computeSupport(cannot_be_zero_dag, temp_support_of_cannot_be_zero_dag, pub_aig_manager); set_difference(temp_support_of_cannot_be_zero_dag.begin(), temp_support_of_cannot_be_zero_dag.end(), variables_not_quantified.begin(), variables_not_quantified.end(),inserter(support_of_cannot_be_zero_dag, support_of_cannot_be_zero_dag.begin())); set_difference(temp_support_of_cannot_be_zero_dag.begin(), temp_support_of_cannot_be_zero_dag.end(), variables_quantified.begin(), variables_quantified.end(),inserter(yin_support_of_cannot_be_zero_dag, yin_support_of_cannot_be_zero_dag.begin())); } else { computeSupport(cannot_be_zero_dag, support_of_cannot_be_zero_dag, pub_aig_manager); } set union_support; set_union(support_of_cofactor_of_mu.begin(), support_of_cofactor_of_mu.end(), support_of_cannot_be_zero_dag.begin(), support_of_cannot_be_zero_dag.end(),inserter(union_support, union_support.begin())); int size_of_union_support = union_support.size(); set yin_union_support; set_union(yin_support_of_cofactor_of_mu.begin(), yin_support_of_cofactor_of_mu.end(), yin_support_of_cannot_be_zero_dag.begin(), yin_support_of_cannot_be_zero_dag.end(),inserter(yin_union_support, yin_union_support.begin())); int yin_size_of_union_support = yin_union_support.size(); #ifdef DEBUG_SKOLEM showSet(support_of_cannot_be_zero_dag, "support_of_cannot_be_zero_dag"); showSet(union_support, "union_support"); showSet(yin_union_support, "yin_union_support"); #endif if(size_of_union_support < size_of_union_support_selected || (size_of_union_support == size_of_union_support_selected && yin_size_of_union_support < yin_size_of_union_support_selected)) { cannot_be_zero_dag_selected = cannot_be_zero_dag; support_of_cannot_be_zero_dag_selected = support_of_cannot_be_zero_dag; yin_support_of_cannot_be_zero_dag_selected = yin_support_of_cannot_be_zero_dag; size_of_union_support_selected = size_of_union_support; yin_size_of_union_support_selected = yin_size_of_union_support; } #ifdef DEBUG_SKOLEM showSet(support_of_cannot_be_zero_dag_selected, "support_of_cannot_be_zero_dag_selected"); showSet(union_support_selected, "union_support_selected"); showSet(yin_union_support_selected, "yin_union_support_selected"); #endif } cannot_be_zero_part_of_mu = cannot_be_zero_dag_selected; number_of_cannot_be_zero_elements_that_are_true_selected = 1; } else { cannot_be_zero_part_of_mu = createOr(dags_from_cannot_be_zero_set, pub_aig_manager); number_of_cannot_be_zero_elements_that_are_true_selected = number_of_cannot_be_zero_elements_that_are_true; } assert(cannot_be_zero_part_of_mu != NULL); return cannot_be_zero_part_of_mu; } Aig_Obj_t* AIGBasedSkolem::obtain_disjunction_of_true_cannot_be_one_dags(int destination, map &cannot_be_object_to_value_map, Aig_Obj_t* cofactor_of_mu, int &number_of_cannot_be_one_elements_that_are_true_selected) { int number_of_cannot_be_one_elements_that_are_true = 0; set dags_from_cannot_be_one_set; map >::iterator cannot_be_one_set_it = cannot_be_one_set.find(destination); assert(cannot_be_one_set_it != cannot_be_one_set.end()); set cannot_be_one_set_of_variable = cannot_be_one_set_it->second; for(set::iterator cannot_be_one_set_of_variable_it = cannot_be_one_set_of_variable.begin(); cannot_be_one_set_of_variable_it != cannot_be_one_set_of_variable.end(); cannot_be_one_set_of_variable_it++) { Aig_Obj_t* cannot_be_one_set_object_of_variable = *cannot_be_one_set_of_variable_it; map::iterator cannot_be_object_to_cannot_be_dag_map_it = cannot_be_object_to_cannot_be_dag_map.find(cannot_be_one_set_object_of_variable); assert(cannot_be_object_to_cannot_be_dag_map_it != cannot_be_object_to_cannot_be_dag_map.end()); Aig_Obj_t* cannot_be_one_set_dag_of_variable = cannot_be_object_to_cannot_be_dag_map_it->second; map::iterator cannot_be_object_to_value_map_it = cannot_be_object_to_value_map.find(cannot_be_one_set_object_of_variable); assert(cannot_be_object_to_value_map_it != cannot_be_object_to_value_map.end()); int value_of_cannot_be_one_set_object_of_variable = cannot_be_object_to_value_map_it->second; if(value_of_cannot_be_one_set_object_of_variable == 1) { dags_from_cannot_be_one_set.insert(cannot_be_one_set_dag_of_variable); number_of_cannot_be_one_elements_that_are_true++; } } assert(!dags_from_cannot_be_one_set.empty()); Aig_Obj_t* cannot_be_one_part_of_mu; if(select_cannot_be_elements_based_on_supports) { // select the cannot-be-one element with minimum (support \union support of cofacto_of_mu) set support_of_cofactor_of_mu; set yin_support_of_cofactor_of_mu; if(avoid_y_variables_in_select_cannot_be_elements_based_on_supports) { set temp_support_of_cofactor_of_mu; computeSupport(cofactor_of_mu, temp_support_of_cofactor_of_mu, pub_aig_manager); set_difference(temp_support_of_cofactor_of_mu.begin(), temp_support_of_cofactor_of_mu.end(), variables_not_quantified.begin(), variables_not_quantified.end(),inserter(support_of_cofactor_of_mu, support_of_cofactor_of_mu.begin())); set_difference(temp_support_of_cofactor_of_mu.begin(), temp_support_of_cofactor_of_mu.end(), variables_quantified.begin(), variables_quantified.end(),inserter(yin_support_of_cofactor_of_mu, yin_support_of_cofactor_of_mu.begin())); } else { computeSupport(cofactor_of_mu, support_of_cofactor_of_mu, pub_aig_manager); } set::iterator dags_from_cannot_be_one_set_it = dags_from_cannot_be_one_set.begin(); Aig_Obj_t* cannot_be_one_dag_selected = *dags_from_cannot_be_one_set_it; set support_of_cannot_be_one_dag_selected; set yin_support_of_cannot_be_one_dag_selected; if(avoid_y_variables_in_select_cannot_be_elements_based_on_supports) { set temp_support_of_cannot_be_one_dag_selected; computeSupport(cannot_be_one_dag_selected, temp_support_of_cannot_be_one_dag_selected, pub_aig_manager); set_difference(temp_support_of_cannot_be_one_dag_selected.begin(), temp_support_of_cannot_be_one_dag_selected.end(), variables_not_quantified.begin(), variables_not_quantified.end(),inserter(support_of_cannot_be_one_dag_selected, support_of_cannot_be_one_dag_selected.begin())); set_difference(temp_support_of_cannot_be_one_dag_selected.begin(), temp_support_of_cannot_be_one_dag_selected.end(), variables_quantified.begin(), variables_quantified.end(),inserter(yin_support_of_cannot_be_one_dag_selected, yin_support_of_cannot_be_one_dag_selected.begin())); } else { computeSupport(cannot_be_one_dag_selected, support_of_cannot_be_one_dag_selected, pub_aig_manager); } set union_support_selected; set_union(support_of_cofactor_of_mu.begin(), support_of_cofactor_of_mu.end(), support_of_cannot_be_one_dag_selected.begin(), support_of_cannot_be_one_dag_selected.end(),inserter(union_support_selected, union_support_selected.begin())); int size_of_union_support_selected = union_support_selected.size(); set yin_union_support_selected; set_union(yin_support_of_cofactor_of_mu.begin(), yin_support_of_cofactor_of_mu.end(), yin_support_of_cannot_be_one_dag_selected.begin(), yin_support_of_cannot_be_one_dag_selected.end(),inserter(yin_union_support_selected, yin_union_support_selected.begin())); int yin_size_of_union_support_selected = yin_union_support_selected.size(); #ifdef DEBUG_SKOLEM showSet(support_of_cofactor_of_mu, "support_of_cofactor_of_mu"); showSet(support_of_cannot_be_one_dag_selected, "support_of_cannot_be_one_dag_selected"); showSet(union_support_selected, "union_support_selected"); showSet(yin_union_support_selected, "yin_union_support_selected"); #endif dags_from_cannot_be_one_set_it++; for(;dags_from_cannot_be_one_set_it != dags_from_cannot_be_one_set.end(); dags_from_cannot_be_one_set_it++) { Aig_Obj_t* cannot_be_one_dag = *dags_from_cannot_be_one_set_it; set support_of_cannot_be_one_dag; set yin_support_of_cannot_be_one_dag; if(avoid_y_variables_in_select_cannot_be_elements_based_on_supports) { set temp_support_of_cannot_be_one_dag; computeSupport(cannot_be_one_dag, temp_support_of_cannot_be_one_dag, pub_aig_manager); set_difference(temp_support_of_cannot_be_one_dag.begin(), temp_support_of_cannot_be_one_dag.end(), variables_not_quantified.begin(), variables_not_quantified.end(),inserter(support_of_cannot_be_one_dag, support_of_cannot_be_one_dag.begin())); set_difference(temp_support_of_cannot_be_one_dag.begin(), temp_support_of_cannot_be_one_dag.end(), variables_quantified.begin(), variables_quantified.end(),inserter(yin_support_of_cannot_be_one_dag, yin_support_of_cannot_be_one_dag.begin())); } else { computeSupport(cannot_be_one_dag, support_of_cannot_be_one_dag, pub_aig_manager); } set union_support; set_union(support_of_cofactor_of_mu.begin(), support_of_cofactor_of_mu.end(), support_of_cannot_be_one_dag.begin(), support_of_cannot_be_one_dag.end(),inserter(union_support, union_support.begin())); int size_of_union_support = union_support.size(); set yin_union_support; set_union(yin_support_of_cofactor_of_mu.begin(), yin_support_of_cofactor_of_mu.end(), yin_support_of_cannot_be_one_dag.begin(), yin_support_of_cannot_be_one_dag.end(),inserter(yin_union_support, yin_union_support.begin())); int yin_size_of_union_support = yin_union_support.size(); #ifdef DEBUG_SKOLEM showSet(support_of_cannot_be_one_dag, "support_of_cannot_be_one_dag"); showSet(union_support, "union_support"); showSet(yin_union_support, "yin_union_support"); #endif if(size_of_union_support < size_of_union_support_selected || ( size_of_union_support == size_of_union_support_selected && yin_size_of_union_support < yin_size_of_union_support_selected)) { cannot_be_one_dag_selected = cannot_be_one_dag; support_of_cannot_be_one_dag_selected = support_of_cannot_be_one_dag; yin_support_of_cannot_be_one_dag_selected = yin_support_of_cannot_be_one_dag; size_of_union_support_selected = size_of_union_support; yin_size_of_union_support_selected = yin_size_of_union_support; } #ifdef DEBUG_SKOLEM showSet(support_of_cannot_be_one_dag_selected, "support_of_cannot_be_one_dag_selected"); showSet(union_support_selected, "union_support_selected"); showSet(yin_union_support_selected, "yin_union_support_selected"); #endif } cannot_be_one_part_of_mu = cannot_be_one_dag_selected; number_of_cannot_be_one_elements_that_are_true_selected = 1; } else { cannot_be_one_part_of_mu = createOr(dags_from_cannot_be_one_set, pub_aig_manager); number_of_cannot_be_one_elements_that_are_true_selected = number_of_cannot_be_one_elements_that_are_true; } assert(cannot_be_one_part_of_mu != NULL); return cannot_be_one_part_of_mu; } void AIGBasedSkolem::show_present_refinement_hint(map &Refinement_Hint_Of_CannotBe_One_To_Eliminate_This_CEX, map &Refinement_Hint_Of_CannotBe_Zero_To_Eliminate_This_CEX) { "\n\nRefinement hint of cannot-be-1\n"; for(map::iterator hint_it = Refinement_Hint_Of_CannotBe_One_To_Eliminate_This_CEX.begin(); hint_it != Refinement_Hint_Of_CannotBe_One_To_Eliminate_This_CEX.end(); hint_it++) { cout << endl << hint_it->first << "\t" << hint_it->second; } "\n\nRefinement hint of cannot-be-0\n"; for(map::iterator hint_it = Refinement_Hint_Of_CannotBe_Zero_To_Eliminate_This_CEX.begin(); hint_it != Refinement_Hint_Of_CannotBe_Zero_To_Eliminate_This_CEX.end(); hint_it++) { cout << endl << hint_it->first << "\t" << hint_it->second; } } void AIGBasedSkolem::obtainSkolemFunctionsInGraphDecomposition(set &uncovered_edges_factors, list &VariablesToEliminate, map &variable_to_skolem_function_map, int iterations_of_loop) { variable_to_skolem_function_map.clear(); if(uncovered_edges_factors.empty()) //i.e. uncovered_edges = true { for(list::iterator list_it = VariablesToEliminate.begin(); list_it != VariablesToEliminate.end(); list_it++) { string variable_to_eliminate = *list_it; Aig_Obj_t* skolem_function = createTrue(pub_aig_manager); assert(skolem_function != NULL); variable_to_skolem_function_map.insert(make_pair(variable_to_eliminate, skolem_function)); } #ifdef RECORD_KEEP string record_file; record_file = logfile_prefix; record_file += "skolem_function_generation_details.txt"; FILE* record_fp = fopen(record_file.c_str(), "a+"); assert(record_fp != NULL); fprintf(record_fp, "\n\nAll TRUE skolem functions generated\n"); fclose(record_fp); #endif } else { #ifdef RECORD_KEEP string record_file; record_file = logfile_prefix; record_file += "skolem_function_generation_details.txt"; FILE* record_fp = fopen(record_file.c_str(), "a+"); assert(record_fp != NULL); fprintf(record_fp, "\n\nSkolem function generation %d\n", iterations_of_loop-1); fclose(record_fp); unsigned long long int total_present_skf_duration_ms; struct timeval total_present_skf_start_ms, total_present_skf_finish_ms; gettimeofday (&total_present_skf_start_ms, NULL); #endif list VariablesToEliminate_Copy; VariablesToEliminate_Copy = VariablesToEliminate; if(disable_factorization) { monolithicSkolemFunctionGeneratorWithScopeReduction(uncovered_edges_factors, VariablesToEliminate_Copy); } else { factorizedSkolemFunctionGenerator(uncovered_edges_factors, VariablesToEliminate_Copy); } #ifdef RECORD_KEEP gettimeofday (&total_present_skf_finish_ms, NULL); total_present_skf_duration_ms = total_present_skf_finish_ms.tv_sec * 1000 + total_present_skf_finish_ms.tv_usec / 1000; total_present_skf_duration_ms -= total_present_skf_start_ms.tv_sec * 1000 + total_present_skf_start_ms.tv_usec / 1000; total_present_skf_duration_ms = total_present_skf_duration_ms - total_time_in_compute_size; string order_string_to_print; if(order_of_elimination_of_variables == 0) { order_string_to_print = "alphabetical"; } else if(order_of_elimination_of_variables == 1) { order_string_to_print = "least-occurring-first"; } else if(order_of_elimination_of_variables == 2) { order_string_to_print = "factor-graph-based"; } else if(order_of_elimination_of_variables == 3) { order_string_to_print = "externally-supplied"; } record_fp = fopen(record_file.c_str(), "a+"); assert(record_fp != NULL); if(enable_cegar) { assert(!use_multi_point_connections && !use_cyclic_two_point_connections); // Note that connection-substitution is not implemented fprintf(record_fp, "\n\n\nordering-used = %s\ntotal-time-in-initial-abstraction-generation-without-size-computation-time = %llu milliseconds\ntotal-time-in-cegar-loops-without-size-computation-time = %llu milliseconds\nsolver-used = %s\nnumber-of-cegar-iterations = %d\ntotal-time-in-reverse-substitution-without-size-computation-time = %llu milliseconds\ntotal-skolem-function-generation-time-without-size-computation-time = %llu milliseconds\nsize-computation-time = %llu\n", order_string_to_print.c_str(), total_time_in_initial_abstraction_generation_in_cegar, total_time_in_cegar_loops_in_cegar, solver.c_str(), cegar_iteration_number, total_time_in_reverse_substitution_in_cegar, total_present_skf_duration_ms, total_time_in_compute_size); } else { fprintf(record_fp, "\n\n\nordering-used = %s\ntotal-time-in-initial-skolem-function-generation-without-size-computation-time = %llu milliseconds\ntotal-time-in-reverse-substitution-without-size-computation-time = %llu milliseconds\ntotal-skolem-function-generation-time-without-size-computation-time = %llu milliseconds\ntotal-time-in-interpolant-computation = %llu\nsize-computation-time = %llu\n", order_string_to_print.c_str(), total_time_in_initial_abstraction_generation_in_cegar, total_time_in_reverse_substitution_in_cegar, total_present_skf_duration_ms, total_time_in_interpolant_computation, total_time_in_compute_size); } fprintf(record_fp, "\nfinal-skolem-function-sizes = "); for(list::iterator sfs_it = skolem_function_sizes_after_reverse_substitution.begin(); sfs_it != skolem_function_sizes_after_reverse_substitution.end(); sfs_it++) { fprintf(record_fp, "%d, ", *sfs_it); } fclose(record_fp); #endif for(list::iterator list_it = VariablesToEliminate.begin(); list_it != VariablesToEliminate.end(); list_it++) { string variable_to_eliminate = *list_it; int index_of_variable_to_eliminate = searchVarNameToVarIndexMap(var_name_to_var_index_map, variable_to_eliminate); Aig_Obj_t* skolem_function; if(index_of_variable_to_eliminate == -1) // uncovered_edges_factors free of variable_to_eliminate { skolem_function = createTrue(pub_aig_manager); assert(skolem_function != NULL); } else { skolem_function = searchOneDimensionalMatrix(SkolemFunctions, number_of_vars_to_elim, index_of_variable_to_eliminate); assert(skolem_function != NULL); } variable_to_skolem_function_map.insert(make_pair(variable_to_eliminate, skolem_function)); } clearAllDataStructures(); } } void AIGBasedSkolem::graphDecomposition(set &transition_function_factors, set &transition_function_parts, list &VariablesToEliminate, map &Output_Object_to_RHS_of_Factors, map &Output_Object_to_RHS_of_PrimaryOutputs, ABC* abcObj, Abc_Frame_t* abcFrame) { assert(!transition_function_factors.empty()); Aig_Obj_t* transition_function = createAnd(transition_function_factors, pub_aig_manager); assert(transition_function != NULL); Aig_Obj_t* transition_function_CO = Aig_ObjCreateCo( pub_aig_manager, transition_function ); // to aviod // unwanted cleanup of transition_function assert(transition_function_CO != NULL); #ifdef DEBUG_SKOLEM string transition_function_file_name = benchmark_name_without_extension; transition_function_file_name += "_transition_function"; writeFormulaToFile(pub_aig_manager, transition_function, transition_function_file_name, ".v", 0, 0); #endif map variable_to_skolem_function_map; if(component_generation_strategy == "preferred_edge") { assert(failure_condition_aig != NULL); set preferred_edges_factors; set failure_condition_support; computeSupport(failure_condition_aig, failure_condition_support, pub_aig_manager); set inputs_in_failure_condition; set_intersection(failure_condition_support.begin(), failure_condition_support.end(), input_names_in_circuit.begin(), input_names_in_circuit.end(), inserter(inputs_in_failure_condition, inputs_in_failure_condition.begin())); if(!inputs_in_failure_condition.empty()) { preferred_edges_factors.insert(failure_condition_aig); } else { cout << "\nCase where failure condition does not involve inputs is not implemented\n"; assert(false); } } else if(component_generation_strategy == "uncovered_edge") { Aig_Obj_t* uncovered_edges; uncovered_edges = createTrue(pub_aig_manager); assert(uncovered_edges != NULL); set uncovered_edges_factors; bool more_components_existing = true; int iterations_of_loop = 1; unsigned long long int step_ms; struct timeval step_start_ms, step_finish_ms; while(more_components_existing) { #ifdef DEBUG_SKOLEM cout << "\nStarting loop iteration " << iterations_of_loop << endl; #endif #ifdef RECORD_KEEP string record_file; record_file = logfile_prefix; record_file += "skolem_function_generation_details.txt"; FILE* record_fp = fopen(record_file.c_str(), "a+"); assert(record_fp != NULL); fprintf(record_fp, "\n\n\nCOMPONENT %d\n", iterations_of_loop); fclose(record_fp); #endif obtainSkolemFunctionsInGraphDecomposition(uncovered_edges_factors, VariablesToEliminate, variable_to_skolem_function_map, iterations_of_loop); #ifdef RECORD_KEEP gettimeofday (&step_start_ms, NULL); #endif if(write_component_as_sequential_circuit) { int number_of_state_elements; map idName; list output_names; map output_name_to_replaced_factor; for(map::iterator map_it = Output_Object_to_RHS_of_Factors.begin(); map_it != Output_Object_to_RHS_of_Factors.end(); map_it++) { Aig_Obj_t* output_obj = map_it->first; Aig_Obj_t* factor = map_it->second; Aig_Obj_t* factor_after_replacement; factor_after_replacement = replaceVariablesByFormulas(factor, variable_to_skolem_function_map); assert(factor_after_replacement != NULL); map::iterator Ci_id_to_Ci_name_map_it = Ci_id_to_Ci_name_map.find(output_obj->Id); assert(Ci_id_to_Ci_name_map_it != Ci_id_to_Ci_name_map.end()); string output_name = Ci_id_to_Ci_name_map_it->second; assert(output_name.find(LATCHOUTPREFIX) != string::npos); int first_location = output_name.find_last_of("_"); string first_index_string = output_name.substr(first_location+1); output_name = "nextstate_"; output_name += first_index_string; output_names.push_back(output_name); output_name_to_replaced_factor.insert(make_pair(output_name, factor_after_replacement)); } for(map::iterator map_it = Output_Object_to_RHS_of_PrimaryOutputs.begin(); map_it != Output_Object_to_RHS_of_PrimaryOutputs.end(); map_it++) { Aig_Obj_t* output_obj = map_it->first; Aig_Obj_t* output = map_it->second; Aig_Obj_t* output_after_replacement; output_after_replacement = replaceVariablesByFormulas(output, variable_to_skolem_function_map); assert(output_after_replacement != NULL); map::iterator Ci_id_to_Ci_name_map_it = Ci_id_to_Ci_name_map.find(output_obj->Id); assert(Ci_id_to_Ci_name_map_it != Ci_id_to_Ci_name_map.end()); string output_name = Ci_id_to_Ci_name_map_it->second; assert(output_name.find(CIRCUITOUTPREFIX) != string::npos); int first_location = output_name.find_last_of("_"); string first_index_string = output_name.substr(first_location+1); output_name = "primaryout_"; output_name += first_index_string; Aig_Obj_t* output_after_replacement_CO = Aig_ObjCreateCo( pub_aig_manager, output_after_replacement ); assert(output_after_replacement_CO != NULL); idName.insert(make_pair(output_after_replacement_CO->Id, output_name)); } output_names.sort(compare_tsietin); number_of_state_elements = output_names.size(); for(list::iterator output_names_it = output_names.begin(); output_names_it != output_names.end(); output_names_it++) { string output_name = *output_names_it; map::iterator output_name_to_replaced_factor_it = output_name_to_replaced_factor.find(output_name); Aig_Obj_t* factor_after_replacement = output_name_to_replaced_factor_it->second; // factor after replacement is formula for a latchout Aig_Obj_t* factor_after_replacement_CO = Aig_ObjCreateCo( pub_aig_manager, factor_after_replacement ); assert(factor_after_replacement_CO != NULL); idName.insert(make_pair(factor_after_replacement_CO->Id, output_name)); } int i; Aig_Obj_t * pObj; Aig_ManForEachPiSeq(pub_aig_manager, pObj, i) { map::iterator Ci_id_to_Ci_name_map_it = Ci_id_to_Ci_name_map.find(pObj->Id); assert(Ci_id_to_Ci_name_map_it != Ci_id_to_Ci_name_map.end()); string input_name = Ci_id_to_Ci_name_map_it->second; if(input_name.find(LATCHPREFIX) != string::npos) { int first_location = input_name.find_last_of("_"); string first_index_string = input_name.substr(first_location+1); input_name = "state_"; input_name += first_index_string; idName.insert(make_pair(pObj->Id, input_name)); } } Abc_Ntk_t* component_network = obtainNetworkFromFragmentOfAIGWithIdNames(pub_aig_manager, idName); //Abc_NtkMakeSequential(component_network, Abc_NtkPoNum(component_network)); Abc_NtkMakeSequential(component_network, number_of_state_elements); // Let's look at the network abcFrame->pNtkCur = Abc_NtkDup(component_network); char verilog_file_char[100]; string verilog_file = benchmark_name_without_extension; char iterations_of_loop_char[10]; sprintf(iterations_of_loop_char, "%d", iterations_of_loop); string iterations_of_loop_string(iterations_of_loop_char); verilog_file += "_component"; verilog_file += iterations_of_loop_string; verilog_file += ".v"; string command = "w "; command += verilog_file; cout << command << endl; if (abcObj->comExecute(abcFrame, command)) { cout << "cannot execute command " << command << endl; assert(false); } } else if(write_component_in_file) { Aig_Obj_t* component; component = generateComponent(transition_function, variable_to_skolem_function_map); assert(component != NULL); Aig_Obj_t* component_CO = Aig_ObjCreateCo( pub_aig_manager, component ); assert(component_CO != NULL); Aig_Man_t* component_aig_manager; component_aig_manager = simplifyUsingConeOfInfluence( pub_aig_manager, Aig_ManCoNum(pub_aig_manager)-1, 1 ); assert(component_aig_manager != NULL); char verilog_file_char[100]; string verilog_file = benchmark_name_without_extension; char iterations_of_loop_char[10]; sprintf(iterations_of_loop_char, "%d", iterations_of_loop); string iterations_of_loop_string(iterations_of_loop_char); verilog_file += "_component"; verilog_file += iterations_of_loop_string; char pname[100]; strcpy(pname, verilog_file.c_str()); component_aig_manager->pName = pname; verilog_file += ".v"; strcpy(verilog_file_char, verilog_file.c_str()); int total_no_of_cis = number_of_Cis; writeCombinationalCircuitInVerilog(component_aig_manager, 0, 0, 0, total_no_of_cis, verilog_file_char, false ); cout << "\nComponent " << iterations_of_loop << " written in file " << verilog_file << "\n"; string dump_file = benchmark_name_without_extension; dump_file += "_component"; dump_file += iterations_of_loop_string; dump_file += "_dump"; writeFormulaToFile(pub_aig_manager, component, dump_file, ".v", 0, 0); #ifdef DEBUG_SKOLEM string component_file_name = benchmark_name_without_extension; component_file_name += "_component"; writeFormulaToFile(pub_aig_manager, component, component_file_name, ".v", iterations_of_loop, 0); #endif } #ifdef RECORD_KEEP gettimeofday (&step_finish_ms, NULL); step_ms = step_finish_ms.tv_sec * 1000 + step_finish_ms.tv_usec / 1000; step_ms -= step_start_ms.tv_sec * 1000 + step_start_ms.tv_usec / 1000; record_fp = fopen(record_file.c_str(), "a+"); assert(record_fp != NULL); fprintf(record_fp, "\n\n\ncomponent generation time = %llu\n", step_ms); fclose(record_fp); #endif number_of_components_generated++; #ifdef RECORD_KEEP gettimeofday (&step_start_ms, NULL); #endif Aig_Obj_t* covered_edges_by_component; covered_edges_by_component = generateCoveredEdges(transition_function_parts, variable_to_skolem_function_map); assert(covered_edges_by_component != NULL); #ifdef RECORD_KEEP gettimeofday (&step_finish_ms, NULL); step_ms = step_finish_ms.tv_sec * 1000 + step_finish_ms.tv_usec / 1000; step_ms -= step_start_ms.tv_sec * 1000 + step_start_ms.tv_usec / 1000; record_fp = fopen(record_file.c_str(), "a+"); assert(record_fp != NULL); fprintf(record_fp, "\ncovered edges generation time = %llu\n", step_ms); fclose(record_fp); #endif #ifdef DEBUG_SKOLEM string covered_edges_by_component_file_name = benchmark_name_without_extension; covered_edges_by_component_file_name += "_covered_edges_by_component"; writeFormulaToFile(pub_aig_manager, covered_edges_by_component, covered_edges_by_component_file_name, ".v", iterations_of_loop, 0); #endif Aig_Obj_t* uncovered_edges_by_component; uncovered_edges_by_component = createNot(covered_edges_by_component, pub_aig_manager); assert(uncovered_edges_by_component != NULL); Aig_Obj_t* uncovered_edges_by_component_CO = Aig_ObjCreateCo( pub_aig_manager, uncovered_edges_by_component ); assert(uncovered_edges_by_component_CO != NULL); uncovered_edges_factors.insert(uncovered_edges_by_component); uncovered_edges = createAnd(uncovered_edges, uncovered_edges_by_component, pub_aig_manager); assert(uncovered_edges != NULL); unsigned long long int cnf_time; int formula_size; unsigned long long int simplification_time; map model_of_satcheck; #ifdef RECORD_KEEP gettimeofday (&step_start_ms, NULL); #endif more_components_existing = isSat(pub_aig_manager, uncovered_edges, model_of_satcheck, cnf_time, formula_size, simplification_time); #ifdef RECORD_KEEP gettimeofday (&step_finish_ms, NULL); step_ms = step_finish_ms.tv_sec * 1000 + step_finish_ms.tv_usec / 1000; step_ms -= step_start_ms.tv_sec * 1000 + step_start_ms.tv_usec / 1000; record_fp = fopen(record_file.c_str(), "a+"); assert(record_fp != NULL); fprintf(record_fp, "\nsatisfiability check time = %llu\n", step_ms); fclose(record_fp); #endif #ifdef DEBUG_SKOLEM cout << "\nLoop iteration " << iterations_of_loop << " finished\n"; #endif iterations_of_loop++; #ifdef DEBUG_SKOLEM cout << "\nPress any key to continue..."; char c = getchar(); #endif } }//if(component_generation_strategy == uncovered_edge) else { cout << "\nUnknown component generation strategy " << component_generation_strategy << endl; assert(false); } } Aig_Obj_t* AIGBasedSkolem::generateComponent(Aig_Obj_t* transition_function, map &variable_to_skolem_function_map) { // component is transition_function[variables --> skolem functions] Aig_Obj_t* component; component = replaceVariablesByFormulas(transition_function, variable_to_skolem_function_map); assert(component != NULL); return component; } Aig_Obj_t* AIGBasedSkolem::generateCoveredEdges(set &transition_function_parts, map &variable_to_skolem_function_map) { // covered_edges_by_component is conjunction of // transition_function_parts[variables --> skolem functions] Aig_Obj_t* covered_edges_by_component; set covered_edges_by_component_parts; for(set::iterator part_it = transition_function_parts.begin(); part_it != transition_function_parts.end(); part_it++) { Aig_Obj_t* transition_function_part = *part_it; // f_i(X, I) Aig_Obj_t* transition_function_part_after_replacement; transition_function_part_after_replacement = replaceVariablesByFormulas(transition_function_part, variable_to_skolem_function_map); assert(transition_function_part_after_replacement != NULL); // f_i(x, G(X)) Aig_Obj_t* covered_edges_by_component_part; covered_edges_by_component_part = createEquivalence(transition_function_part, transition_function_part_after_replacement, pub_aig_manager); assert(covered_edges_by_component_part != NULL); // f_i(X, I) \equiv f_i(x, G(X)) covered_edges_by_component_parts.insert(covered_edges_by_component_part); } covered_edges_by_component = createAnd(covered_edges_by_component_parts, pub_aig_manager); assert(covered_edges_by_component != NULL); return covered_edges_by_component; } void AIGBasedSkolem::clearAllDataStructures() { // All variables declared in AIGBasedSkolem class to be cleared // global variables number_of_factors = 0; number_of_vars_to_elim = 0; var_name_to_var_index_map.clear(); var_index_to_var_name_map.clear(); FactorMatrix.clear(); SkolemFunctions.clear(); AlphaCombineds.clear(); GammaCombineds.clear(); BadSets.clear(); FixedCNF.clear(); CNFForRenamedConjunctionOfFactors.clear(); top_labels_of_skolem_functions.clear(); Connections.clear(); top_labels_of_connections.clear(); end_locations_of_connections_sensitive_to_skolem_function.clear(); start_locations_of_connections_skolem_function_is_sensitive_to.clear(); refinement_hints.clear(); // local variables FactorsWithVariable.clear(); CofactorOneMatrix.clear(); CofactorZeroMatrix.clear(); AlphaMatrix.clear(); BetaMatrix.clear(); GammaMatrix.clear(); DeltaMatrix.clear(); original_factor_sizes.clear(); abstracted_factor_sizes.clear(); original_factor_support_sizes.clear(); original_factor_varstoelim_sizes.clear(); FactorsAffectingSkolemFunction.clear(); sizes_of_factors_affecting_variable.clear(); sizes_of_conflict_conjuncts_affecting_variable.clear(); sizes_of_cofactors_affecting_variable.clear(); sizes_of_factors_with_variable.clear(); PreviousFactorsWithVariable.clear(); // All variables declared in helper.cpp to be cleared cumulative_time_in_compute_size = cumulative_time_in_compute_size + total_time_in_compute_size; // to keep track of cumulative time in size computation across all skolem function generation calls // data to plot sum_of_number_of_factors_containing_variable = 0; sum_of_skolem_function_sizes = 0; total_number_of_compose_operations = 0; total_time_in_compose_operations = 0; total_time_in_alpha_combined = 0; total_time_in_delta_part = 0; total_time_in_correction_part = 0; total_time_in_delta_combined = 0; total_time_in_next_factor = 0; sum_of_skolem_function_sizes_after_reverse_substitution = 0; skolem_function_sizes_after_reverse_substitution.clear(); total_time_in_ordering = 0; total_of_skyline_sizes_in_least_cost_ordering = 0; total_time_in_compute_size = 0; total_time_in_compute_support = 0; total_time_in_generator_initialization = 0; sum_of_numbers_of_affecting_factors = 0; max_factor_size = -1; min_factor_size = -1; max_factor_varstoelim_size = -1; min_factor_varstoelim_size = -1; number_of_boolean_operations_for_variable = 0; BooleanOpTime = 0; number_of_support_operations_for_variable = 0; total_number_of_compose_operations_in_initial_skolem_function_generation = 0; total_ComposeTime_in_initial_skolem_function_generation = 0; total_number_of_boolean_operations_in_initial_skolem_function_generation = 0; total_BooleanOpTime_in_initial_skolem_function_generation = 0; total_number_of_support_operations_in_initial_skolem_function_generation = 0; total_FactorFindingTime_in_initial_skolem_function_generation = 0; size_of_quantified_result_in_bdd_like_scheme = 0; // declarations for least cost first ordering factor_graph_factors_to_vars_map.clear(); factor_graph_vars_to_factors_map.clear(); factor_graph_factors_to_topvars_map.clear(); topvars.clear(); factor_graph_vars_to_sccnos_map.clear(); factor_graph_sccnos_to_sccs_map.clear(); vars_to_eqclassnos_map.clear(); eqclassnos_to_eqclasses_map.clear(); ordered_vars_to_elim.clear(); unordered_vars_to_elim.clear(); factor_to_costs_map.clear(); skolemfunctions_to_costs_map.clear(); deltas_to_costs_map.clear(); // declarations to perform CEGAR style skolem function generation cegar_iteration_number = 0; conjunction_of_factors = NULL; B_equivalence_part = NULL; LabelTable.clear(); LabelCount = 1; Ci_name_to_Ci_label_mapForGetCNF.clear(); Ci_label_to_Ci_name_mapForGetCNF.clear(); number_of_variables_in_renamed_conjunction_of_factors = 0; total_time_in_smt_solver = 0; EvaluationTable.clear(); sensitivity_list.clear(); dependency_list.clear(); size_of_alpha_in_interpolant_computation_for_variable = -1; size_of_beta_in_interpolant_computation_for_variable = -1; time_in_interpolant_computation_for_variable = 0; total_time_in_interpolant_computation = 0; connections_starting_at_skolem_function.clear(); connections_ending_at_skolem_function.clear(); maximum_length_of_connection_in_connection_based_scheme = 0; number_of_connections_in_connection_based_scheme = 0; number_of_connections_updated_in_iteration_in_connection_based_scheme = 0; values_of_variables_from_bad_to_var.clear(); values_of_variables_from_var.clear(); values_of_Y_variables.clear(); // declarations to perform incremental solving Z_variable_counter.clear(); I_variable_counter.clear(); temporary_variable_for_incremental_solving_to_object_map.clear(); IncrementalLabelTableForExactnessCheck.clear(); IncrementalLabelCountForExactnessCheck = 1; Ci_name_to_Ci_label_mapForExactnessCheck.clear(); Ci_label_to_Ci_name_mapForExactnessCheck.clear(); IncrementalLabelTableForMismatchCheck.clear(); IncrementalLabelCountForMismatchCheck = 1; Ci_name_to_Ci_label_mapForMismatchCheck.clear(); Ci_label_to_Ci_name_mapForMismatchCheck.clear(); // the following are for debugging BetaCombineds.clear(); AlphaOrGammaCombineds.clear(); GammaDisjunctions.clear(); DeltaDisjunctions.clear(); DeltasForSpecificVariable.clear(); // following in data collection total_time_in_initial_abstraction_generation_in_cegar = 0; total_time_in_cegar_loops_in_cegar = 0; total_time_in_connection_substitution_in_cegar = 0; total_time_in_reverse_substitution_in_cegar = 0; total_time_in_exactness_checking_in_cegar = 0; total_time_in_x_new_recompution_in_cegar = 0; total_time_in_reevaluation_in_cegar = 0; number_of_exactness_checking_in_cegar = 0; number_of_x_new_recompution_in_cegar = 0; number_of_reevaluation_in_cegar = 0; size_computation_time_in_initialization = 0; size_computation_time_in_initial_abstraction_generation_in_cegar = 0; size_computation_time_in_reverse_substitution_in_cegar = 0; size_computation_time_in_cegar_loops_in_cegar = 0; size_computation_time_in_connection_substitution_in_cegar = 0; sizes_of_exactness_formulae_in_cegar.clear(); times_in_cnf_generation_in_cegar.clear(); times_in_sat_solving_in_cegar.clear(); times_in_aig_simplification_in_cegar.clear(); total_time_in_true_sat_solving_in_cegar = 0; total_time_in_false_sat_solving_in_cegar = 0; total_time_in_sat_solving_in_cegar = 0; // for using generic Skolem functions inside CEGAR cannot_be_one_count = 0; cannot_be_zero_count = 0; cannot_be_string_to_cannot_be_object_map.clear(); cannot_be_object_to_cannot_be_dag_map.clear(); cannot_be_one_set.clear(); cannot_be_zero_set.clear(); initial_cannot_be_zero_dags.clear(); initial_cannot_be_zero_objects.clear(); size_of_conjunction_of_factors = 0; sizes_of_cannot_be_one_elements_of_variable.clear(); sizes_of_cannot_be_zero_elements_of_variable.clear(); cegar_iteration_for_correction_index = 0; variables_not_quantified.clear(); original_variables.clear(); variables_quantified.clear(); total_time_in_mu_evaluation_in_cegar = 0; total_time_in_interpolant_computation_in_cegar = 0; total_time_in_dontcare_optimization_in_cegar = 0; D_variable_counter.clear(); S_variable_counter.clear(); total_time_in_generalization_in_mu_based_scheme_with_optimizations_in_cegar = 0; IncrementalLabelTableForGeneralizationCheck.clear(); IncrementalLabelCountForGeneralizationCheck = 1; Ci_name_to_Ci_label_mapForGeneralizationCheck.clear(); Ci_label_to_Ci_name_mapForGeneralizationCheck.clear(); Y_variable_counter.clear(); N_i_index_to_N_i_object_map.clear(); bads_to_exclude.clear(); cumulative_time_in_compute_size = 0; assumptions_flag = 1; } void AIGBasedSkolem::benchmarkGeneration(set &transition_function_factors, map &output_string_to_transition_function_parts, list &VariablesToEliminate) { int number_of_variables_to_eliminate = VariablesToEliminate.size(); int original_no_of_cis = number_of_Cis; assert(!transition_function_factors.empty()); // each element is x_i' \equiv f_i(X, I) assert(!output_string_to_transition_function_parts.empty()); // each element is string x_i' --> f_i(X, I) map variable_to_skolem_function_map; // This stores x_i ---> true for(list::iterator list_it = VariablesToEliminate.begin(); list_it != VariablesToEliminate.end(); list_it++) { string variable_to_eliminate = *list_it; Aig_Obj_t* skolem_function = createTrue(pub_aig_manager); assert(skolem_function != NULL); variable_to_skolem_function_map.insert(make_pair(variable_to_eliminate, skolem_function)); } // let's see output_string_to_transition_function_parts #ifdef DEBUG_SKOLEM cout << "\noutput_string_to_transition_function_parts\n"; for(map::iterator map_it = output_string_to_transition_function_parts.begin(); map_it != output_string_to_transition_function_parts.end(); map_it++) { cout << endl << map_it->first << "\t" << map_it->second << endl; string transition_function_part_file_name = benchmark_name_without_extension; transition_function_part_file_name += "_"; transition_function_part_file_name += map_it->first; transition_function_part_file_name += "_transition_function_part"; writeFormulaToFile(pub_aig_manager, map_it->second, transition_function_part_file_name, ".v", 0, 0); } #endif map input_object_to_transition_function_parts; for(map::iterator map_it = output_string_to_transition_function_parts.begin(); map_it != output_string_to_transition_function_parts.end(); map_it++) { string latchout_name = map_it->first; int index_of_uscore = latchout_name.find_last_of("_"); string latchout_part = latchout_name.substr(0, index_of_uscore); assert(latchout_part == "LATCHOUT"); string location_str = latchout_name.substr(index_of_uscore+1); string latchin_name = "LATCHIN_"; latchin_name += location_str; map::iterator Ci_name_to_Ci_object_map_it = Ci_name_to_Ci_object_map.find(latchin_name); assert(Ci_name_to_Ci_object_map_it != Ci_name_to_Ci_object_map.end()); Aig_Obj_t* input_object = Ci_name_to_Ci_object_map_it->second; assert(input_object != NULL); input_object_to_transition_function_parts.insert(make_pair(input_object, map_it->second)); } #ifdef DEBUG_SKOLEM cout << "\ninput_object_to_transition_function_parts\n"; int file_counter = 1; for(map::iterator map_it = input_object_to_transition_function_parts.begin(); map_it != input_object_to_transition_function_parts.end(); map_it++) { string transition_function_part_file_name = benchmark_name_without_extension; transition_function_part_file_name += "_transition_function_part"; writeFormulaToFile(pub_aig_manager, map_it->second, transition_function_part_file_name, ".v", 0, file_counter); string transition_function_name_file_name = benchmark_name_without_extension; transition_function_name_file_name += "_transition_function_name"; writeFormulaToFile(pub_aig_manager, map_it->first, transition_function_name_file_name, ".v", 0, file_counter); file_counter++; } #endif set single_bit_differing_from_true_components; // This has (f_1(X, I) = f_1(X, true)) \wedge \ldots \wedge (f_m(X, I) \neq f_m(X, true)) set single_bit_differing_from_cycle_components; // This has (f_1(X, I) = x_1) \wedge \ldots \wedge (f_m(X, I) \neq x_m) set all_bit_differing_from_true_components; set all_bit_differing_from_cycle_components; int part_number = 1; int number_of_parts = input_object_to_transition_function_parts.size(); for(map::iterator map_it = input_object_to_transition_function_parts.begin(); map_it != input_object_to_transition_function_parts.end(); map_it++) { Aig_Obj_t* transition_function_part = map_it->second; // f_i(X, I) Aig_Obj_t* transition_function_name = map_it->first; // x_i Aig_Obj_t* transition_function_part_after_replacement; transition_function_part_after_replacement = replaceVariablesByFormulas(transition_function_part, variable_to_skolem_function_map); assert(transition_function_part_after_replacement != NULL); // f_i(x, true) Aig_Obj_t* single_bit_differing_from_true_component; single_bit_differing_from_true_component = createEquivalence(transition_function_part, transition_function_part_after_replacement, pub_aig_manager); assert(single_bit_differing_from_true_component != NULL); // f_i(X, I) \equiv f_i(x, G(X)) Aig_Obj_t* single_bit_differing_from_cycle_component; single_bit_differing_from_cycle_component = createEquivalence(transition_function_part, transition_function_name, pub_aig_manager); assert(single_bit_differing_from_cycle_component != NULL); // f_i(X, I) \equiv x_i Aig_Obj_t* all_bit_differing_from_true_component = createNot(single_bit_differing_from_true_component, pub_aig_manager); assert(all_bit_differing_from_true_component != NULL); Aig_Obj_t* all_bit_differing_from_cycle_component = createNot(single_bit_differing_from_cycle_component, pub_aig_manager); assert(all_bit_differing_from_cycle_component != NULL); if(part_number == number_of_parts) { single_bit_differing_from_true_component = createNot(single_bit_differing_from_true_component, pub_aig_manager); assert(single_bit_differing_from_true_component != NULL); // f_i(X, I) \neq f_i(x, G(X)) single_bit_differing_from_cycle_component = createNot(single_bit_differing_from_cycle_component, pub_aig_manager); assert(single_bit_differing_from_cycle_component != NULL); // f_i(X, I) \neq x_i } single_bit_differing_from_true_components.insert(single_bit_differing_from_true_component); single_bit_differing_from_cycle_components.insert(single_bit_differing_from_cycle_component); all_bit_differing_from_true_components.insert(all_bit_differing_from_true_component); all_bit_differing_from_cycle_components.insert(all_bit_differing_from_cycle_component); part_number++; } int fresh_count = 1; set all_bit_differing_from_true_tseitin_components; set fresh_objects_for_all_bit_differing_from_true_tseitin_components; for(set::iterator all_bit_differing_from_true_components_it = all_bit_differing_from_true_components.begin(); all_bit_differing_from_true_components_it != all_bit_differing_from_true_components.end(); all_bit_differing_from_true_components_it++) { Aig_Obj_t* all_bit_differing_from_true_component = *all_bit_differing_from_true_components_it; Aig_Obj_t* fresh_object = Aig_ObjCreateCi(pub_aig_manager); assert(fresh_object != NULL); fresh_objects_for_all_bit_differing_from_true_tseitin_components.insert(fresh_object); char fresh_count_char[100]; sprintf(fresh_count_char, "%d", fresh_count); string fresh_count_string(fresh_count_char); string fresh_object_string = "f_"; fresh_object_string += fresh_count_string; fresh_count++; int fresh_object_id = Aig_ObjId(fresh_object); Ci_id_to_Ci_name_map.insert(make_pair(fresh_object_id, fresh_object_string)); Ci_name_to_Ci_number_map.insert(make_pair(fresh_object_string, number_of_Cis)); number_of_Cis++; Aig_Obj_t* all_bit_differing_from_true_tseitin_component = createEquivalence(fresh_object, all_bit_differing_from_true_component, pub_aig_manager); assert(all_bit_differing_from_true_tseitin_component != NULL); all_bit_differing_from_true_tseitin_components.insert(all_bit_differing_from_true_tseitin_component); } int no_of_cis_with_f_variables = number_of_Cis; assert(fresh_objects_for_all_bit_differing_from_true_tseitin_components.size() > 0); Aig_Obj_t* all_bit_differing_from_true_tseitin_component = createOr(fresh_objects_for_all_bit_differing_from_true_tseitin_components, pub_aig_manager); assert(all_bit_differing_from_true_tseitin_component != NULL); all_bit_differing_from_true_tseitin_components.insert(all_bit_differing_from_true_tseitin_component); fresh_count = 1; set all_bit_differing_from_cycle_tseitin_components; set fresh_objects_for_all_bit_differing_from_cycle_tseitin_components; for(set::iterator all_bit_differing_from_cycle_components_it = all_bit_differing_from_cycle_components.begin(); all_bit_differing_from_cycle_components_it != all_bit_differing_from_cycle_components.end(); all_bit_differing_from_cycle_components_it++) { Aig_Obj_t* all_bit_differing_from_cycle_component = *all_bit_differing_from_cycle_components_it; Aig_Obj_t* fresh_object = Aig_ObjCreateCi(pub_aig_manager); assert(fresh_object != NULL); fresh_objects_for_all_bit_differing_from_cycle_tseitin_components.insert(fresh_object); char fresh_count_char[100]; sprintf(fresh_count_char, "%d", fresh_count); string fresh_count_string(fresh_count_char); string fresh_object_string = "g_"; fresh_object_string += fresh_count_string; fresh_count++; int fresh_object_id = Aig_ObjId(fresh_object); Ci_id_to_Ci_name_map.insert(make_pair(fresh_object_id, fresh_object_string)); Ci_name_to_Ci_number_map.insert(make_pair(fresh_object_string, number_of_Cis)); number_of_Cis++; Aig_Obj_t* all_bit_differing_from_cycle_tseitin_component = createEquivalence(fresh_object, all_bit_differing_from_cycle_component, pub_aig_manager); assert(all_bit_differing_from_cycle_tseitin_component != NULL); all_bit_differing_from_cycle_tseitin_components.insert(all_bit_differing_from_cycle_tseitin_component); } int total_no_of_cis = number_of_Cis; assert(fresh_objects_for_all_bit_differing_from_cycle_tseitin_components.size() > 0); Aig_Obj_t* all_bit_differing_from_cycle_tseitin_component = createOr(fresh_objects_for_all_bit_differing_from_cycle_tseitin_components, pub_aig_manager); assert(all_bit_differing_from_cycle_tseitin_component != NULL); all_bit_differing_from_cycle_tseitin_components.insert(all_bit_differing_from_cycle_tseitin_component); assert(single_bit_differing_from_true_components.size() > 0); Aig_Obj_t* single_bit_differing_from_true = createAnd(single_bit_differing_from_true_components, pub_aig_manager); assert(single_bit_differing_from_true != NULL); #ifdef DEBUG_SKOLEM string single_bit_differing_from_true_file_name = benchmark_name_without_extension; single_bit_differing_from_true_file_name += "_single_bit_differing_from_true"; writeFormulaToFile(pub_aig_manager, single_bit_differing_from_true, single_bit_differing_from_true_file_name, ".v", 0, 0); #endif assert(single_bit_differing_from_cycle_components.size() > 0); Aig_Obj_t* single_bit_differing_from_cycle = createAnd(single_bit_differing_from_cycle_components, pub_aig_manager); assert(single_bit_differing_from_cycle != NULL); #ifdef DEBUG_SKOLEM string single_bit_differing_from_cycle_file_name = benchmark_name_without_extension; single_bit_differing_from_cycle_file_name += "_single_bit_differing_from_cycle"; writeFormulaToFile(pub_aig_manager, single_bit_differing_from_cycle, single_bit_differing_from_cycle_file_name, ".v", 0, 0); #endif assert(all_bit_differing_from_true_tseitin_components.size() > 0); Aig_Obj_t* all_bit_differing_from_true_tseitin = createAnd(all_bit_differing_from_true_tseitin_components, pub_aig_manager); assert(all_bit_differing_from_true_tseitin != NULL); #ifdef DEBUG_SKOLEM string all_bit_differing_from_true_tseitin_file_name = benchmark_name_without_extension; all_bit_differing_from_true_tseitin_file_name += "_all_bit_differing_from_true_tseitin"; writeFormulaToFile(pub_aig_manager, all_bit_differing_from_true_tseitin, all_bit_differing_from_true_tseitin_file_name, ".v", 0, 0); #endif assert(all_bit_differing_from_cycle_tseitin_components.size() > 0); Aig_Obj_t* all_bit_differing_from_cycle_tseitin = createAnd(all_bit_differing_from_cycle_tseitin_components, pub_aig_manager); assert(all_bit_differing_from_cycle_tseitin != NULL); #ifdef DEBUG_SKOLEM string all_bit_differing_from_cycle_tseitin_file_name = benchmark_name_without_extension; all_bit_differing_from_cycle_tseitin_file_name += "_all_bit_differing_from_cycle_tseitin"; writeFormulaToFile(pub_aig_manager, all_bit_differing_from_cycle_tseitin, all_bit_differing_from_cycle_tseitin_file_name, ".v", 0, 0); #endif // Printing in files Aig_Obj_t* single_bit_differing_from_cycle_CO; single_bit_differing_from_cycle_CO = Aig_ObjCreateCo( pub_aig_manager, single_bit_differing_from_cycle ); assert(single_bit_differing_from_cycle_CO != NULL); Aig_Man_t* single_bit_differing_from_cycle_aig_manager; single_bit_differing_from_cycle_aig_manager = simplifyUsingConeOfInfluence( pub_aig_manager, Aig_ManCoNum(pub_aig_manager)-1, 1 ); assert(single_bit_differing_from_cycle_aig_manager != NULL); char verilog_file_char[100]; string verilog_file = benchmark_name_without_extension; verilog_file += "_single_bit_differing_from_cycle"; char pname[100]; strcpy(pname, verilog_file.c_str()); single_bit_differing_from_cycle_aig_manager->pName = pname; verilog_file += ".v"; strcpy(verilog_file_char, verilog_file.c_str()); writeCombinationalCircuitInVerilog(single_bit_differing_from_cycle_aig_manager, number_of_variables_to_eliminate, original_no_of_cis, no_of_cis_with_f_variables, total_no_of_cis, verilog_file_char, false ); cout << "\nBenchmark file " << verilog_file << " written\n"; Aig_Obj_t* single_bit_differing_from_true_CO; single_bit_differing_from_true_CO = Aig_ObjCreateCo( pub_aig_manager, single_bit_differing_from_true ); assert(single_bit_differing_from_true_CO != NULL); Aig_Man_t* single_bit_differing_from_true_aig_manager; single_bit_differing_from_true_aig_manager = simplifyUsingConeOfInfluence( pub_aig_manager, Aig_ManCoNum(pub_aig_manager)-1, 1 ); assert(single_bit_differing_from_true_aig_manager != NULL); verilog_file = benchmark_name_without_extension; verilog_file += "_single_bit_differing_from_true"; strcpy(pname, verilog_file.c_str()); single_bit_differing_from_true_aig_manager->pName = pname; verilog_file += ".v"; strcpy(verilog_file_char, verilog_file.c_str()); writeCombinationalCircuitInVerilog(single_bit_differing_from_true_aig_manager, number_of_variables_to_eliminate, original_no_of_cis, no_of_cis_with_f_variables, total_no_of_cis, verilog_file_char, false ); cout << "\nBenchmark file " << verilog_file << " written\n"; Aig_Obj_t* all_bit_differing_from_cycle_tseitin_CO; all_bit_differing_from_cycle_tseitin_CO = Aig_ObjCreateCo( pub_aig_manager, all_bit_differing_from_cycle_tseitin ); assert(all_bit_differing_from_cycle_tseitin_CO != NULL); Aig_Man_t* all_bit_differing_from_cycle_tseitin_aig_manager; all_bit_differing_from_cycle_tseitin_aig_manager = simplifyUsingConeOfInfluence( pub_aig_manager, Aig_ManCoNum(pub_aig_manager)-1, 1 ); assert(all_bit_differing_from_cycle_tseitin_aig_manager != NULL); verilog_file = benchmark_name_without_extension; verilog_file += "_all_bit_differing_from_cycle_tseitin"; strcpy(pname, verilog_file.c_str()); all_bit_differing_from_cycle_tseitin_aig_manager->pName = pname; verilog_file += ".v"; strcpy(verilog_file_char, verilog_file.c_str()); writeCombinationalCircuitInVerilog(all_bit_differing_from_cycle_tseitin_aig_manager, number_of_variables_to_eliminate, original_no_of_cis, no_of_cis_with_f_variables, total_no_of_cis, verilog_file_char, false ); cout << "\nBenchmark file " << verilog_file << " written\n"; Aig_Obj_t* all_bit_differing_from_true_tseitin_CO; all_bit_differing_from_true_tseitin_CO = Aig_ObjCreateCo( pub_aig_manager, all_bit_differing_from_true_tseitin ); assert(all_bit_differing_from_true_tseitin_CO != NULL); Aig_Man_t* all_bit_differing_from_true_tseitin_aig_manager; all_bit_differing_from_true_tseitin_aig_manager = simplifyUsingConeOfInfluence( pub_aig_manager, Aig_ManCoNum(pub_aig_manager)-1, 1 ); assert(all_bit_differing_from_true_tseitin_aig_manager != NULL); verilog_file = benchmark_name_without_extension; verilog_file += "_all_bit_differing_from_true_tseitin"; strcpy(pname, verilog_file.c_str()); all_bit_differing_from_true_tseitin_aig_manager->pName = pname; verilog_file += ".v"; strcpy(verilog_file_char, verilog_file.c_str()); writeCombinationalCircuitInVerilog(all_bit_differing_from_true_tseitin_aig_manager, number_of_variables_to_eliminate, original_no_of_cis, no_of_cis_with_f_variables, total_no_of_cis, verilog_file_char, false ); cout << "\nBenchmark file " << verilog_file << " written\n"; } Aig_Obj_t* AIGBasedSkolem::computeInitialSkolemFunctionsBadSetsAndCannotBeSets(int var_to_elim_index) { Aig_Obj_t* skolem_function; Aig_Obj_t* skolem_function_part1; Aig_Obj_t* skolem_function_part2; set skolem_function_part1_components; set skolem_function_part2_components; Aig_Obj_t* initial_cbzero_part_for_bad; Aig_Obj_t* initial_cbone_part_for_bad; // compute the elements in cb0_k and cb1_k set cannot_be_one_set_for_var_to_elim_index; set cannot_be_zero_set_for_var_to_elim_index; for(set::iterator factor_it = FactorsWithVariable.begin(); factor_it != FactorsWithVariable.end(); factor_it++) { int factor_index = *factor_it; #ifdef DEBUG_SKOLEM cout << "\nfactor_index = " << factor_index << endl; #endif Aig_Obj_t* neg_cofactor_1 = computeNegatedCofactorOne(var_to_elim_index, factor_index); assert(neg_cofactor_1 != NULL); sizes_of_cannot_be_one_elements_of_variable.push_back(computeSize(neg_cofactor_1, pub_aig_manager)); // connecting to some output to avoid unwanted deletion Aig_Obj_t* neg_cofactor_1_CO = Aig_ObjCreateCo(pub_aig_manager, neg_cofactor_1 ); assert(neg_cofactor_1_CO != NULL); Aig_Obj_t* neg_cofactor_0 = computeNegatedCofactorZero(var_to_elim_index, factor_index); assert(neg_cofactor_0 != NULL); sizes_of_cannot_be_zero_elements_of_variable.push_back(computeSize(neg_cofactor_0, pub_aig_manager)); // connect to some output to avoid unwanted deletion Aig_Obj_t* neg_cofactor_0_CO = Aig_ObjCreateCo(pub_aig_manager, neg_cofactor_0 ); assert(neg_cofactor_0_CO != NULL); #ifdef DEBUG_SKOLEM writeFormulaToFile(pub_aig_manager, neg_cofactor_1, "neg_cofactor_1", ".v", var_to_elim_index, factor_index); writeFormulaToFile(pub_aig_manager, neg_cofactor_0, "neg_cofactor_0", ".v", var_to_elim_index, factor_index); #endif // Allocate strings and objects for the dags neg_cofactor_1 and neg_cofactor_0 string cannot_be_one_string; Aig_Obj_t* cannot_be_one_object; allocateStringAndObjectToCannotBeDag(1, neg_cofactor_1, cannot_be_one_string, cannot_be_one_object); string cannot_be_zero_string; Aig_Obj_t* cannot_be_zero_object; allocateStringAndObjectToCannotBeDag(0, neg_cofactor_0, cannot_be_zero_string, cannot_be_zero_object); #ifdef DEBUG_SKOLEM show_cannot_be_string_to_cannot_be_object_map(); show_cannot_be_object_to_cannot_be_dag_map(); #endif // Insert the objects in respective cannot-be-sets cannot_be_one_set_for_var_to_elim_index.insert(cannot_be_one_object); cannot_be_zero_set_for_var_to_elim_index.insert(cannot_be_zero_object); // Insert the cannot-be-1 dag into the skolem_function_part1_components skolem_function_part1_components.insert(neg_cofactor_1); // Insert the cannot-be-0 dag into the skolem_function_part2_components skolem_function_part2_components.insert(neg_cofactor_0); }// for each factor ends here if(checkTimeOut()) // check for time-out { cout << "\nWarning!!Time-out inside the function AIGBasedSkolem::computeInitialSkolemFunctionsBadSetsAndCannotBeSets\n"; timed_out = true; // timed_out flag set return NULL; } // insert in global tables map >::iterator cannot_be_one_set_it = cannot_be_one_set.find(var_to_elim_index); assert(cannot_be_one_set_it == cannot_be_one_set.end()); cannot_be_one_set.insert(make_pair(var_to_elim_index, cannot_be_one_set_for_var_to_elim_index)); map >::iterator cannot_be_zero_set_it = cannot_be_zero_set.find(var_to_elim_index); assert(cannot_be_zero_set_it == cannot_be_zero_set.end()); cannot_be_zero_set.insert(make_pair(var_to_elim_index, cannot_be_zero_set_for_var_to_elim_index)); // Let's compute the skolem_function // skolem_function is // disjunction of elements in cannot_be_one_set_for_var_to_elim_index \vee // negation of (disjunction of elements in cannot_be_one_set_for_var_to_elim_index) if(cannot_be_one_set_for_var_to_elim_index.empty()) // no condition under which it can't be 1 // i.e. it can be 1 always { skolem_function_part1 = createTrue(pub_aig_manager); initial_cbone_part_for_bad = createFalse(pub_aig_manager); } else { skolem_function_part1 = createOr(skolem_function_part1_components, pub_aig_manager); initial_cbone_part_for_bad = skolem_function_part1; skolem_function_part1 = createNot(skolem_function_part1, pub_aig_manager); } assert(skolem_function_part1 != NULL); if(cannot_be_zero_set_for_var_to_elim_index.empty()) // no condition under which it can't be 0 // i.e. it can be 0 always { skolem_function_part2 = createFalse(pub_aig_manager); initial_cbzero_part_for_bad = createFalse(pub_aig_manager); } else { skolem_function_part2 = createOr(skolem_function_part2_components, pub_aig_manager); initial_cbzero_part_for_bad = skolem_function_part2; } assert(skolem_function_part2 != NULL); if(unify_code_for_mu_based_scheme_in_cegar) { if(use_cbzero_in_unified_cegar) { skolem_function = createOr(skolem_function_part2, skolem_function_part1, pub_aig_manager); } else { skolem_function = skolem_function_part1; } } else { skolem_function = createOr(skolem_function_part2, skolem_function_part1, pub_aig_manager); } assert(skolem_function != NULL); InitialSkolemFunctionSizeBeforeOptimization = computeSize(skolem_function, pub_aig_manager); if(use_dontcare_optimization_in_mu_based_scheme_with_optimizations_in_cegar) // optimize the skolem_function { // create Cb1_i \wedge Cb0_i // Cb1_i is disjunction of AIGs in cannot_be_one_set_for_var_to_elim_index, i.e. ~skolem_function_part1 Aig_Obj_t* Cb1_part = createNot(skolem_function_part1, pub_aig_manager); // Cb0_i is disjunction of AIGs in cannot_be_zero_set_for_var_to_elim_index, i.e. skolem_function_part2 Aig_Obj_t* Cb0_part = skolem_function_part2; Aig_Obj_t* dontcare_part = createAnd(Cb1_part, Cb0_part, pub_aig_manager); assert(dontcare_part != NULL); #ifdef DEBUG_SKOLEM writeFormulaToFile(pub_aig_manager, dontcare_part, "dontcare_part", ".v", var_to_elim_index, cegar_iteration_number); writeFormulaToFile(pub_aig_manager, skolem_function, "unoptimized_skolem_function", ".v", var_to_elim_index, cegar_iteration_number); #endif skolem_function = performDontCareOptimization(pub_aig_manager, skolem_function, dontcare_part); assert(skolem_function != NULL); } // connect to some output to avoid unwanted deletion Aig_Obj_t* skolem_function_part2_CO = Aig_ObjCreateCo(pub_aig_manager, skolem_function_part2 ); assert(skolem_function_part2_CO != NULL); Aig_Obj_t* skolem_function_CO = Aig_ObjCreateCo(pub_aig_manager, skolem_function ); assert(skolem_function_CO != NULL); #ifdef DEBUG_SKOLEM cout << "\nabstract skolem_function computed\n"; #endif #ifdef PRINT_SKOLEM_FUNCTIONS string skolem_function_file_name = benchmark_name_without_extension; skolem_function_file_name += "_skolem_function"; writeFormulaToFile(pub_aig_manager, skolem_function, skolem_function_file_name, ".v", var_to_elim_index, cegar_iteration_number); #endif // Enter into matrix insertIntoOneDimensionalMatrix(SkolemFunctions, number_of_vars_to_elim, var_to_elim_index, skolem_function, false); // Compute Badsets if(var_to_elim_index < number_of_vars_to_elim) // No need to compute Bad_{n+1} { Aig_Obj_t* bad_set_for_next_var; if(compute_initial_bads_from_cbs) { bad_set_for_next_var = createAnd(initial_cbzero_part_for_bad, initial_cbone_part_for_bad, pub_aig_manager); } else { set alpha_components; set beta_components; for(set::iterator factor_it = FactorsWithVariable.begin(); factor_it != FactorsWithVariable.end(); factor_it++) { int factor_index = *factor_it; #ifdef DEBUG_SKOLEM cout << "\nfactor_index = " << factor_index << endl; #endif // Suppose j = factor_index // Get alpha_i_j and beta_i_j Aig_Obj_t* alpha_i_j; alpha_i_j = computeAlpha(var_to_elim_index, factor_index); assert(alpha_i_j != NULL); #ifdef DEBUG_SKOLEM writeFormulaToFile(pub_aig_manager, alpha_i_j, "alpha", ".v", var_to_elim_index, factor_index); cout << "\nalpha_" << var_to_elim_index << "_" << factor_index << " obtained\n"; #endif Aig_Obj_t* beta_i_j; beta_i_j = computeBeta(var_to_elim_index, factor_index); assert(beta_i_j != NULL); #ifdef DEBUG_SKOLEM writeFormulaToFile(pub_aig_manager, beta_i_j, "beta", ".v", var_to_elim_index, factor_index); cout << "\nbeta_" << var_to_elim_index << "_" << factor_index << " obtained\n"; #endif alpha_components.insert(alpha_i_j); beta_components.insert(beta_i_j); }// for each factor ends here if(checkTimeOut()) // check for time-out { cout << "\nWarning!!Time-out inside the function AIGBasedSkolem::computeInitialSkolemFunctionsBadSetsAndCannotBeSets\n"; timed_out = true; // timed_out flag set return NULL; } Aig_Obj_t* alpha_part; if(alpha_components.size() == 0) // we should return false in this case (as per defn. of alpha) { alpha_part = createFalse(pub_aig_manager); assert(alpha_part != NULL); } else { alpha_part = createOr(alpha_components, pub_aig_manager); assert(alpha_part != NULL); } Aig_Obj_t* beta_part; if(beta_components.size() == 0) // we should return false in this case (as per defn. of beta) { beta_part = createFalse(pub_aig_manager); assert(beta_part != NULL); } else { beta_part = createOr(beta_components, pub_aig_manager); assert(beta_part != NULL); } bad_set_for_next_var = createAnd(alpha_part, beta_part, pub_aig_manager); } assert(bad_set_for_next_var != NULL); // connect to some output to avoid unwanted deletion Aig_Obj_t* bad_set_for_next_var_CO = Aig_ObjCreateCo(pub_aig_manager, bad_set_for_next_var ); assert(bad_set_for_next_var_CO != NULL); #ifdef DEBUG_SKOLEM cout << "\nbad_set_" << var_to_elim_index+1 << " computed\n"; writeFormulaToFile(pub_aig_manager, bad_set_for_next_var, "bad_set", ".v", var_to_elim_index+1, cegar_iteration_number); #endif // Enter into matrix insertIntoOneDimensionalMatrix(BadSets, number_of_vars_to_elim, var_to_elim_index+1, bad_set_for_next_var, false); CorrectionPartSize = computeSize(bad_set_for_next_var, pub_aig_manager); } else { CorrectionPartSize = -1; } #ifdef PRINT_VERY_DETAILED_RECORDS_ON_SCREEN cout << "\nsize of bad_set_" << var_to_elim_index+1 << " is " << CorrectionPartSize << endl; #endif if(checkTimeOut()) // check for time-out { cout << "\nWarning!!Time-out inside the function AIGBasedSkolem::computeInitialSkolemFunctionsBadSetsAndCannotBeSets\n"; timed_out = true; // timed_out flag set return NULL; } // Compute ICb0_k in terms of objects and as dag // These will be required while recomputing the Skolem functions // Let's compute these right now, since later on these sets will get changed // we already have ICb0_k dag; let's insert it map::iterator initial_cannot_be_zero_dags_it = initial_cannot_be_zero_dags.find(var_to_elim_index); assert(initial_cannot_be_zero_dags_it == initial_cannot_be_zero_dags.end()); initial_cannot_be_zero_dags.insert(make_pair(var_to_elim_index, skolem_function_part2)); // Let's compute the ICb0_k object Aig_Obj_t* initial_cannot_be_zero_object; if(cannot_be_zero_set_for_var_to_elim_index.empty()) // no condition under which it can't be 0 // i.e. it can be 0 always { initial_cannot_be_zero_object = createFalse(pub_aig_manager); } else { initial_cannot_be_zero_object = createOr(cannot_be_zero_set_for_var_to_elim_index, pub_aig_manager); } assert(initial_cannot_be_zero_object != NULL); // connect to some output to avoid unwanted deletion Aig_Obj_t* initial_cannot_be_zero_object_CO = Aig_ObjCreateCo(pub_aig_manager, initial_cannot_be_zero_object ); assert(initial_cannot_be_zero_object_CO != NULL); // let's insert it map::iterator initial_cannot_be_zero_objects_it = initial_cannot_be_zero_objects.find(var_to_elim_index); assert(initial_cannot_be_zero_objects_it == initial_cannot_be_zero_objects.end()); initial_cannot_be_zero_objects.insert(make_pair(var_to_elim_index, initial_cannot_be_zero_object)); return skolem_function; } bool AIGBasedSkolem::checkIfSkolemFunctionAtGivenIndexIsExact_using_Mu_Based_Scheme_With_Optimizations(int correction_index, map &Model_of_ExactnessCheck, map &Refinement_Hint_Of_CannotBe_One_To_Eliminate_This_CEX, map &Refinement_Hint_Of_CannotBe_Zero_To_Eliminate_This_CEX, list &VariablesToEliminate) { #ifdef RECORD_KEEP string record_file; record_file = logfile_prefix; record_file += "skolem_function_generation_details.txt"; FILE* record_fp = fopen(record_file.c_str(), "a+"); assert(record_fp != NULL); #endif if(cegar_iteration_for_correction_index == 0) { Aig_Obj_t* epsilon_zero; // Create the dag for epsilon_zero: // Let correction_index be i // dag for epsilon_zero is: // F(x_1',...,x_{i-1}',0, x_{i+1},...,x_n,Y) \wedge // (B_1 \vee ... \vee B_{i}) \wedge (B_1 = dag for bad_1) \wedge ... (B_{i} = dag for bad_{i}) \wedge // ~(disjunction of labels of Cb1_i) \wedge ~(disjunction of labels of Cb0_i) \wedge // (x_1 = psi_1) \wedge ... \wedge (x_n = psi_n) \wedge // (eta_1 = dag for eta_1) \wedge ... \wedge (eta_l = dag for eta_l) \wedge // (sigma_1 = dag for sigma_1) \wedge ... \wedge (sigma_s = dag for sigma_s) // we need to consider the eta's and sigma's of only those x_k's such that k <= i // eta's and sigma's of x_k's such that k > i are never needed // Let's first create dag for // (eta_1 = dag for eta_1) \wedge ... \wedge (eta_l = dag for eta_l) \wedge // (sigma_1 = dag for sigma_1) \wedge ... \wedge (sigma_s = dag for sigma_s) // in Cb_part Aig_Obj_t* Cb_part; set Cb_objects; for(map >::iterator cannot_be_one_set_it = cannot_be_one_set.begin(); cannot_be_one_set_it != cannot_be_one_set.end(); cannot_be_one_set_it++) { int var_to_elim_index = cannot_be_one_set_it->first; if(var_to_elim_index > correction_index) { break; } set cannot_be_one_set_objects = cannot_be_one_set_it->second; // let's find the corresponding dags for(set::iterator cannot_be_one_set_objects_it = cannot_be_one_set_objects.begin(); cannot_be_one_set_objects_it != cannot_be_one_set_objects.end(); cannot_be_one_set_objects_it++) { Aig_Obj_t* cannot_be_object = *cannot_be_one_set_objects_it; assert(cannot_be_object != NULL); map::iterator cannot_be_object_to_cannot_be_dag_map_it = cannot_be_object_to_cannot_be_dag_map.find(cannot_be_object); assert(cannot_be_object_to_cannot_be_dag_map_it != cannot_be_object_to_cannot_be_dag_map.end()); Aig_Obj_t* cannot_be_dag = cannot_be_object_to_cannot_be_dag_map_it->second; assert(cannot_be_dag != NULL); Aig_Obj_t* Cb_equivalence = createEquivalence(cannot_be_object, cannot_be_dag, pub_aig_manager); Cb_objects.insert(Cb_equivalence); } } for(map >::iterator cannot_be_zero_set_it = cannot_be_zero_set.begin(); cannot_be_zero_set_it != cannot_be_zero_set.end(); cannot_be_zero_set_it++) { int var_to_elim_index = cannot_be_zero_set_it->first; if(var_to_elim_index > correction_index) { break; } set cannot_be_zero_set_objects = cannot_be_zero_set_it->second; // let's find the corresponding dags for(set::iterator cannot_be_zero_set_objects_it = cannot_be_zero_set_objects.begin(); cannot_be_zero_set_objects_it != cannot_be_zero_set_objects.end(); cannot_be_zero_set_objects_it++) { Aig_Obj_t* cannot_be_object = *cannot_be_zero_set_objects_it; assert(cannot_be_object != NULL); map::iterator cannot_be_object_to_cannot_be_dag_map_it = cannot_be_object_to_cannot_be_dag_map.find(cannot_be_object); assert(cannot_be_object_to_cannot_be_dag_map_it != cannot_be_object_to_cannot_be_dag_map.end()); Aig_Obj_t* cannot_be_dag = cannot_be_object_to_cannot_be_dag_map_it->second; assert(cannot_be_dag != NULL); Aig_Obj_t* Cb_equivalence = createEquivalence(cannot_be_object, cannot_be_dag, pub_aig_manager); Cb_objects.insert(Cb_equivalence); } } assert(!Cb_objects.empty()); Cb_part = createAnd(Cb_objects, pub_aig_manager); assert(Cb_part != NULL); // connect to some output to avoid unwanted deletion Aig_Obj_t* Cb_part_CO = Aig_ObjCreateCo(pub_aig_manager, Cb_part ); assert(Cb_part_CO != NULL); // Let's create dag for (x_1 = psi_1) \wedge ... \wedge (x_n = psi_n) Aig_Obj_t* S_equivalence_part; set S_equivalence_objects; if(use_dontcare_optimization_in_mu_based_scheme_with_optimizations_in_cegar) { // we need to create psi_i as SkolemFunctions[i] optimized using don't cares in // (disjunction of elements in cannot_be_zero_dags[i]) \wedge (disjunction of elements in cannot_be_one_dags[i]) for(map::iterator SkolemFunctions_it = SkolemFunctions.begin(); SkolemFunctions_it != SkolemFunctions.end(); SkolemFunctions_it++) { int var_to_elim_index = SkolemFunctions_it->first; // obtaining dag for x_i string var_to_elim = searchVarIndexToVarNameMap(var_index_to_var_name_map, var_to_elim_index); map::iterator Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it = Ci_to_eliminate_name_to_Ci_to_eliminate_object_map.find(var_to_elim); assert(Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it != Ci_to_eliminate_name_to_Ci_to_eliminate_object_map.end()); Aig_Obj_t* var_to_elim_obj = Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it->second; // obtaining \psi_i_dag Aig_Obj_t* psi_i_dag = SkolemFunctions_it->second; assert(psi_i_dag != NULL); // psi_i = ite(D_0_i, psi_i_dag, S_0_i) // create D_0_i object // initialize D_variable_counter[var_to_elim_index] to 0 D_variable_counter.insert(make_pair(var_to_elim_index, 0)); int d_i_count = D_variable_counter[var_to_elim_index]; // 0 here string d_i_string = obtainDVariableString(var_to_elim_index, d_i_count); // obtain the string d_{var_to_elim_index}_0 // check if object for d_i_string is already existing; if yes return it; otherwise create, // update temporary_variable_for_incremental_solving_to_object_map and return Aig_Obj_t* d_i_object = obtainObjectOfTemporaryVariableForIncrementalSolving(d_i_string); assert(d_i_object != NULL); // create S_0_i object // initialize S_variable_counter[var_to_elim_index] to 0 S_variable_counter.insert(make_pair(var_to_elim_index, 0)); int s_i_count = S_variable_counter[var_to_elim_index]; // 0 here string s_i_string = obtainSVariableString(var_to_elim_index, s_i_count); // obtain the string s_{var_to_elim_index}_0 // check if object for s_i_string is already existing; if yes return it; otherwise create, // update temporary_variable_for_incremental_solving_to_object_map and return Aig_Obj_t* s_i_object = obtainObjectOfTemporaryVariableForIncrementalSolving(s_i_string); assert(s_i_object != NULL); // obtaining \psi_i Aig_Obj_t* psi_i; psi_i = createIte(d_i_object, psi_i_dag, s_i_object, pub_aig_manager); assert(psi_i != NULL); Aig_Obj_t* S_equivalence_i = createEquivalence(var_to_elim_obj, psi_i, pub_aig_manager); S_equivalence_objects.insert(S_equivalence_i); } } else { // we need to create psi_i as disjunction of elements in initial_cannot_be_zero_objects[i] // \vee negation of disjunction of elements in cannot-be-one-set[i] for(map >::iterator cannot_be_one_set_it = cannot_be_one_set.begin(); cannot_be_one_set_it != cannot_be_one_set.end(); cannot_be_one_set_it++) { int var_to_elim_index = cannot_be_one_set_it->first; // obtaining dag for x_i string var_to_elim = searchVarIndexToVarNameMap(var_index_to_var_name_map, var_to_elim_index); map::iterator Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it = Ci_to_eliminate_name_to_Ci_to_eliminate_object_map.find(var_to_elim); assert(Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it != Ci_to_eliminate_name_to_Ci_to_eliminate_object_map.end()); Aig_Obj_t* var_to_elim_obj = Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it->second; // obtaining \psi_i_part2 Aig_Obj_t* psi_i_part2; set psi_i_part2_components = cannot_be_one_set_it->second; if(psi_i_part2_components.empty()) { psi_i_part2 = createTrue(pub_aig_manager); } else { psi_i_part2 = createOr(psi_i_part2_components, pub_aig_manager); psi_i_part2 = createNot(psi_i_part2, pub_aig_manager); } assert(psi_i_part2 != NULL); // initialize Z_variable_counter[var_to_elim_index] to 0 Z_variable_counter.insert(make_pair(var_to_elim_index, 0)); int z_i_count = Z_variable_counter[var_to_elim_index]; // 0 here string z_i_string = obtainZVariableString(var_to_elim_index, z_i_count); // obtain the string Z_{var_to_elim_index}_0 // check if object for z_i_string is already existing; if yes return it; otherwise create, // update temporary_variable_for_incremental_solving_to_object_map and return Aig_Obj_t* z_i_object = obtainObjectOfTemporaryVariableForIncrementalSolving(z_i_string); assert(z_i_object != NULL); psi_i_part2 = createAnd(psi_i_part2, z_i_object, pub_aig_manager); assert(psi_i_part2 != NULL); // obtaining \psi_i_part1 Aig_Obj_t* psi_i_part1; map::iterator initial_cannot_be_zero_objects_it = initial_cannot_be_zero_objects.find(var_to_elim_index); assert(initial_cannot_be_zero_objects_it != initial_cannot_be_zero_objects.end()); psi_i_part1 = initial_cannot_be_zero_objects_it->second; assert(psi_i_part1 != NULL); // obtaining \psi_i Aig_Obj_t* psi_i; psi_i = createOr(psi_i_part1, psi_i_part2, pub_aig_manager); assert(psi_i != NULL); Aig_Obj_t* S_equivalence_i = createEquivalence(var_to_elim_obj, psi_i, pub_aig_manager); S_equivalence_objects.insert(S_equivalence_i); } } assert(!S_equivalence_objects.empty()); S_equivalence_part = createAnd(S_equivalence_objects, pub_aig_manager); assert(S_equivalence_part != NULL); // connect to some output to avoid unwanted deletion Aig_Obj_t* S_equivalence_part_CO = Aig_ObjCreateCo(pub_aig_manager, S_equivalence_part ); assert(S_equivalence_part_CO != NULL); // Let's create dag for // (B_1 = dag for bad_1) \wedge ... \wedge (B_{i} = dag for bad_{i}) Aig_Obj_t* B_equivalence_part; set B_equivalence_objects; Aig_Obj_t* B_part; set B_objects; for(int bad_location_index = 1; bad_location_index <= correction_index; bad_location_index++) { Aig_Obj_t* bad_set_obj; bad_set_obj = searchOneDimensionalMatrix(BadSets, number_of_vars_to_elim, bad_location_index); assert(bad_set_obj != NULL); // Obtaining dag for bad_set_obj map::iterator B_i_index_to_B_i_object_map_iterator = B_i_index_to_B_i_object_map.find(bad_location_index); assert(B_i_index_to_B_i_object_map_iterator != B_i_index_to_B_i_object_map.end()); Aig_Obj_t* B_obj = B_i_index_to_B_i_object_map_iterator->second; assert(B_obj != NULL); B_objects.insert(B_obj); Aig_Obj_t* B_equivalence_i = createEquivalence(bad_set_obj, B_obj, pub_aig_manager); B_equivalence_objects.insert(B_equivalence_i); } assert(!B_equivalence_objects.empty()); B_equivalence_part = createAnd(B_equivalence_objects, pub_aig_manager); assert(B_equivalence_part != NULL); // connect to some output to avoid unwanted deletion Aig_Obj_t* B_equivalence_part_CO = Aig_ObjCreateCo(pub_aig_manager, B_equivalence_part ); assert(B_equivalence_part_CO != NULL); // Let's create dag for // (B_1 \vee ... \vee B_{i}) assert(!B_objects.empty()); B_part = createOr(B_objects, pub_aig_manager); assert(B_part != NULL); // connect to some output to avoid unwanted deletion Aig_Obj_t* B_part_CO = Aig_ObjCreateCo(pub_aig_manager, B_part ); assert(B_part_CO != NULL); // Let's create dag for // F(x_1',...,x_{i-1}',0, x_{i+1},...,x_n,Y) // Recall that x_1',...,x_n' are already created map replacement_map_for_renamed_factor_conjunction_part; for(int var_to_elim_index = 1; var_to_elim_index <= correction_index-1; var_to_elim_index++) { map::iterator Ci_to_eliminate_renamed_to_Ci_to_eliminate_renamed_object_map_it = Ci_to_eliminate_renamed_to_Ci_to_eliminate_renamed_object_map.find(var_to_elim_index); assert(Ci_to_eliminate_renamed_to_Ci_to_eliminate_renamed_object_map_it != Ci_to_eliminate_renamed_to_Ci_to_eliminate_renamed_object_map.end()); Aig_Obj_t* var_to_elim_renamed_obj = Ci_to_eliminate_renamed_to_Ci_to_eliminate_renamed_object_map_it->second; assert(var_to_elim_renamed_obj != NULL); replacement_map_for_renamed_factor_conjunction_part.insert(make_pair(var_to_elim_index, var_to_elim_renamed_obj)); } Aig_Obj_t* renamed_factor_conjunction_part = replaceVariablesByFormulas(conjunction_of_factors, replacement_map_for_renamed_factor_conjunction_part); assert(renamed_factor_conjunction_part != NULL); renamed_factor_conjunction_part = replaceVariableByConstant(renamed_factor_conjunction_part, correction_index, 0); assert(renamed_factor_conjunction_part != NULL); // connect to some output to avoid unwanted deletion Aig_Obj_t* renamed_factor_conjunction_part_CO = Aig_ObjCreateCo(pub_aig_manager, renamed_factor_conjunction_part ); assert(renamed_factor_conjunction_part_CO != NULL); Aig_Obj_t* correction_variable_part; if(simplify_sat_calls_in_use_mu_based_scheme_with_optimizations_in_cegar) { // Let's create dag for x_i // obtaining dag for x_i string var_to_elim_at_correction_index = searchVarIndexToVarNameMap(var_index_to_var_name_map, correction_index); map::iterator Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it = Ci_to_eliminate_name_to_Ci_to_eliminate_object_map.find(var_to_elim_at_correction_index); assert(Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it != Ci_to_eliminate_name_to_Ci_to_eliminate_object_map.end()); correction_variable_part = Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it->second; assert(correction_variable_part != NULL); } else { // Let's create dags for // ~(disjunction of labels of Cb1_i) \wedge ~(disjunction of labels of Cb0_i) Aig_Obj_t* correction_variable_first_part; map >::iterator cannot_be_one_set_it = cannot_be_one_set.find(correction_index); assert(cannot_be_one_set_it != cannot_be_one_set.end()); set correction_variable_first_part_components = cannot_be_one_set_it->second; if(correction_variable_first_part_components.empty()) { correction_variable_first_part = createTrue(pub_aig_manager); } else { correction_variable_first_part = createOr(correction_variable_first_part_components, pub_aig_manager); correction_variable_first_part = createNot(correction_variable_first_part, pub_aig_manager); } assert(correction_variable_first_part != NULL); Aig_Obj_t* correction_variable_second_part; map >::iterator cannot_be_zero_set_it = cannot_be_zero_set.find(correction_index); assert(cannot_be_zero_set_it != cannot_be_zero_set.end()); set correction_variable_second_part_components = cannot_be_zero_set_it->second; if(correction_variable_second_part_components.empty()) { correction_variable_second_part = createTrue(pub_aig_manager); } else { correction_variable_second_part = createOr(correction_variable_second_part_components, pub_aig_manager); correction_variable_second_part = createNot(correction_variable_second_part, pub_aig_manager); } assert(correction_variable_second_part != NULL); correction_variable_part = createAnd(correction_variable_first_part, correction_variable_second_part, pub_aig_manager); assert(correction_variable_part != NULL); } // connect to some output to avoid unwanted deletion Aig_Obj_t* correction_variable_part_CO = Aig_ObjCreateCo(pub_aig_manager, correction_variable_part ); assert(correction_variable_part_CO != NULL); #ifdef DEBUG_SKOLEM string Cb_part_file_name = benchmark_name_without_extension; Cb_part_file_name += "_Cb_part"; string S_equivalence_part_file_name = benchmark_name_without_extension; S_equivalence_part_file_name += "_S_equivalence_part"; string B_equivalence_part_file_name = benchmark_name_without_extension; B_equivalence_part_file_name += "_B_equivalence_part"; string B_part_file_name = benchmark_name_without_extension; B_part_file_name += "_B_part"; string renamed_factor_conjunction_part_file_name = benchmark_name_without_extension; renamed_factor_conjunction_part_file_name += "_renamed_factor_conjunction_part"; string correction_variable_part_file_name = benchmark_name_without_extension; correction_variable_part_file_name += "_correction_variable_part"; cout << "\nCb_part computed\n"; cout << "\nS_equivalence_part computed\n"; cout << "\nB_equivalence_part computed\n"; cout << "\nB_part computed\n"; cout << "\nrenamed_factor_conjunction_part computed\n"; cout << "\ncorrection_variable_part computed\n"; writeFormulaToFile(pub_aig_manager, Cb_part, Cb_part_file_name, ".v", cegar_iteration_number, 0); writeFormulaToFile(pub_aig_manager, S_equivalence_part, S_equivalence_part_file_name, ".v", cegar_iteration_number, 0); writeFormulaToFile(pub_aig_manager, B_equivalence_part, B_equivalence_part_file_name, ".v", cegar_iteration_number, 0); writeFormulaToFile(pub_aig_manager, B_part, B_part_file_name, ".v", cegar_iteration_number, 0); writeFormulaToFile(pub_aig_manager, renamed_factor_conjunction_part, renamed_factor_conjunction_part_file_name, ".v", cegar_iteration_number, 0); writeFormulaToFile(pub_aig_manager, correction_variable_part, correction_variable_part_file_name, ".v", cegar_iteration_number, 0); #endif set epsilon_zero_objects; epsilon_zero_objects.insert(Cb_part); epsilon_zero_objects.insert(S_equivalence_part); epsilon_zero_objects.insert(B_equivalence_part); epsilon_zero_objects.insert(B_part); epsilon_zero_objects.insert(renamed_factor_conjunction_part); epsilon_zero_objects.insert(correction_variable_part); epsilon_zero = createAnd(epsilon_zero_objects, pub_aig_manager); assert(epsilon_zero != NULL); // connect to some output to avoid unwanted deletion Aig_Obj_t* epsilon_zero_CO = Aig_ObjCreateCo(pub_aig_manager, epsilon_zero ); assert(epsilon_zero_CO != NULL); if(Aig_IsComplement(epsilon_zero) && Aig_Regular(epsilon_zero) == createTrue(pub_aig_manager)) // epsilon_zero is false { #ifdef DEBUG_CEGAR cout << "\nAIG for epsilon_zero is false; no need to call the sat-solver\n"; #endif #ifdef RECORD_KEEP number_of_exactness_checking_in_cegar++; fprintf(record_fp, "\t0(0,0)(1)"); fclose(record_fp); #endif return true; } vector positive_assumptions_in_exactness_check; vector negative_assumptions_in_exactness_check; if(use_dontcare_optimization_in_mu_based_scheme_with_optimizations_in_cegar) { // Identify labels of D_1_0 ,..., D_n_0 and // assume that they are true (in positive_assumptions_in_exactness_check) obtainAssumptionsInExactnessCheck_using_Generic_Skolem_Functions_And_Dontcare_Optimization(positive_assumptions_in_exactness_check, negative_assumptions_in_exactness_check); assert(positive_assumptions_in_exactness_check.size() != 0); assert(negative_assumptions_in_exactness_check.size() == 0); } else { // Identify labels of Z_1_0 ,..., Z_n_0 and // assume that they are true (in positive_assumptions_in_exactness_check) obtainAssumptionsInExactnessCheck_using_Generic_Skolem_Functions(positive_assumptions_in_exactness_check); assert(positive_assumptions_in_exactness_check.size() != 0); } // Use incremental solver call #ifdef DEBUG_CEGAR string epsilon_zero_file_name = benchmark_name_without_extension; epsilon_zero_file_name += "_epsilon_zero"; cout << "\nepsilon_zero computed\n"; writeFormulaToFile(pub_aig_manager, epsilon_zero, epsilon_zero_file_name, ".v", cegar_iteration_number, 0); cout << endl << "Adding clauses of epsilon_zero to SAT-Solver, and calling SAT-Solver\n"; #endif #ifdef DETAILED_RECORD_KEEP unsigned long long int solver_ms; struct timeval solver_start_ms, solver_finish_ms; gettimeofday (&solver_start_ms, NULL); #endif // Give to SAT-Solver and get unsat / sat with model unsigned long long int cnf_time; int formula_size; unsigned long long int simplification_time; bool result_of_exactnesscheck = isExactnessCheckSatisfiable(pub_aig_manager, epsilon_zero, Model_of_ExactnessCheck, cnf_time, formula_size, simplification_time, positive_assumptions_in_exactness_check, negative_assumptions_in_exactness_check, pSat_for_exactness_check, IncrementalLabelTableForExactnessCheck, IncrementalLabelCountForExactnessCheck, Ci_name_to_Ci_label_mapForExactnessCheck, Ci_label_to_Ci_name_mapForExactnessCheck); #ifdef DETAILED_RECORD_KEEP gettimeofday (&solver_finish_ms, NULL); solver_ms = solver_finish_ms.tv_sec * 1000 + solver_finish_ms.tv_usec / 1000; solver_ms -= solver_start_ms.tv_sec * 1000 + solver_start_ms.tv_usec / 1000; cout << "\nsolver finished in " << solver_ms << " milliseconds\n"; total_time_in_smt_solver = total_time_in_smt_solver + solver_ms; total_time_in_exactness_checking_in_cegar = total_time_in_exactness_checking_in_cegar + solver_ms; number_of_exactness_checking_in_cegar++; #endif #ifdef RECORD_KEEP fprintf(record_fp, "\t%llu(%llu,%llu)(%d)", solver_ms, cnf_time, simplification_time, formula_size); fclose(record_fp); #endif #ifdef DEBUG_SKOLEM displayModelFromSATSolver(Model_of_ExactnessCheck); cout << endl << "result_of_exactnesscheck = " << result_of_exactnesscheck << endl; #endif removeTemporaryVariablesFromModel(Model_of_ExactnessCheck); #ifdef DEBUG_CEGAR cout << "\nModel after removing temporary variables\n"; displayModelFromSATSolver(Model_of_ExactnessCheck); cout << endl << "result_of_exactnesscheck = " << result_of_exactnesscheck << endl; #endif if(!result_of_exactnesscheck) // ExactnessCheck unsat i.e. skolem function at correction_index is exact { return true; } else // skolem function at correction_index is inexact { return false; } } // if(cegar_iteration_for_correction_index == 0) ends here else // if(cegar_iteration_for_correction_index > 0) { #ifdef DEBUG_CEGAR show_present_refinement_hint(Refinement_Hint_Of_CannotBe_One_To_Eliminate_This_CEX, Refinement_Hint_Of_CannotBe_Zero_To_Eliminate_This_CEX); #endif Aig_Obj_t* delta_epsilon_i; // Create the dag for delta_epsilon_i: // (o_j = dag_j) \wedge ;for each o_j added in Refinement_Hint_Of_CannotBe_One_To_Eliminate_This_CEX // (Z_i_k = Z_i_{k+1} \wedge o_j) \wedge if !use_dontcare_optimization_in_mu_based_scheme_with_optimizations_in_cegar // (S_i_k = ite(D_i_{k+1}, dag of skolem function, S_i_{k+1}) if use_dontcare_optimization_in_mu_based_scheme_with_optimizations_in_cegar // (o_l = dag_l) ;for each o_l added in Refinement_Hint_Of_CannotBe_Zero_To_Eliminate_This_CEX Aig_Obj_t* Cb_part; set Cb_objects; Aig_Obj_t* Z_part; set Z_objects; for(map::iterator hint_it = Refinement_Hint_Of_CannotBe_One_To_Eliminate_This_CEX.begin(); hint_it != Refinement_Hint_Of_CannotBe_One_To_Eliminate_This_CEX.end(); hint_it++) { int destination = hint_it->first; Aig_Obj_t* new_cannot_be_one_object_at_destination = hint_it->second; map::iterator cannot_be_object_to_cannot_be_dag_map_it = cannot_be_object_to_cannot_be_dag_map.find(new_cannot_be_one_object_at_destination); assert(cannot_be_object_to_cannot_be_dag_map_it != cannot_be_object_to_cannot_be_dag_map.end()); Aig_Obj_t* new_cannot_be_one_dag_at_destination = cannot_be_object_to_cannot_be_dag_map_it->second; Aig_Obj_t* Cb_one_equivalence = createEquivalence(new_cannot_be_one_object_at_destination, new_cannot_be_one_dag_at_destination, pub_aig_manager); assert(Cb_one_equivalence != NULL); Cb_objects.insert(Cb_one_equivalence); if(use_dontcare_optimization_in_mu_based_scheme_with_optimizations_in_cegar) { // S_i_k = ite(D_i_{k+1}, psi_destination_dag, S_i_{k+1} // obtaining \psi_destination_dag map::iterator SkolemFunctions_it = SkolemFunctions.find(destination); assert(SkolemFunctions_it != SkolemFunctions.end()); Aig_Obj_t* psi_destination_dag = SkolemFunctions_it->second; assert(psi_destination_dag != NULL); // obtain objects of S_i_k and S_i_{k+1} int present_s_j_k_count = S_variable_counter[destination]; int next_s_j_k_count = present_s_j_k_count + 1; S_variable_counter[destination] = next_s_j_k_count; string present_s_j_k_string = obtainSVariableString(destination, present_s_j_k_count); // obtain the string S_{destination}_{present_s_j_k_count} Aig_Obj_t* present_s_j_k_object = obtainExistingObjectOfTemporaryVariableForIncrementalSolving(present_s_j_k_string); assert(present_s_j_k_object != NULL); string next_s_j_k_string = obtainSVariableString(destination, next_s_j_k_count); // obtain the string S_{destination}_{next_s_j_k_count} Aig_Obj_t* next_s_j_k_object = obtainObjectOfTemporaryVariableForIncrementalSolving(next_s_j_k_string); assert(next_s_j_k_object != NULL); // obtain object of D_i_{k+1} int present_d_j_k_count = D_variable_counter[destination]; int next_d_j_k_count = present_d_j_k_count + 1; D_variable_counter[destination] = next_d_j_k_count; string next_d_j_k_string = obtainDVariableString(destination, next_d_j_k_count); // obtain the string D_{destination}_{next_d_j_k_count} Aig_Obj_t* next_d_j_k_object = obtainObjectOfTemporaryVariableForIncrementalSolving(next_d_j_k_string); assert(next_d_j_k_object != NULL); // create S_i_k = ite(D_i_{k+1}, psi_destination_dag, S_i_{k+1} Aig_Obj_t* R_i_j_increment = createEquivalence(present_s_j_k_object, createIte(next_d_j_k_object, psi_destination_dag, next_s_j_k_object, pub_aig_manager), pub_aig_manager); assert(R_i_j_increment != NULL); Z_objects.insert(R_i_j_increment); } else { int present_z_j_k_count = Z_variable_counter[destination]; int next_z_j_k_count = present_z_j_k_count + 1; Z_variable_counter[destination] = next_z_j_k_count; string present_z_j_k_string = obtainZVariableString(destination, present_z_j_k_count); // obtain the string Z_{destination}_{present_z_j_k_count} Aig_Obj_t* present_z_j_k_object = obtainExistingObjectOfTemporaryVariableForIncrementalSolving(present_z_j_k_string); assert(present_z_j_k_object != NULL); string next_z_j_k_string = obtainZVariableString(destination, next_z_j_k_count); // obtain the string Z_{destination}_{next_z_j_k_count} Aig_Obj_t* next_z_j_k_object = obtainObjectOfTemporaryVariableForIncrementalSolving(next_z_j_k_string); assert(next_z_j_k_object != NULL); Aig_Obj_t* R_i_j_increment = createEquivalence(present_z_j_k_object, createAnd(createNot(new_cannot_be_one_object_at_destination, pub_aig_manager), next_z_j_k_object, pub_aig_manager), pub_aig_manager); assert(R_i_j_increment != NULL); Z_objects.insert(R_i_j_increment); } } for(map::iterator hint_it = Refinement_Hint_Of_CannotBe_Zero_To_Eliminate_This_CEX.begin(); hint_it != Refinement_Hint_Of_CannotBe_Zero_To_Eliminate_This_CEX.end(); hint_it++) { int destination = hint_it->first; Aig_Obj_t* new_cannot_be_zero_object_at_destination = hint_it->second; map::iterator cannot_be_object_to_cannot_be_dag_map_it = cannot_be_object_to_cannot_be_dag_map.find(new_cannot_be_zero_object_at_destination); assert(cannot_be_object_to_cannot_be_dag_map_it != cannot_be_object_to_cannot_be_dag_map.end()); Aig_Obj_t* new_cannot_be_zero_dag_at_destination = cannot_be_object_to_cannot_be_dag_map_it->second; Aig_Obj_t* Cb_zero_equivalence = createEquivalence(new_cannot_be_zero_object_at_destination, new_cannot_be_zero_dag_at_destination, pub_aig_manager); assert(Cb_zero_equivalence != NULL); Cb_objects.insert(Cb_zero_equivalence); } assert(!Cb_objects.empty()); Cb_part = createAnd(Cb_objects, pub_aig_manager); assert(Cb_part != NULL); // connect to some output to avoid unwanted deletion Aig_Obj_t* Cb_part_CO = Aig_ObjCreateCo(pub_aig_manager, Cb_part ); assert(Cb_part_CO != NULL); assert(!Z_objects.empty()); Z_part = createAnd(Z_objects, pub_aig_manager); assert(Z_part != NULL); // connect to some output to avoid unwanted deletion Aig_Obj_t* Z_part_CO = Aig_ObjCreateCo(pub_aig_manager, Z_part ); assert(Z_part_CO != NULL); #ifdef DEBUG_SKOLEM string Cb_part_file_name = benchmark_name_without_extension; Cb_part_file_name += "_Cb_part"; string Z_part_file_name = benchmark_name_without_extension; Z_part_file_name += "_Z_part"; cout << "\nCb_part computed\n"; cout << "\nZ_part computed\n"; writeFormulaToFile(pub_aig_manager, Cb_part, Cb_part_file_name, ".v", cegar_iteration_number, 0); writeFormulaToFile(pub_aig_manager, Z_part, Z_part_file_name, ".v", cegar_iteration_number, 0); #endif delta_epsilon_i = createAnd(Cb_part, Z_part, pub_aig_manager); assert(delta_epsilon_i != NULL); // connect to some output to avoid unwanted deletion Aig_Obj_t* delta_epsilon_i_CO = Aig_ObjCreateCo(pub_aig_manager, delta_epsilon_i ); assert(delta_epsilon_i_CO != NULL); vector positive_assumptions_in_exactness_check; vector negative_assumptions_in_exactness_check; if(use_dontcare_optimization_in_mu_based_scheme_with_optimizations_in_cegar) { // Identify labels of D_1_k ,..., D_n_k and // assume that they are true (in positive_assumptions_in_exactness_check) // Also identify labels of D_1_l ,..., D_n_l, where l < k and // assume that they are false (in negative_assumptions_in_exactness_check) obtainAssumptionsInExactnessCheck_using_Generic_Skolem_Functions_And_Dontcare_Optimization(positive_assumptions_in_exactness_check, negative_assumptions_in_exactness_check); assert(positive_assumptions_in_exactness_check.size() != 0); assert(positive_assumptions_in_exactness_check.size() != 0); } else { // Identify labels of Z_1_k ,..., Z_n_k and // assume that they are true (in positive_assumptions_in_exactness_check) obtainAssumptionsInExactnessCheck_using_Generic_Skolem_Functions(positive_assumptions_in_exactness_check); assert(positive_assumptions_in_exactness_check.size() != 0); } // Use incremental solver call #ifdef DEBUG_CEGAR cout << endl << "Adding clauses of delta_epsilon_i to SAT-Solver, and calling SAT-Solver\n"; #endif #ifdef DETAILED_RECORD_KEEP unsigned long long int solver_ms; struct timeval solver_start_ms, solver_finish_ms; gettimeofday (&solver_start_ms, NULL); #endif // Give to SAT-Solver and get unsat / sat with model unsigned long long int cnf_time; int formula_size; unsigned long long int simplification_time; bool result_of_exactnesscheck = isExactnessCheckSatisfiable(pub_aig_manager, delta_epsilon_i, Model_of_ExactnessCheck, cnf_time, formula_size, simplification_time, positive_assumptions_in_exactness_check, negative_assumptions_in_exactness_check, pSat_for_exactness_check, IncrementalLabelTableForExactnessCheck, IncrementalLabelCountForExactnessCheck, Ci_name_to_Ci_label_mapForExactnessCheck, Ci_label_to_Ci_name_mapForExactnessCheck); #ifdef DETAILED_RECORD_KEEP gettimeofday (&solver_finish_ms, NULL); solver_ms = solver_finish_ms.tv_sec * 1000 + solver_finish_ms.tv_usec / 1000; solver_ms -= solver_start_ms.tv_sec * 1000 + solver_start_ms.tv_usec / 1000; cout << "\nsolver finished in " << solver_ms << " milliseconds\n"; total_time_in_smt_solver = total_time_in_smt_solver + solver_ms; total_time_in_exactness_checking_in_cegar = total_time_in_exactness_checking_in_cegar + solver_ms; number_of_exactness_checking_in_cegar++; #endif #ifdef RECORD_KEEP fprintf(record_fp, "\t%llu(%llu,%llu)(%d)", solver_ms, cnf_time, simplification_time, formula_size); fclose(record_fp); #endif #ifdef DEBUG_SKOLEM displayModelFromSATSolver(Model_of_ExactnessCheck); cout << endl << "result_of_exactnesscheck = " << result_of_exactnesscheck << endl; #endif removeTemporaryVariablesFromModel(Model_of_ExactnessCheck); #ifdef DEBUG_CEGAR cout << "\nModel after removing temporary variables\n"; displayModelFromSATSolver(Model_of_ExactnessCheck); cout << endl << "result_of_exactnesscheck = " << result_of_exactnesscheck << endl; #endif if(!result_of_exactnesscheck) // ExactnessCheck unsat i.e. skolem function at correction_index is exact { return true; } else // skolem function at correction_index is inexact { return false; } } // if(cegar_iteration_for_correction_index > 0) ends here } void AIGBasedSkolem::refineSkolemFunctions_using_Mu_Based_Scheme_With_Optimizations(int correction_index, map &Model_of_ExactnessCheck, map &Refinement_Hint_Of_CannotBe_One_To_Eliminate_This_CEX, map &Refinement_Hint_Of_CannotBe_Zero_To_Eliminate_This_CEX) { #ifdef RECORD_KEEP string record_file; record_file = logfile_prefix; record_file += "skolem_function_generation_details.txt"; FILE* record_fp = fopen(record_file.c_str(), "a+"); assert(record_fp != NULL); #endif // For easy of processing let's create map XValues; // XValues[i] gives value of x_i map YValues; // YValues[y_variable] gives value of y_variable map cannot_be_object_to_value_map; // maps object of eta_j or sigma_j to value map cannot_be_one_set_values; // cannot_be_one_set_values[i] gives value of cannot_be_one_set_values_i map cannot_be_zero_set_values; // cannot_be_zero_set_values[i] gives value of cannot_be_zero_set_values_i for(int var_to_elim_index = 1; var_to_elim_index <= number_of_vars_to_elim; var_to_elim_index++) { string var_to_elim = searchVarIndexToVarNameMap(var_index_to_var_name_map, var_to_elim_index); map::iterator Model_of_ExactnessCheck_it; Model_of_ExactnessCheck_it = Model_of_ExactnessCheck.find(var_to_elim); assert(Model_of_ExactnessCheck_it != Model_of_ExactnessCheck.end()); XValues.insert(make_pair(var_to_elim_index, Model_of_ExactnessCheck_it->second)); } for(map::iterator model_it = Model_of_ExactnessCheck.begin(); model_it != Model_of_ExactnessCheck.end(); model_it++) { string variable_name = model_it->first; int variable_value = model_it->second; map::iterator cannot_be_string_to_cannot_be_object_map_it = cannot_be_string_to_cannot_be_object_map.find(variable_name); if(cannot_be_string_to_cannot_be_object_map_it != cannot_be_string_to_cannot_be_object_map.end()) // variable_name is eta/sigma { Aig_Obj_t* cannot_be_object = cannot_be_string_to_cannot_be_object_map_it->second; cannot_be_object_to_value_map.insert(make_pair(cannot_be_object, variable_value)); } else if(variables_not_quantified.find(variable_name) != variables_not_quantified.end()) // variable_name is a Y variable { YValues.insert(make_pair(variable_name, variable_value)); } } for(map >::iterator cannot_be_one_set_it = cannot_be_one_set.begin(); cannot_be_one_set_it != cannot_be_one_set.end(); cannot_be_one_set_it++) { int var_to_elim_index = cannot_be_one_set_it->first; if(var_to_elim_index > correction_index) { break; } set cannot_be_one_set_of_variable = cannot_be_one_set_it->second; int value_of_cannot_be_one_set_of_variable = 0; for(set::iterator cannot_be_one_set_of_variable_it = cannot_be_one_set_of_variable.begin(); cannot_be_one_set_of_variable_it != cannot_be_one_set_of_variable.end(); cannot_be_one_set_of_variable_it++) { Aig_Obj_t* cannot_be_one_set_object_of_variable = *cannot_be_one_set_of_variable_it; map::iterator cannot_be_object_to_value_map_it = cannot_be_object_to_value_map.find(cannot_be_one_set_object_of_variable); if(cannot_be_object_to_value_map_it == cannot_be_object_to_value_map.end()) { cout << "\nProblem with var_to_elim_index = " << var_to_elim_index << "\t cannot_be_one_set_object_of_variable = " << cannot_be_one_set_object_of_variable << endl; assert(false); } int value_of_cannot_be_one_set_object_of_variable = cannot_be_object_to_value_map_it->second; if(value_of_cannot_be_one_set_object_of_variable == 1) { value_of_cannot_be_one_set_of_variable = value_of_cannot_be_one_set_object_of_variable; break; } } cannot_be_one_set_values.insert(make_pair(var_to_elim_index, value_of_cannot_be_one_set_of_variable)); } for(map >::iterator cannot_be_zero_set_it = cannot_be_zero_set.begin(); cannot_be_zero_set_it != cannot_be_zero_set.end(); cannot_be_zero_set_it++) { int var_to_elim_index = cannot_be_zero_set_it->first; if(var_to_elim_index > correction_index) { break; } set cannot_be_zero_set_of_variable = cannot_be_zero_set_it->second; int value_of_cannot_be_zero_set_of_variable = 0; for(set::iterator cannot_be_zero_set_of_variable_it = cannot_be_zero_set_of_variable.begin(); cannot_be_zero_set_of_variable_it != cannot_be_zero_set_of_variable.end(); cannot_be_zero_set_of_variable_it++) { Aig_Obj_t* cannot_be_zero_set_object_of_variable = *cannot_be_zero_set_of_variable_it; map::iterator cannot_be_object_to_value_map_it = cannot_be_object_to_value_map.find(cannot_be_zero_set_object_of_variable); assert(cannot_be_object_to_value_map_it != cannot_be_object_to_value_map.end()); int value_of_cannot_be_zero_set_object_of_variable = cannot_be_object_to_value_map_it->second; if(value_of_cannot_be_zero_set_object_of_variable == 1) { value_of_cannot_be_zero_set_of_variable = value_of_cannot_be_zero_set_object_of_variable; break; } } cannot_be_zero_set_values.insert(make_pair(var_to_elim_index, value_of_cannot_be_zero_set_of_variable)); } #ifdef DEBUG_CEGAR cout << endl; for(int var_to_elim_index = 1; var_to_elim_index <= number_of_vars_to_elim; var_to_elim_index++) { cout << endl << "XValues[" << var_to_elim_index << "] = " << XValues[var_to_elim_index]; } cout << endl; for(map::iterator YValues_it = YValues.begin(); YValues_it != YValues.end(); YValues_it++) { cout << endl << "YValues[" << YValues_it->first << "] = " << YValues_it->second; } cout << endl; for(int var_to_elim_index = 1; var_to_elim_index <= correction_index; var_to_elim_index++) { cout << endl << "cannot_be_one_set_values[" << var_to_elim_index << "] = " << cannot_be_one_set_values[var_to_elim_index]; } cout << endl; for(int var_to_elim_index = 1; var_to_elim_index <= correction_index; var_to_elim_index++) { cout << endl << "cannot_be_zero_set_values[" << var_to_elim_index << "] = " << cannot_be_zero_set_values[var_to_elim_index]; } cout << endl; #endif // find origin = largest l s.t. both cannot_be_one_set_values[l] and cannot_be_zero_set_values[l] are true // note that Skolem functions from correction_index+1 upto number_of_vars_to_elim are already corrected int origin = correction_index; for(int var_to_elim_index = correction_index-1; var_to_elim_index >= 1; var_to_elim_index--) { if(cannot_be_one_set_values[var_to_elim_index] == 1 && cannot_be_zero_set_values[var_to_elim_index] == 1) { origin = var_to_elim_index; break; } } assert(origin <= correction_index-1); #ifdef DEBUG_CEGAR cout << "\norigin = " << origin << endl; #endif int number_of_cannot_be_one_elements_in_initial_mu; int number_of_cannot_be_zero_elements_in_initial_mu; int size_of_initial_mu; Aig_Obj_t* mu; mu = obtain_initial_mu(origin, cannot_be_object_to_value_map, number_of_cannot_be_one_elements_in_initial_mu, number_of_cannot_be_zero_elements_in_initial_mu, size_of_initial_mu); assert(mu != NULL); #ifdef RECORD_KEEP fprintf(record_fp, "\t(x@%d,%d+%d,%d)", origin, number_of_cannot_be_one_elements_in_initial_mu, number_of_cannot_be_zero_elements_in_initial_mu, size_of_initial_mu); #endif #ifdef DEBUG_CEGAR string mu_file_name = benchmark_name_without_extension; mu_file_name += "_mu"; cout << "\nInitial mu computed\n"; writeFormulaToFile(pub_aig_manager, mu, mu_file_name, ".v", cegar_iteration_number, origin); #endif int destination = origin + 1; #ifdef DEBUG_CEGAR cout << "\ndestination = " << destination << endl; #endif while(destination <= correction_index) { if(!formulaFreeOfVariable(mu, destination)) // mu has x_destination in support { #ifdef DEBUG_SKOLEM cout << "\nmu has x_" << destination << " in its support\n"; #endif if(XValues[destination] == 1) // x_destination == 1 { #ifdef DEBUG_SKOLEM cout << "\nx_" << destination << " == 1\n"; #endif // assert (mu[x_destination --> 1]) if(cannot_be_zero_set_values[destination] == 1) // Cb0_destination is true { #ifdef DEBUG_SKOLEM cout << "\ncannot_be_zero_set[" << destination << "] == 1\n"; #endif // Let's obtain mu[x_destination --> 1] Aig_Obj_t* cofactor_one_of_mu; cofactor_one_of_mu = replaceVariableByConstant(mu, destination, 1); assert(cofactor_one_of_mu != NULL); int number_of_cannot_be_zero_elements_that_are_true; Aig_Obj_t* disjunction_of_true_cannot_be_zero_dags = obtain_disjunction_of_true_cannot_be_zero_dags(destination, cannot_be_object_to_value_map, cofactor_one_of_mu, number_of_cannot_be_zero_elements_that_are_true); assert(disjunction_of_true_cannot_be_zero_dags != NULL); int size_of_disjunction_of_true_cannot_be_zero_dags = computeSize(disjunction_of_true_cannot_be_zero_dags, pub_aig_manager); mu = createAnd(cofactor_one_of_mu, disjunction_of_true_cannot_be_zero_dags, pub_aig_manager); assert(mu != NULL); int size_of_changed_mu = computeSize(mu, pub_aig_manager); int size_of_new_element_added_to_cannot_be_one_set; if(refine_all_locations_in_use_mu_based_scheme_with_optimizations_in_cegar && !(apply_tsietin_encoding_on_benchmarks && destination <= number_of_tsietin_variables)) { Aig_Obj_t* new_cannot_be_one_dag_at_destination; if(use_interpolants_in_mu_based_scheme_with_optimizations_in_cegar) { new_cannot_be_one_dag_at_destination = optimizeCannotBeOneDagThroughInterpolation(cofactor_one_of_mu, destination); } else { new_cannot_be_one_dag_at_destination = cofactor_one_of_mu; } int size_of_extra_cannot_be_one_dag_at_destination = -1; int number_of_variables_dropped_in_generalization = -1; if(use_refinement_from_bottom_in_mu_based_scheme_with_optimizations_in_cegar) { if (use_incremental_solving_for_generalization_in_mu_based_scheme_with_optimizations_in_cegar || use_interpolants_in_mu_based_scheme_with_optimizations_in_cegar) { Aig_Obj_t* extra_cannot_be_one_dag_at_destination; extra_cannot_be_one_dag_at_destination = obtainExtraCannotBeOneDagAtDestination(XValues, YValues, destination, number_of_variables_dropped_in_generalization); assert(extra_cannot_be_one_dag_at_destination != NULL); // weakening the extra cannot be one dag if(use_interpolants_in_mu_based_scheme_with_optimizations_in_cegar) { extra_cannot_be_one_dag_at_destination = optimizeCannotBeOneDagThroughInterpolation(extra_cannot_be_one_dag_at_destination, destination); assert(extra_cannot_be_one_dag_at_destination != NULL); } #ifdef DEBUG_CEGAR string extra_cannot_be_one_dag_at_destination_file_name = benchmark_name_without_extension; extra_cannot_be_one_dag_at_destination_file_name += "_extra_cannot_be_one_dag_at_destination"; cout << "\nextra_cannot_be_one_dag_at_destination computed\n"; writeFormulaToFile(pub_aig_manager, extra_cannot_be_one_dag_at_destination, extra_cannot_be_one_dag_at_destination_file_name, ".v", cegar_iteration_number, destination); #endif size_of_extra_cannot_be_one_dag_at_destination = computeSize(extra_cannot_be_one_dag_at_destination, pub_aig_manager); new_cannot_be_one_dag_at_destination = createOr(new_cannot_be_one_dag_at_destination, extra_cannot_be_one_dag_at_destination, pub_aig_manager); assert(new_cannot_be_one_dag_at_destination != NULL); } } // connecting to some output to avoid unwanted deletion Aig_Obj_t* new_cannot_be_one_dag_at_destination_CO = Aig_ObjCreateCo(pub_aig_manager, new_cannot_be_one_dag_at_destination); assert(new_cannot_be_one_dag_at_destination_CO != NULL); // First allocate string and object to new_cannot_be_one_dag_at_destination string cannot_be_one_string_at_destination; Aig_Obj_t* cannot_be_one_object_at_destination; allocateStringAndObjectToCannotBeDag(1, new_cannot_be_one_dag_at_destination, cannot_be_one_string_at_destination, cannot_be_one_object_at_destination); #ifdef DEBUG_SKOLEM cout << "\nnew_cannot_be_one_dag_at_destination for x_" << destination << " is obtained\n"; string new_cannot_be_one_dag_at_destination_file_name = benchmark_name_without_extension; new_cannot_be_one_dag_at_destination_file_name += "_new_cannot_be_one_dag_at_destination"; writeFormulaToFile(pub_aig_manager, new_cannot_be_one_dag_at_destination, new_cannot_be_one_dag_at_destination_file_name, ".v", destination, cegar_iteration_number); show_cannot_be_string_to_cannot_be_object_map(); show_cannot_be_object_to_cannot_be_dag_map(); #endif // Insert new_cannot_be_one_object_at_destination into cannot_be_one_set at destination cannot_be_one_set[destination].insert(cannot_be_one_object_at_destination); // Insert new_cannot_be_one_object_at_destination into Refinement_Hint_Of_CannotBe_One_To_Eliminate_This_CEX Refinement_Hint_Of_CannotBe_One_To_Eliminate_This_CEX.insert(make_pair(destination, cannot_be_one_object_at_destination)); #ifdef DEBUG_CEGAR cout << "\ncannot_be_one_set for x_" << destination << " is modified\n"; #endif // Conjoin ~new_cannot_be_one_object_at_destination to skolem_function at destination Aig_Obj_t* current_skolem_function_at_destination; current_skolem_function_at_destination = searchOneDimensionalMatrix(SkolemFunctions, number_of_vars_to_elim, destination); assert(current_skolem_function_at_destination != NULL); Aig_Obj_t* new_skolem_function_at_destination; new_skolem_function_at_destination = createSkolemFunction_In_Mu_Based_Scheme_With_Optimizations(destination); // new_skolem_function_at_destination can be created from // cannot_be_one_set[destination] and initial_cannot_be_zero_dags[destination] assert(new_skolem_function_at_destination != NULL); int size_of_new_skolem_function_at_destination_unoptimized = computeSize(new_skolem_function_at_destination, pub_aig_manager); if(use_dontcare_optimization_in_mu_based_scheme_with_optimizations_in_cegar) // optimize the skolem_function { Aig_Obj_t* dontcare_part = createDontCarePart_In_Mu_Based_Scheme_With_Optimizations(destination); assert(dontcare_part != NULL); #ifdef DEBUG_SKOLEM writeFormulaToFile(pub_aig_manager, dontcare_part, "dontcare_part", ".v", destination, cegar_iteration_number); writeFormulaToFile(pub_aig_manager, new_skolem_function_at_destination, "unoptimized_skolem_function", ".v", destination, cegar_iteration_number); #endif new_skolem_function_at_destination = performDontCareOptimization(pub_aig_manager, new_skolem_function_at_destination, dontcare_part); assert(new_skolem_function_at_destination != NULL); } if(new_skolem_function_at_destination != current_skolem_function_at_destination) // skolem function is changed { // connecting to some output to avoid unwanted deletion Aig_Obj_t* new_skolem_function_at_destination_CO = Aig_ObjCreateCo( pub_aig_manager, new_skolem_function_at_destination); assert(new_skolem_function_at_destination_CO != NULL); // insert the new skolem function insertIntoOneDimensionalMatrix(SkolemFunctions, number_of_vars_to_elim, destination, new_skolem_function_at_destination, true); #ifdef DEBUG_CEGAR cout << "\nSkolem function for x_" << destination << " is modified\n"; string skolem_function_file_name = benchmark_name_without_extension; skolem_function_file_name += "_skolem_function"; writeFormulaToFile(pub_aig_manager, new_skolem_function_at_destination, skolem_function_file_name, ".v", destination, cegar_iteration_number); #endif } size_of_new_element_added_to_cannot_be_one_set = computeSize(new_cannot_be_one_dag_at_destination, pub_aig_manager); int size_of_new_skolem_function_at_destination = computeSize(new_skolem_function_at_destination, pub_aig_manager); #ifdef RECORD_KEEP if(size_of_extra_cannot_be_one_dag_at_destination == -1) { fprintf(record_fp, "\t(x@%d=1,%d,%d,%d,%d,%d,%d,-,-)", destination, size_of_new_element_added_to_cannot_be_one_set, number_of_cannot_be_zero_elements_that_are_true, size_of_disjunction_of_true_cannot_be_zero_dags, size_of_changed_mu, size_of_new_skolem_function_at_destination_unoptimized, size_of_new_skolem_function_at_destination); } else { fprintf(record_fp, "\t(x@%d=1,%d,%d,%d,%d,%d,%d,%d,%d)", destination, size_of_new_element_added_to_cannot_be_one_set, number_of_cannot_be_zero_elements_that_are_true, size_of_disjunction_of_true_cannot_be_zero_dags, size_of_changed_mu, size_of_new_skolem_function_at_destination_unoptimized, size_of_new_skolem_function_at_destination, size_of_extra_cannot_be_one_dag_at_destination, number_of_variables_dropped_in_generalization); } #endif } else { size_of_new_element_added_to_cannot_be_one_set = -1; //nothing is added to Cb1_k #ifdef RECORD_KEEP fprintf(record_fp, "\t(x@%d=1,-,%d,%d,%d,-,-,-,-)", destination, number_of_cannot_be_zero_elements_that_are_true, size_of_disjunction_of_true_cannot_be_zero_dags, size_of_changed_mu); #endif } #ifdef DEBUG_CEGAR mu_file_name = benchmark_name_without_extension; mu_file_name += "_mu"; cout << "\nmu updated\n"; writeFormulaToFile(pub_aig_manager, mu, mu_file_name, ".v", cegar_iteration_number, destination); #endif } else if(!refine_all_locations_in_use_mu_based_scheme_with_optimizations_in_cegar && evaluateMu(mu, XValues, YValues, destination, 0)) //evaluate mu with XValues' where // XValues'[l] = 0 for l = destination and XValues'[l] = XValues[l] for l \neq destination { #ifdef DEBUG_SKOLEM cout << "\ncannot_be_zero_set[" << destination << "] == 0 && mu[x_" << destination << "-->0] == 1\n"; #endif int number_of_cannot_be_zero_elements_that_are_true = -1; int size_of_disjunction_of_true_cannot_be_zero_dags = -1; // Let's obtain mu[x_destination --> 1] Aig_Obj_t* cofactor_one_of_mu; cofactor_one_of_mu = replaceVariableByConstant(mu, destination, 1); assert(cofactor_one_of_mu != NULL); // Let's obtain mu[x_destination --> 0] Aig_Obj_t* cofactor_zero_of_mu; cofactor_zero_of_mu = replaceVariableByConstant(mu, destination, 0); assert(cofactor_zero_of_mu != NULL); mu = createAnd(cofactor_one_of_mu, cofactor_zero_of_mu, pub_aig_manager); assert(mu != NULL); int size_of_changed_mu = computeSize(mu, pub_aig_manager); int size_of_new_element_added_to_cannot_be_one_set = -1; //nothing is added to Cb1_k #ifdef RECORD_KEEP fprintf(record_fp, "\t(x@%d=1,-,-,-,%d,-,-,-,-)", destination, size_of_changed_mu); #endif #ifdef DEBUG_CEGAR mu_file_name = benchmark_name_without_extension; mu_file_name += "_mu"; cout << "\nmu updated\n"; writeFormulaToFile(pub_aig_manager, mu, mu_file_name, ".v", cegar_iteration_number, destination); #endif } else // flipping x_destination makes mu zero { #ifdef DEBUG_SKOLEM cout << "\ncannot_be_zero_set[" << destination << "] == 0 && mu[x_" << destination << "-->0] == 0\n"; #endif int number_of_cannot_be_zero_elements_that_are_true = -1; int size_of_disjunction_of_true_cannot_be_zero_dags = -1; int size_of_changed_mu = -1; // Let's obtain mu[x_destination --> 1] Aig_Obj_t* cofactor_one_of_mu; cofactor_one_of_mu = replaceVariableByConstant(mu, destination, 1); assert(cofactor_one_of_mu != NULL); Aig_Obj_t* new_cannot_be_one_dag_at_destination; if(use_interpolants_in_mu_based_scheme_with_optimizations_in_cegar) { new_cannot_be_one_dag_at_destination = optimizeCannotBeOneDagThroughInterpolation(cofactor_one_of_mu, destination); } else { new_cannot_be_one_dag_at_destination = cofactor_one_of_mu; } int size_of_extra_cannot_be_one_dag_at_destination = -1; int number_of_variables_dropped_in_generalization = -1; if(use_refinement_from_bottom_in_mu_based_scheme_with_optimizations_in_cegar) { if(use_incremental_solving_for_generalization_in_mu_based_scheme_with_optimizations_in_cegar || use_interpolants_in_mu_based_scheme_with_optimizations_in_cegar) { Aig_Obj_t* extra_cannot_be_one_dag_at_destination; extra_cannot_be_one_dag_at_destination = obtainExtraCannotBeOneDagAtDestination(XValues, YValues, destination, number_of_variables_dropped_in_generalization); assert(extra_cannot_be_one_dag_at_destination != NULL); // weakening the extra cannot be one dag if(use_interpolants_in_mu_based_scheme_with_optimizations_in_cegar) { extra_cannot_be_one_dag_at_destination = optimizeCannotBeOneDagThroughInterpolation(extra_cannot_be_one_dag_at_destination, destination); assert(extra_cannot_be_one_dag_at_destination != NULL); } #ifdef DEBUG_CEGAR string extra_cannot_be_one_dag_at_destination_file_name = benchmark_name_without_extension; extra_cannot_be_one_dag_at_destination_file_name += "_extra_cannot_be_one_dag_at_destination"; cout << "\nextra_cannot_be_one_dag_at_destination computed\n"; writeFormulaToFile(pub_aig_manager, extra_cannot_be_one_dag_at_destination, extra_cannot_be_one_dag_at_destination_file_name, ".v", cegar_iteration_number, destination); #endif size_of_extra_cannot_be_one_dag_at_destination = computeSize(extra_cannot_be_one_dag_at_destination, pub_aig_manager); new_cannot_be_one_dag_at_destination = createOr(new_cannot_be_one_dag_at_destination, extra_cannot_be_one_dag_at_destination, pub_aig_manager); assert(new_cannot_be_one_dag_at_destination != NULL); } } // connecting to some output to avoid unwanted deletion Aig_Obj_t* new_cannot_be_one_dag_at_destination_CO = Aig_ObjCreateCo(pub_aig_manager, new_cannot_be_one_dag_at_destination); assert(new_cannot_be_one_dag_at_destination_CO != NULL); // First allocate string and object to new_cannot_be_one_dag_at_destination string cannot_be_one_string_at_destination; Aig_Obj_t* cannot_be_one_object_at_destination; allocateStringAndObjectToCannotBeDag(1, new_cannot_be_one_dag_at_destination, cannot_be_one_string_at_destination, cannot_be_one_object_at_destination); #ifdef DEBUG_SKOLEM cout << "\nnew_cannot_be_one_dag_at_destination for x_" << destination << " is obtained\n"; string new_cannot_be_one_dag_at_destination_file_name = benchmark_name_without_extension; new_cannot_be_one_dag_at_destination_file_name += "_new_cannot_be_one_dag_at_destination"; writeFormulaToFile(pub_aig_manager, new_cannot_be_one_dag_at_destination, new_cannot_be_one_dag_at_destination_file_name, ".v", destination, cegar_iteration_number); show_cannot_be_string_to_cannot_be_object_map(); show_cannot_be_object_to_cannot_be_dag_map(); #endif // Insert new_cannot_be_one_object_at_destination into cannot_be_one_set at destination cannot_be_one_set[destination].insert(cannot_be_one_object_at_destination); // Insert new_cannot_be_one_object_at_destination into Refinement_Hint_Of_CannotBe_One_To_Eliminate_This_CEX Refinement_Hint_Of_CannotBe_One_To_Eliminate_This_CEX.insert(make_pair(destination, cannot_be_one_object_at_destination)); #ifdef DEBUG_CEGAR cout << "\ncannot_be_one_set for x_" << destination << " is modified\n"; #endif // Conjoin ~new_cannot_be_one_object_at_destination to skolem_function at destination Aig_Obj_t* current_skolem_function_at_destination; current_skolem_function_at_destination = searchOneDimensionalMatrix(SkolemFunctions, number_of_vars_to_elim, destination); assert(current_skolem_function_at_destination != NULL); Aig_Obj_t* new_skolem_function_at_destination; new_skolem_function_at_destination = createSkolemFunction_In_Mu_Based_Scheme_With_Optimizations(destination); // new_skolem_function_at_destination can be created from // cannot_be_one_set[destination] and initial_cannot_be_zero_dags[destination] assert(new_skolem_function_at_destination != NULL); int size_of_new_skolem_function_at_destination_unoptimized = computeSize(new_skolem_function_at_destination, pub_aig_manager); if(use_dontcare_optimization_in_mu_based_scheme_with_optimizations_in_cegar) // optimize the skolem_function { Aig_Obj_t* dontcare_part = createDontCarePart_In_Mu_Based_Scheme_With_Optimizations(destination); assert(dontcare_part != NULL); #ifdef DEBUG_SKOLEM writeFormulaToFile(pub_aig_manager, dontcare_part, "dontcare_part", ".v", destination, cegar_iteration_number); writeFormulaToFile(pub_aig_manager, new_skolem_function_at_destination, "unoptimized_skolem_function", ".v", destination, cegar_iteration_number); #endif new_skolem_function_at_destination = performDontCareOptimization(pub_aig_manager, new_skolem_function_at_destination, dontcare_part); assert(new_skolem_function_at_destination != NULL); } if(new_skolem_function_at_destination != current_skolem_function_at_destination) // skolem function is changed { // connecting to some output to avoid unwanted deletion Aig_Obj_t* new_skolem_function_at_destination_CO = Aig_ObjCreateCo( pub_aig_manager, new_skolem_function_at_destination); assert(new_skolem_function_at_destination_CO != NULL); // insert the new skolem function insertIntoOneDimensionalMatrix(SkolemFunctions, number_of_vars_to_elim, destination, new_skolem_function_at_destination, true); #ifdef DEBUG_CEGAR cout << "\nSkolem function for x_" << destination << " is modified\n"; string skolem_function_file_name = benchmark_name_without_extension; skolem_function_file_name += "_skolem_function"; writeFormulaToFile(pub_aig_manager, new_skolem_function_at_destination, skolem_function_file_name, ".v", destination, cegar_iteration_number); #endif } int size_of_new_element_added_to_cannot_be_one_set = computeSize(new_cannot_be_one_dag_at_destination, pub_aig_manager); int size_of_new_skolem_function_at_destination = computeSize(new_skolem_function_at_destination, pub_aig_manager); #ifdef RECORD_KEEP if(size_of_extra_cannot_be_one_dag_at_destination == -1) { fprintf(record_fp, "\t(x@%d=1,%d,-,-,-,%d,%d,-,-)", destination, size_of_new_element_added_to_cannot_be_one_set, size_of_new_skolem_function_at_destination_unoptimized, size_of_new_skolem_function_at_destination); } else { fprintf(record_fp, "\t(x@%d=1,%d,-,-,-,%d,%d,%d,%d)", destination, size_of_new_element_added_to_cannot_be_one_set, size_of_new_skolem_function_at_destination_unoptimized, size_of_new_skolem_function_at_destination, size_of_extra_cannot_be_one_dag_at_destination, number_of_variables_dropped_in_generalization); } #endif break; } // flipping x_destination makes mu zero ends here }// if(x_destination == 1) ends here else // if(x_destination == 0) { #ifdef DEBUG_SKOLEM cout << "\nx_" << destination << " == 0\n"; #endif // assert (mu[x_destination --> 0]) if(!refine_all_locations_in_use_mu_based_scheme_with_optimizations_in_cegar && evaluateMu(mu, XValues, YValues, destination, 1)) //evaluate mu with XValues' where // XValues'[l] = 1 for l = destination and XValues'[l] = XValues[l] for l \neq destination { #ifdef DEBUG_SKOLEM cout << "\nmu[x_" << destination << "-->1] == 1\n"; #endif int number_of_cannot_be_one_elements_that_are_true = -1; int size_of_disjunction_of_true_cannot_be_one_dags = -1; // Let's obtain mu[x_destination --> 1] Aig_Obj_t* cofactor_one_of_mu; cofactor_one_of_mu = replaceVariableByConstant(mu, destination, 1); assert(cofactor_one_of_mu != NULL); // Let's obtain mu[x_destination --> 0] Aig_Obj_t* cofactor_zero_of_mu; cofactor_zero_of_mu = replaceVariableByConstant(mu, destination, 0); assert(cofactor_zero_of_mu != NULL); mu = createAnd(cofactor_one_of_mu, cofactor_zero_of_mu, pub_aig_manager); assert(mu != NULL); int size_of_changed_mu = computeSize(mu, pub_aig_manager); int size_of_new_element_added_to_cannot_be_zero_set = -1; //nothing is added to Cb0_k #ifdef RECORD_KEEP fprintf(record_fp, "\t(x@%d=0,-,-,-,%d,-,-,-,-)", destination, size_of_changed_mu); #endif #ifdef DEBUG_CEGAR mu_file_name = benchmark_name_without_extension; mu_file_name += "_mu"; cout << "\nmu updated\n"; writeFormulaToFile(pub_aig_manager, mu, mu_file_name, ".v", cegar_iteration_number, destination); #endif } else { assert(cannot_be_one_set_values[destination] == 1); // Cb1_destination is true #ifdef DEBUG_SKOLEM cout << "\ncannot_be_one_set[" << destination << "] == 1\n"; #endif // Let's obtain mu[x_destination --> 0] Aig_Obj_t* cofactor_zero_of_mu; cofactor_zero_of_mu = replaceVariableByConstant(mu, destination, 0); assert(cofactor_zero_of_mu != NULL); int number_of_cannot_be_one_elements_that_are_true; Aig_Obj_t* disjunction_of_true_cannot_be_one_dags = obtain_disjunction_of_true_cannot_be_one_dags(destination, cannot_be_object_to_value_map, cofactor_zero_of_mu, number_of_cannot_be_one_elements_that_are_true); assert(disjunction_of_true_cannot_be_one_dags != NULL); int size_of_disjunction_of_true_cannot_be_one_dags = computeSize(disjunction_of_true_cannot_be_one_dags, pub_aig_manager); mu = createAnd(cofactor_zero_of_mu, disjunction_of_true_cannot_be_one_dags, pub_aig_manager); assert(mu != NULL); int size_of_changed_mu = computeSize(mu, pub_aig_manager); int size_of_new_element_added_to_cannot_be_zero_set; if(refine_all_locations_in_use_mu_based_scheme_with_optimizations_in_cegar && accumulate_formulae_in_cbzero_in_cegar && !(apply_tsietin_encoding_on_benchmarks && destination <= number_of_tsietin_variables) ) { Aig_Obj_t* new_cannot_be_zero_dag_at_destination; new_cannot_be_zero_dag_at_destination = cofactor_zero_of_mu; assert(new_cannot_be_zero_dag_at_destination != NULL); // connecting to some output to avoid unwanted deletion Aig_Obj_t* new_cannot_be_zero_dag_at_destination_CO = Aig_ObjCreateCo(pub_aig_manager, new_cannot_be_zero_dag_at_destination); assert(new_cannot_be_zero_dag_at_destination_CO != NULL); // First allocate string and object to new_cannot_be_zero_dag_at_destination string cannot_be_zero_string_at_destination; Aig_Obj_t* cannot_be_zero_object_at_destination; allocateStringAndObjectToCannotBeDag(1, new_cannot_be_zero_dag_at_destination, cannot_be_zero_string_at_destination, cannot_be_zero_object_at_destination); #ifdef DEBUG_SKOLEM cout << "\nnew_cannot_be_zero_dag_at_destination for x_" << destination << " is obtained\n"; string new_cannot_be_zero_dag_at_destination_file_name = benchmark_name_without_extension; new_cannot_be_zero_dag_at_destination_file_name += "_new_cannot_be_zero_dag_at_destination"; writeFormulaToFile(pub_aig_manager, new_cannot_be_zero_dag_at_destination, new_cannot_be_zero_dag_at_destination_file_name, ".v", destination, cegar_iteration_number); show_cannot_be_string_to_cannot_be_object_map(); show_cannot_be_object_to_cannot_be_dag_map(); #endif // Insert new_cannot_be_zero_object_at_destination into cannot_be_zero_set at destination cannot_be_zero_set[destination].insert(cannot_be_zero_object_at_destination); // Insert new_cannot_be_zero_object_at_destination into Refinement_Hint_Of_CannotBe_Zero_To_Eliminate_This_CEX Refinement_Hint_Of_CannotBe_Zero_To_Eliminate_This_CEX.insert(make_pair(destination, cannot_be_zero_object_at_destination)); #ifdef DEBUG_CEGAR cout << "\ncannot_be_zero_set for x_" << destination << " is modified\n"; #endif size_of_new_element_added_to_cannot_be_zero_set = computeSize(new_cannot_be_zero_dag_at_destination, pub_aig_manager); #ifdef RECORD_KEEP fprintf(record_fp, "\t(x@%d=0,%d,%d,%d,%d,-,-,-,-)", destination, size_of_new_element_added_to_cannot_be_zero_set, number_of_cannot_be_one_elements_that_are_true, size_of_disjunction_of_true_cannot_be_one_dags, size_of_changed_mu); #endif } else { size_of_new_element_added_to_cannot_be_zero_set = -1; //nothing is added to Cb0_k #ifdef RECORD_KEEP fprintf(record_fp, "\t(x@%d=0,-,%d,%d,%d,-,-,-,-)", destination, number_of_cannot_be_one_elements_that_are_true, size_of_disjunction_of_true_cannot_be_one_dags, size_of_changed_mu); #endif } #ifdef DEBUG_CEGAR mu_file_name = benchmark_name_without_extension; mu_file_name += "_mu"; cout << "\nmu updated\n"; writeFormulaToFile(pub_aig_manager, mu, mu_file_name, ".v", cegar_iteration_number, destination); #endif }// else of mu with XValues' is 1 }// if(x_destination == 0) ends here }// mu has x_destination in support ends here destination = destination + 1; }// while(destination <= number_of_vars_to_elim) ends here assert(destination <= correction_index); #ifdef RECORD_KEEP fclose(record_fp); #endif } bool AIGBasedSkolem::evaluateMu(Aig_Obj_t* mu, map &XValues, map &YValues, int destination, int value_at_destination) { #ifdef DETAILED_RECORD_KEEP unsigned long long int step_ms; struct timeval step_start_ms, step_finish_ms; gettimeofday (&step_start_ms, NULL); #endif assert(mu != NULL); map variable_to_value_map; for(map::iterator yvalues_it = YValues.begin(); yvalues_it != YValues.end(); yvalues_it++) { bool bool_value; if(yvalues_it->second == 1) { bool_value = true; } else { assert(yvalues_it->second == 0); bool_value = false; } variable_to_value_map.insert(make_pair(yvalues_it->first, bool_value)); #ifdef DEBUG_SKOLEM cout << endl << yvalues_it->first << " --> " << bool_value << " inserted into variable_to_value_map\n"; #endif } for(int var_to_elim_index = number_of_vars_to_elim; var_to_elim_index > destination; var_to_elim_index--) { string var_to_elim = searchVarIndexToVarNameMap(var_index_to_var_name_map, var_to_elim_index); int value = XValues[var_to_elim_index]; bool bool_value; if(value == 1) { bool_value = true; } else { assert(value == 0); bool_value = false; } variable_to_value_map.insert(make_pair(var_to_elim, bool_value)); #ifdef DEBUG_SKOLEM cout << endl << var_to_elim << " --> " << bool_value << " inserted into variable_to_value_map\n"; #endif } string var_to_elim_at_destination = searchVarIndexToVarNameMap(var_index_to_var_name_map, destination); bool bool_value_at_destination; if(value_at_destination == 1) { bool_value_at_destination = true; } else { assert(value_at_destination == 0); bool_value_at_destination = false; } variable_to_value_map.insert(make_pair(var_to_elim_at_destination, bool_value_at_destination)); #ifdef DEBUG_SKOLEM cout << endl << var_to_elim_at_destination << " --> " << bool_value_at_destination << " inserted into variable_to_value_map\n"; #endif bool result_value = evaluateFormulaOfCi(mu, variable_to_value_map); #ifdef DETAILED_RECORD_KEEP gettimeofday (&step_finish_ms, NULL); step_ms = step_finish_ms.tv_sec * 1000 + step_finish_ms.tv_usec / 1000; step_ms -= step_start_ms.tv_sec * 1000 + step_start_ms.tv_usec / 1000; total_time_in_mu_evaluation_in_cegar = total_time_in_mu_evaluation_in_cegar + step_ms; #endif #ifdef DEBUG_SKOLEM cout << endl << "result_value = " << result_value << endl; cout << "Time to evaluate mu with size " << computeSize(mu, pub_aig_manager) << " is: " << step_ms << "milli seconds\n"; #endif return result_value; } Aig_Obj_t* AIGBasedSkolem::createSkolemFunction_In_Mu_Based_Scheme_With_Optimizations(int destination) { map >::iterator cannot_be_one_set_it = cannot_be_one_set.find(destination); assert(cannot_be_one_set_it != cannot_be_one_set.end()); set cannot_be_one_set_objects = cannot_be_one_set_it->second; // let's find the corresponding dags Aig_Obj_t* skolem_function_part1; set skolem_function_part1_components; for(set::iterator cannot_be_one_set_objects_it = cannot_be_one_set_objects.begin(); cannot_be_one_set_objects_it != cannot_be_one_set_objects.end(); cannot_be_one_set_objects_it++) { Aig_Obj_t* cannot_be_object = *cannot_be_one_set_objects_it; assert(cannot_be_object != NULL); map::iterator cannot_be_object_to_cannot_be_dag_map_it = cannot_be_object_to_cannot_be_dag_map.find(cannot_be_object); assert(cannot_be_object_to_cannot_be_dag_map_it != cannot_be_object_to_cannot_be_dag_map.end()); Aig_Obj_t* cannot_be_dag = cannot_be_object_to_cannot_be_dag_map_it->second; assert(cannot_be_dag != NULL); skolem_function_part1_components.insert(cannot_be_dag); } if(skolem_function_part1_components.empty()) // no condition under which it can't be 1 // i.e. it can be 1 always { skolem_function_part1 = createTrue(pub_aig_manager); } else { skolem_function_part1 = createOr(skolem_function_part1_components, pub_aig_manager); skolem_function_part1 = createNot(skolem_function_part1, pub_aig_manager); } assert(skolem_function_part1 != NULL); map::iterator initial_cannot_be_zero_dags_it = initial_cannot_be_zero_dags.find(destination); assert(initial_cannot_be_zero_dags_it != initial_cannot_be_zero_dags.end()); Aig_Obj_t* skolem_function_part2 = initial_cannot_be_zero_dags_it->second; Aig_Obj_t* skolem_function; skolem_function = createOr(skolem_function_part2, skolem_function_part1, pub_aig_manager); assert(skolem_function != NULL); return skolem_function; } Aig_Obj_t* AIGBasedSkolem::optimizeCannotBeOneDagThroughInterpolation(Aig_Obj_t* original_cannot_be_one_dag, int destination) { #ifdef DEBUG_SKOLEM cout << "\noptimizing cannot-be-1 dag through interpolation\n"; #endif Aig_Obj_t* optimized_cannot_be_one_dag; unsigned long long int interpolate_ms; struct timeval interpolate_start_ms, interpolate_finish_ms; gettimeofday (&interpolate_start_ms, NULL); Aig_Obj_t* interpolant;// interpolate(e_k, \phi) interpolant = Interpolate(pub_aig_manager, original_cannot_be_one_dag, conjunction_of_factors); if(interpolant != NULL) { #ifdef DEBUG_SKOLEM cout << "\ne_k and phi is unsat; interpolant(e_k, phi) returned\n"; #endif optimized_cannot_be_one_dag = interpolant; } else // e_k \wedge \phi is not unsat { #ifdef DEBUG_SKOLEM cout << "\ne_k and phi is sat\n"; #endif // obtain AIG for x_destination string var_to_elim_at_destination = searchVarIndexToVarNameMap(var_index_to_var_name_map, destination); map::iterator Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it = Ci_to_eliminate_name_to_Ci_to_eliminate_object_map.find(var_to_elim_at_destination); assert(Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it != Ci_to_eliminate_name_to_Ci_to_eliminate_object_map.end()); Aig_Obj_t* var_to_elim_at_destination_obj = Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it->second; assert(var_to_elim_at_destination_obj != NULL); Aig_Obj_t* conjoined_dag = createAnd(conjunction_of_factors, var_to_elim_at_destination_obj, pub_aig_manager); assert(conjoined_dag != NULL); // \phi \wedge x_k is created // interpolate(e_k, \phi \wedge x_k) interpolant = Interpolate(pub_aig_manager, original_cannot_be_one_dag, conjoined_dag); assert(interpolant != NULL); #ifdef DEBUG_SKOLEM cout << "\ninterpolant(e_k, phi and x_k) returned\n"; #endif optimized_cannot_be_one_dag = interpolant; } gettimeofday (&interpolate_finish_ms, NULL); interpolate_ms = interpolate_finish_ms.tv_sec * 1000 + interpolate_finish_ms.tv_usec / 1000; interpolate_ms -= interpolate_start_ms.tv_sec * 1000 + interpolate_start_ms.tv_usec / 1000; cout << "\ncomputeSkolemFunctionAsInterpolant finished in " << interpolate_ms << " milliseconds\n"; total_time_in_interpolant_computation_in_cegar = total_time_in_interpolant_computation_in_cegar + interpolate_ms; return optimized_cannot_be_one_dag; } Aig_Obj_t* AIGBasedSkolem::createDontCarePart_In_Mu_Based_Scheme_With_Optimizations(int destination) { map >::iterator cannot_be_one_set_it = cannot_be_one_set.find(destination); assert(cannot_be_one_set_it != cannot_be_one_set.end()); set cannot_be_one_set_objects = cannot_be_one_set_it->second; // let's find the corresponding dags Aig_Obj_t* dont_care_part1; set dont_care_part1_components; for(set::iterator cannot_be_one_set_objects_it = cannot_be_one_set_objects.begin(); cannot_be_one_set_objects_it != cannot_be_one_set_objects.end(); cannot_be_one_set_objects_it++) { Aig_Obj_t* cannot_be_object = *cannot_be_one_set_objects_it; assert(cannot_be_object != NULL); map::iterator cannot_be_object_to_cannot_be_dag_map_it = cannot_be_object_to_cannot_be_dag_map.find(cannot_be_object); assert(cannot_be_object_to_cannot_be_dag_map_it != cannot_be_object_to_cannot_be_dag_map.end()); Aig_Obj_t* cannot_be_dag = cannot_be_object_to_cannot_be_dag_map_it->second; assert(cannot_be_dag != NULL); dont_care_part1_components.insert(cannot_be_dag); } if(dont_care_part1_components.empty()) { dont_care_part1 = createFalse(pub_aig_manager); } else { dont_care_part1 = createOr(dont_care_part1_components, pub_aig_manager); } assert(dont_care_part1 != NULL); map >::iterator cannot_be_zero_set_it = cannot_be_zero_set.find(destination); assert(cannot_be_zero_set_it != cannot_be_zero_set.end()); set cannot_be_zero_set_objects = cannot_be_zero_set_it->second; // let's find the corresponding dags Aig_Obj_t* dont_care_part2; set dont_care_part2_components; for(set::iterator cannot_be_zero_set_objects_it = cannot_be_zero_set_objects.begin(); cannot_be_zero_set_objects_it != cannot_be_zero_set_objects.end(); cannot_be_zero_set_objects_it++) { Aig_Obj_t* cannot_be_object = *cannot_be_zero_set_objects_it; assert(cannot_be_object != NULL); map::iterator cannot_be_object_to_cannot_be_dag_map_it = cannot_be_object_to_cannot_be_dag_map.find(cannot_be_object); assert(cannot_be_object_to_cannot_be_dag_map_it != cannot_be_object_to_cannot_be_dag_map.end()); Aig_Obj_t* cannot_be_dag = cannot_be_object_to_cannot_be_dag_map_it->second; assert(cannot_be_dag != NULL); dont_care_part2_components.insert(cannot_be_dag); } if(dont_care_part2_components.empty()) { dont_care_part2 = createFalse(pub_aig_manager); } else { dont_care_part2 = createOr(dont_care_part2_components, pub_aig_manager); } assert(dont_care_part2 != NULL); Aig_Obj_t* dont_care_part; dont_care_part = createAnd(dont_care_part1, dont_care_part2, pub_aig_manager); assert(dont_care_part != NULL); return dont_care_part; } string AIGBasedSkolem::obtainDVariableString(int var_to_elim_index, int d_i_count) { // Return the string D_{var_to_elim_index}_{d_i_count} string D_string = "D_"; char var_char[100]; sprintf(var_char, "%d", var_to_elim_index); string var_string(var_char); D_string += var_string; D_string += "_"; char count_char[100]; sprintf(count_char, "%d", d_i_count); string count_string(count_char); D_string += count_string; return D_string; } string AIGBasedSkolem::obtainSVariableString(int var_to_elim_index, int s_i_count) { // Return the string S_{var_to_elim_index}_{s_i_count} string S_string = "S_"; char var_char[100]; sprintf(var_char, "%d", var_to_elim_index); string var_string(var_char); S_string += var_string; S_string += "_"; char count_char[100]; sprintf(count_char, "%d", s_i_count); string count_string(count_char); S_string += count_string; return S_string; } void AIGBasedSkolem::obtainAssumptionsInExactnessCheck_using_Generic_Skolem_Functions_And_Dontcare_Optimization(vector &positive_assumptions_in_exactness_check, vector &negative_assumptions_in_exactness_check) { // positive_assumptions_in_exactness_check includes // D_i_j for each i = variable_to_eliminate and j = D_variable_counter[i] // negative_assumptions_in_exactness_check includes // D_i_j for each i = variable_to_eliminate and j < D_variable_counter[i] for(int var_to_elim_index = 1; var_to_elim_index <= number_of_vars_to_elim; var_to_elim_index++) { map::iterator D_variable_counter_it = D_variable_counter.find(var_to_elim_index); assert(D_variable_counter_it != D_variable_counter.end()); int d_i_count = D_variable_counter_it->second; string d_i_string = obtainDVariableString(var_to_elim_index, d_i_count); // obtain the string D_{var_to_elim_index}_{d_i_count} Aig_Obj_t* d_i_object = obtainExistingObjectOfTemporaryVariableForIncrementalSolving(d_i_string); assert(d_i_object != NULL); positive_assumptions_in_exactness_check.push_back(d_i_object); #ifdef DEBUG_SKOLEM cout << "\nvar_to_elim_index = " << var_to_elim_index << "\td_i_count = " << d_i_count << endl; #endif for(int old_count = 0; old_count < d_i_count; old_count++) { string old_string = obtainDVariableString(var_to_elim_index, old_count); Aig_Obj_t* old_object = obtainExistingObjectOfTemporaryVariableForIncrementalSolving(old_string); assert(old_object != NULL); negative_assumptions_in_exactness_check.push_back(old_object); } } } Aig_Obj_t* AIGBasedSkolem::obtainExtraCannotBeOneDagAtDestination(map &XValues, map &YValues, int destination, int &number_of_variables_dropped_in_generalization) { set variables_avoided; unsigned long long int generalize_ms; struct timeval generalize_start_ms, generalize_finish_ms; gettimeofday (&generalize_start_ms, NULL); if(use_incremental_solving_for_generalization_in_mu_based_scheme_with_optimizations_in_cegar) { obtainGeneralizedModelByIncrementalSolvingInObtainingExtraCannotBeOneDagAtDestination(XValues, YValues, destination, variables_avoided); } gettimeofday (&generalize_finish_ms, NULL); generalize_ms = generalize_finish_ms.tv_sec * 1000 + generalize_finish_ms.tv_usec / 1000; generalize_ms -= generalize_start_ms.tv_sec * 1000 + generalize_start_ms.tv_usec / 1000; #ifdef DEBUG_SKOLEM cout << "\nGeneralization finished in " << generalize_ms << " milliseconds\n"; #endif total_time_in_generalization_in_mu_based_scheme_with_optimizations_in_cegar = total_time_in_generalization_in_mu_based_scheme_with_optimizations_in_cegar + generalize_ms; number_of_variables_dropped_in_generalization = variables_avoided.size(); // Return the conjunction of x's below destination and y's as per their values set extra_cannot_be_one_dag_components; // all y variables keep their values in the existing model for(map::iterator yvalues_it = YValues.begin(); yvalues_it != YValues.end(); yvalues_it++) { string variable_name = yvalues_it->first; int variable_value = yvalues_it->second; if(variables_avoided.find(variable_name) != variables_avoided.end()) { continue; } Aig_Obj_t* variable_object; map::iterator Ci_name_to_Ci_object_map_it = Ci_name_to_Ci_object_map.find(variable_name); assert(Ci_name_to_Ci_object_map_it != Ci_name_to_Ci_object_map.end()); variable_object = Ci_name_to_Ci_object_map_it->second; if(variable_value == 1) // variable_value is true { extra_cannot_be_one_dag_components.insert(variable_object); } else if(variable_value == 0) // variable_value is false { extra_cannot_be_one_dag_components.insert(createNot(variable_object, pub_aig_manager)); } } // assert that all x_new variables upto destination keep their values in the existing model for(int var_to_elim_index = number_of_vars_to_elim; var_to_elim_index >= 1; var_to_elim_index--) { if(var_to_elim_index <= destination) { break; } else { string variable_name = searchVarIndexToVarNameMap(var_index_to_var_name_map, var_to_elim_index); if(variables_avoided.find(variable_name) != variables_avoided.end()) { continue; } Aig_Obj_t* variable_object; map::iterator Ci_name_to_Ci_object_map_it = Ci_name_to_Ci_object_map.find(variable_name); assert(Ci_name_to_Ci_object_map_it != Ci_name_to_Ci_object_map.end()); variable_object = Ci_name_to_Ci_object_map_it->second; map::iterator XValues_it = XValues.find(var_to_elim_index); assert(XValues_it != XValues.end()); if(XValues_it->second == 1) // variable_value is true { extra_cannot_be_one_dag_components.insert(variable_object); } else if(XValues_it->second == 0) // variable_value is false { extra_cannot_be_one_dag_components.insert(createNot(variable_object, pub_aig_manager)); } } } Aig_Obj_t* extra_cannot_be_one_dag; if(extra_cannot_be_one_dag_components.size() == 0) { extra_cannot_be_one_dag = createTrue(pub_aig_manager); } else { extra_cannot_be_one_dag = createAnd(extra_cannot_be_one_dag_components, pub_aig_manager); } assert(extra_cannot_be_one_dag != NULL); return extra_cannot_be_one_dag; } void AIGBasedSkolem::obtainGeneralizedModelByIncrementalSolvingInObtainingExtraCannotBeOneDagAtDestination(map &XValues, map &YValues, int destination, set &variables_avoided) { map positive_objects; map negative_objects; set variables_to_consider; vector positive_assumptions; vector negative_assumptions; Aig_Obj_t* increment; bool result_of_generalization_check; map Model_of_Generalizationcheck; unsigned long long int cnf_time; int formula_size; unsigned long long int simplification_time; for(map::iterator yvalues_it = YValues.begin(); yvalues_it != YValues.end(); yvalues_it++) { string variable_name = yvalues_it->first; int variable_value = yvalues_it->second; Aig_Obj_t* variable_object; map::iterator Ci_name_to_Ci_object_map_it = Ci_name_to_Ci_object_map.find(variable_name); assert(Ci_name_to_Ci_object_map_it != Ci_name_to_Ci_object_map.end()); variable_object = Ci_name_to_Ci_object_map_it->second; if(variable_value == 1) // variable_value is true { positive_objects.insert(make_pair(variable_name, variable_object)); positive_assumptions.push_back(variable_object); } else if(variable_value == 0) // variable_value is false { negative_objects.insert(make_pair(variable_name, variable_object)); negative_assumptions.push_back(variable_object); } else { assert(false); } variables_to_consider.insert(variable_name); } for(int var_to_elim_index = number_of_vars_to_elim; var_to_elim_index >= 1; var_to_elim_index--) { if(var_to_elim_index <= destination) { break; } else { string variable_name = searchVarIndexToVarNameMap(var_index_to_var_name_map, var_to_elim_index); Aig_Obj_t* variable_object; map::iterator Ci_name_to_Ci_object_map_it = Ci_name_to_Ci_object_map.find(variable_name); assert(Ci_name_to_Ci_object_map_it != Ci_name_to_Ci_object_map.end()); variable_object = Ci_name_to_Ci_object_map_it->second; map::iterator XValues_it = XValues.find(var_to_elim_index); assert(XValues_it != XValues.end()); if(XValues_it->second == 1) // variable_value is true { positive_objects.insert(make_pair(variable_name, variable_object)); positive_assumptions.push_back(variable_object); } else if(XValues_it->second == 0) // variable_value is false { negative_objects.insert(make_pair(variable_name, variable_object)); negative_assumptions.push_back(variable_object); } else { assert(false); } variables_to_consider.insert(variable_name); } } string variable_name_at_destination = searchVarIndexToVarNameMap(var_index_to_var_name_map, destination); Aig_Obj_t* variable_object_at_destination; map::iterator Ci_name_to_Ci_object_map_it = Ci_name_to_Ci_object_map.find(variable_name_at_destination); assert(Ci_name_to_Ci_object_map_it != Ci_name_to_Ci_object_map.end()); variable_object_at_destination = Ci_name_to_Ci_object_map_it->second; positive_objects.insert(make_pair(variable_name_at_destination, variable_object_at_destination)); positive_assumptions.push_back(variable_object_at_destination); if(!incremental_solver_for_generalization_check_initialized) { increment = conjunction_of_factors; incremental_solver_for_generalization_check_initialized = true; } else { increment = createTrue(pub_aig_manager); } assert(increment != NULL); result_of_generalization_check = isExactnessCheckSatisfiable(pub_aig_manager, increment, Model_of_Generalizationcheck, cnf_time, formula_size, simplification_time, positive_assumptions, negative_assumptions, pSat_for_generalization_check, IncrementalLabelTableForGeneralizationCheck, IncrementalLabelCountForGeneralizationCheck, Ci_name_to_Ci_label_mapForGeneralizationCheck, Ci_label_to_Ci_name_mapForGeneralizationCheck); assert(!result_of_generalization_check); //x_destination = 1 and variables below as per model should give unsat for(set::iterator variables_to_consider_it = variables_to_consider.begin(); variables_to_consider_it != variables_to_consider.end(); variables_to_consider_it++) { string variable_to_consider = *variables_to_consider_it; positive_assumptions.clear(); negative_assumptions.clear(); for(map::iterator positive_objects_it = positive_objects.begin(); positive_objects_it != positive_objects.end(); positive_objects_it++) { string positive_variable_name = positive_objects_it->first; Aig_Obj_t* positive_object_of_variable_name = positive_objects_it->second; if(positive_variable_name != variable_to_consider && variables_avoided.find(positive_variable_name) == variables_avoided.end()) { positive_assumptions.push_back(positive_object_of_variable_name); } } for(map::iterator negative_objects_it = negative_objects.begin(); negative_objects_it != negative_objects.end(); negative_objects_it++) { string negative_variable_name = negative_objects_it->first; Aig_Obj_t* negative_object_of_variable_name = negative_objects_it->second; if(negative_variable_name != variable_to_consider && variables_avoided.find(negative_variable_name) == variables_avoided.end()) { negative_assumptions.push_back(negative_object_of_variable_name); } } increment = createTrue(pub_aig_manager); assert(increment != NULL); result_of_generalization_check = isExactnessCheckSatisfiable(pub_aig_manager, increment, Model_of_Generalizationcheck, cnf_time, formula_size, simplification_time, positive_assumptions, negative_assumptions, pSat_for_generalization_check, IncrementalLabelTableForGeneralizationCheck, IncrementalLabelCountForGeneralizationCheck, Ci_name_to_Ci_label_mapForGeneralizationCheck, Ci_label_to_Ci_name_mapForGeneralizationCheck); if(!result_of_generalization_check) // GeneralizationCheck unsat i.e. we can avoid variable_to_consider { #ifdef DEBUG_SKOLEM cout << "\nWe CAN avoid " << variable_to_consider << endl; #endif variables_avoided.insert(variable_to_consider); } else // we cannot avoid variable_to_consider { #ifdef DEBUG_SKOLEM cout << "\nWe CANNOT avoid " << variable_to_consider << endl; #endif } } // take each variable to consider } // function ends here bool AIGBasedSkolem::checkIfSkolemFunctionAtGivenIndexIsExact_using_Mu_Based_Scheme_With_Optimizations_With_Incremental_Solving(int correction_index, map &Model_of_ExactnessCheck, map &Refinement_Hint_Of_CannotBe_One_To_Eliminate_This_CEX, map &Refinement_Hint_Of_CannotBe_Zero_To_Eliminate_This_CEX, list &VariablesToEliminate) { #ifdef RECORD_KEEP string record_file; record_file = logfile_prefix; record_file += "skolem_function_generation_details.txt"; FILE* record_fp = fopen(record_file.c_str(), "a+"); assert(record_fp != NULL); #endif if(cegar_iteration_number == 0) { Aig_Obj_t* epsilon_zero; // correction_index must be number_of_vars_to_elim assert(correction_index == number_of_vars_to_elim); // Create the dag for epsilon_zero: // dag for epsilon_zero is: // F(x_1',...,x_n',Y) \wedge // (B_1 \vee ... \vee B_{n-1}) \wedge (B_1 = dag for bad_1) \wedge ... (B_{n-1} = dag for bad_{n-1}) \wedge // (x_2 = psi_2) \wedge ... \wedge (x_n = psi_n) \wedge // (eta_1 = dag for eta_1) \wedge ... \wedge (eta_l = dag for eta_l) \wedge // (sigma_1 = dag for sigma_1) \wedge ... \wedge (sigma_s = dag for sigma_s) \wedge // we need to consider eta's and sigma's of all x_i's // (neg_cb0_1 = \neg(disjunction of sigma's of x_1)\wedge y_1) \wedge ... \wedge (neg_cb0_n = \neg(disjunction of sigma's of x_n)\wedge y_n) // Let's first create dag for // (eta_1 = dag for eta_1) \wedge ... \wedge (eta_l = dag for eta_l) \wedge // (sigma_1 = dag for sigma_1) \wedge ... \wedge (sigma_s = dag for sigma_s) // in Cb_part Aig_Obj_t* Cb_part; set Cb_objects; for(map >::iterator cannot_be_one_set_it = cannot_be_one_set.begin(); cannot_be_one_set_it != cannot_be_one_set.end(); cannot_be_one_set_it++) { int var_to_elim_index = cannot_be_one_set_it->first; set cannot_be_one_set_objects = cannot_be_one_set_it->second; // let's find the corresponding dags for(set::iterator cannot_be_one_set_objects_it = cannot_be_one_set_objects.begin(); cannot_be_one_set_objects_it != cannot_be_one_set_objects.end(); cannot_be_one_set_objects_it++) { Aig_Obj_t* cannot_be_object = *cannot_be_one_set_objects_it; assert(cannot_be_object != NULL); map::iterator cannot_be_object_to_cannot_be_dag_map_it = cannot_be_object_to_cannot_be_dag_map.find(cannot_be_object); assert(cannot_be_object_to_cannot_be_dag_map_it != cannot_be_object_to_cannot_be_dag_map.end()); Aig_Obj_t* cannot_be_dag = cannot_be_object_to_cannot_be_dag_map_it->second; assert(cannot_be_dag != NULL); Aig_Obj_t* Cb_equivalence = createEquivalence(cannot_be_object, cannot_be_dag, pub_aig_manager); Cb_objects.insert(Cb_equivalence); } } for(map >::iterator cannot_be_zero_set_it = cannot_be_zero_set.begin(); cannot_be_zero_set_it != cannot_be_zero_set.end(); cannot_be_zero_set_it++) { int var_to_elim_index = cannot_be_zero_set_it->first; set cannot_be_zero_set_objects = cannot_be_zero_set_it->second; // let's find the corresponding dags for(set::iterator cannot_be_zero_set_objects_it = cannot_be_zero_set_objects.begin(); cannot_be_zero_set_objects_it != cannot_be_zero_set_objects.end(); cannot_be_zero_set_objects_it++) { Aig_Obj_t* cannot_be_object = *cannot_be_zero_set_objects_it; assert(cannot_be_object != NULL); map::iterator cannot_be_object_to_cannot_be_dag_map_it = cannot_be_object_to_cannot_be_dag_map.find(cannot_be_object); assert(cannot_be_object_to_cannot_be_dag_map_it != cannot_be_object_to_cannot_be_dag_map.end()); Aig_Obj_t* cannot_be_dag = cannot_be_object_to_cannot_be_dag_map_it->second; assert(cannot_be_dag != NULL); Aig_Obj_t* Cb_equivalence = createEquivalence(cannot_be_object, cannot_be_dag, pub_aig_manager); Cb_objects.insert(Cb_equivalence); } } assert(!Cb_objects.empty()); Cb_part = createAnd(Cb_objects, pub_aig_manager); assert(Cb_part != NULL); // connect to some output to avoid unwanted deletion Aig_Obj_t* Cb_part_CO = Aig_ObjCreateCo(pub_aig_manager, Cb_part ); assert(Cb_part_CO != NULL); // Let's create dag for (x_2 = psi_2) \wedge ... \wedge (x_n = psi_n) Aig_Obj_t* S_equivalence_part; set S_equivalence_objects; // we need to create psi_i as disjunction of elements in initial_cannot_be_zero_objects[i] // \vee negation of disjunction of elements in cannot-be-one-set[i] for(map >::iterator cannot_be_one_set_it = cannot_be_one_set.begin(); cannot_be_one_set_it != cannot_be_one_set.end(); cannot_be_one_set_it++) { int var_to_elim_index = cannot_be_one_set_it->first; // obtaining dag for x_i string var_to_elim = searchVarIndexToVarNameMap(var_index_to_var_name_map, var_to_elim_index); map::iterator Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it = Ci_to_eliminate_name_to_Ci_to_eliminate_object_map.find(var_to_elim); assert(Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it != Ci_to_eliminate_name_to_Ci_to_eliminate_object_map.end()); Aig_Obj_t* var_to_elim_obj = Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it->second; // obtaining \psi_i_part2 Aig_Obj_t* psi_i_part2; set psi_i_part2_components = cannot_be_one_set_it->second; if(psi_i_part2_components.empty()) { psi_i_part2 = createTrue(pub_aig_manager); } else { psi_i_part2 = createOr(psi_i_part2_components, pub_aig_manager); psi_i_part2 = createNot(psi_i_part2, pub_aig_manager); } assert(psi_i_part2 != NULL); // initialize Z_variable_counter[var_to_elim_index] to 0 Z_variable_counter.insert(make_pair(var_to_elim_index, 0)); int z_i_count = Z_variable_counter[var_to_elim_index]; // 0 here string z_i_string = obtainZVariableString(var_to_elim_index, z_i_count); // obtain the string Z_{var_to_elim_index}_0 // check if object for z_i_string is already existing; if yes return it; otherwise create, // update temporary_variable_for_incremental_solving_to_object_map and return Aig_Obj_t* z_i_object = obtainObjectOfTemporaryVariableForIncrementalSolving(z_i_string); assert(z_i_object != NULL); psi_i_part2 = createAnd(psi_i_part2, z_i_object, pub_aig_manager); assert(psi_i_part2 != NULL); // obtaining \psi_i_part1 Aig_Obj_t* psi_i_part1; map::iterator initial_cannot_be_zero_objects_it = initial_cannot_be_zero_objects.find(var_to_elim_index); assert(initial_cannot_be_zero_objects_it != initial_cannot_be_zero_objects.end()); psi_i_part1 = initial_cannot_be_zero_objects_it->second; assert(psi_i_part1 != NULL); // obtaining \psi_i Aig_Obj_t* psi_i; psi_i = createOr(psi_i_part1, psi_i_part2, pub_aig_manager); assert(psi_i != NULL); Aig_Obj_t* S_equivalence_i = createEquivalence(var_to_elim_obj, psi_i, pub_aig_manager); if(true) //var_to_elim_index > 1 is sufficeint; but may need code change { S_equivalence_objects.insert(S_equivalence_i); } } if(S_equivalence_objects.empty()) { S_equivalence_part = createTrue(pub_aig_manager); } else { S_equivalence_part = createAnd(S_equivalence_objects, pub_aig_manager); } assert(S_equivalence_part != NULL); // connect to some output to avoid unwanted deletion Aig_Obj_t* S_equivalence_part_CO = Aig_ObjCreateCo(pub_aig_manager, S_equivalence_part ); assert(S_equivalence_part_CO != NULL); // Let's create dag for // (B_1 = dag for bad_1) \wedge ... \wedge (B_{i} = dag for bad_{i}) Aig_Obj_t* B_equivalence_part; set B_equivalence_objects; Aig_Obj_t* B_part; set B_objects; for(int bad_location_index = 1; bad_location_index <= number_of_vars_to_elim; bad_location_index++) { Aig_Obj_t* bad_set_obj; bad_set_obj = searchOneDimensionalMatrix(BadSets, number_of_vars_to_elim, bad_location_index); assert(bad_set_obj != NULL); // Obtaining dag for bad_set_obj map::iterator B_i_index_to_B_i_object_map_iterator = B_i_index_to_B_i_object_map.find(bad_location_index); assert(B_i_index_to_B_i_object_map_iterator != B_i_index_to_B_i_object_map.end()); Aig_Obj_t* B_obj = B_i_index_to_B_i_object_map_iterator->second; assert(B_obj != NULL); B_objects.insert(B_obj); Aig_Obj_t* B_equivalence_i = createEquivalence(bad_set_obj, B_obj, pub_aig_manager); B_equivalence_objects.insert(B_equivalence_i); } assert(!B_equivalence_objects.empty()); B_equivalence_part = createAnd(B_equivalence_objects, pub_aig_manager); assert(B_equivalence_part != NULL); // connect to some output to avoid unwanted deletion Aig_Obj_t* B_equivalence_part_CO = Aig_ObjCreateCo(pub_aig_manager, B_equivalence_part ); assert(B_equivalence_part_CO != NULL); // Let's create dag for (~Cb0_1 = ~(sigmas)\wedge Y_1_0) \wedge ... \wedge (~Cb0_n = ~(sigmas)\wedge Y_n_0) // Let's denote ~Cb0_i's by N_i's #ifdef DEBUG_SKOLEM cout << "\nObtaining Ci's for N's\n"; #endif for(int var_to_elim_index = 1; var_to_elim_index <= number_of_vars_to_elim; var_to_elim_index++) { string N_i = "N_"; char var_count_char[100]; sprintf(var_count_char, "%d", var_to_elim_index); string var_count_string(var_count_char); N_i += var_count_string; Aig_Obj_t* N_i_obj = Aig_ObjCreateCi(pub_aig_manager); int N_i_id = Aig_ObjId(N_i_obj); // no need to apply Aig_Regular() as N_i_obj is CI Ci_id_to_Ci_name_map.insert(make_pair(N_i_id, N_i)); Ci_name_to_Ci_number_map.insert(make_pair(N_i, number_of_Cis)); N_i_index_to_N_i_object_map.insert(make_pair(var_to_elim_index, N_i_obj)); number_of_Cis++; } #ifdef DEBUG_SKOLEM cout << "\nCi's for N's obtained\n"; #endif Aig_Obj_t* additional_Cb_part; set additional_Cb_objects; for(map >::iterator cannot_be_zero_set_it = cannot_be_zero_set.begin(); cannot_be_zero_set_it != cannot_be_zero_set.end(); cannot_be_zero_set_it++) { int var_to_elim_index = cannot_be_zero_set_it->first; // obtaining object of N_i map::iterator N_i_index_to_N_i_object_map_iterator = N_i_index_to_N_i_object_map.find(var_to_elim_index); assert(N_i_index_to_N_i_object_map_iterator != N_i_index_to_N_i_object_map.end()); Aig_Obj_t* N_i_obj = N_i_index_to_N_i_object_map_iterator->second; assert(N_i_obj != NULL); // obtaining neg_cannot_be_zero_i dag Aig_Obj_t* neg_cannot_be_zero_i; set neg_cannot_be_zero_i_components = cannot_be_zero_set_it->second; if(neg_cannot_be_zero_i_components.empty()) { neg_cannot_be_zero_i = createTrue(pub_aig_manager); } else { neg_cannot_be_zero_i = createOr(neg_cannot_be_zero_i_components, pub_aig_manager); neg_cannot_be_zero_i = createNot(neg_cannot_be_zero_i, pub_aig_manager); } assert(neg_cannot_be_zero_i != NULL); // initialize Y_variable_counter[var_to_elim_index] to 0 Y_variable_counter.insert(make_pair(var_to_elim_index, 0)); int y_i_count = Y_variable_counter[var_to_elim_index]; // 0 here string y_i_string = obtainYVariableString(var_to_elim_index, y_i_count); // obtain the string Y_{var_to_elim_index}_0 // check if object for y_i_string is already existing; if yes return it; otherwise create, // update temporary_variable_for_incremental_solving_to_object_map and return Aig_Obj_t* y_i_object = obtainObjectOfTemporaryVariableForIncrementalSolving(y_i_string); assert(y_i_object != NULL); neg_cannot_be_zero_i = createAnd(neg_cannot_be_zero_i, y_i_object, pub_aig_manager); assert(neg_cannot_be_zero_i != NULL); Aig_Obj_t* N_equivalence_i = createEquivalence(N_i_obj, neg_cannot_be_zero_i, pub_aig_manager); assert(N_equivalence_i != NULL); additional_Cb_objects.insert(N_equivalence_i); } assert(!additional_Cb_objects.empty()); additional_Cb_part = createAnd(additional_Cb_objects, pub_aig_manager); assert(additional_Cb_part != NULL); // connect to some output to avoid unwanted deletion Aig_Obj_t* additional_Cb_part_CO = Aig_ObjCreateCo(pub_aig_manager, additional_Cb_part ); assert(additional_Cb_part_CO != NULL); #ifdef DEBUG_SKOLEM string Cb_part_file_name = benchmark_name_without_extension; Cb_part_file_name += "_Cb_part"; string S_equivalence_part_file_name = benchmark_name_without_extension; S_equivalence_part_file_name += "_S_equivalence_part"; string B_equivalence_part_file_name = benchmark_name_without_extension; B_equivalence_part_file_name += "_B_equivalence_part"; string additional_Cb_part_file_name = benchmark_name_without_extension; additional_Cb_part_file_name += "_additional_Cb_part"; cout << "\nCb_part computed\n"; cout << "\nS_equivalence_part computed\n"; cout << "\nB_equivalence_part computed\n"; cout << "\nadditional_Cb_part computed\n"; writeFormulaToFile(pub_aig_manager, Cb_part, Cb_part_file_name, ".v", cegar_iteration_number, 0); writeFormulaToFile(pub_aig_manager, S_equivalence_part, S_equivalence_part_file_name, ".v", cegar_iteration_number, 0); writeFormulaToFile(pub_aig_manager, B_equivalence_part, B_equivalence_part_file_name, ".v", cegar_iteration_number, 0); writeFormulaToFile(pub_aig_manager, additional_Cb_part, additional_Cb_part_file_name, ".v", cegar_iteration_number, 0); #endif set epsilon_zero_objects; epsilon_zero_objects.insert(Cb_part); epsilon_zero_objects.insert(S_equivalence_part); epsilon_zero_objects.insert(B_equivalence_part); epsilon_zero_objects.insert(disjunction_of_bad_symbols); epsilon_zero_objects.insert(renamed_conjunction_of_factors); epsilon_zero_objects.insert(additional_Cb_part); epsilon_zero = createAnd(epsilon_zero_objects, pub_aig_manager); assert(epsilon_zero != NULL); // connect to some output to avoid unwanted deletion Aig_Obj_t* epsilon_zero_CO = Aig_ObjCreateCo(pub_aig_manager, epsilon_zero ); assert(epsilon_zero_CO != NULL); if(Aig_IsComplement(epsilon_zero) && Aig_Regular(epsilon_zero) == createTrue(pub_aig_manager)) // epsilon_zero is false { #ifdef DEBUG_CEGAR cout << "\nAIG for epsilon_zero is false; no need to call the sat-solver\n"; #endif #ifdef RECORD_KEEP number_of_exactness_checking_in_cegar++; fprintf(record_fp, "\t0(0,0)(1)"); fclose(record_fp); #endif return true; } vector positive_assumptions_in_exactness_check; vector negative_assumptions_in_exactness_check; obtainAssumptionsInExactnessCheck_using_Generic_Skolem_Functions_With_Incremental_Solving(correction_index, positive_assumptions_in_exactness_check, negative_assumptions_in_exactness_check); assert(positive_assumptions_in_exactness_check.size() != 0); assert(negative_assumptions_in_exactness_check.size() == 1); // Use incremental solver call #ifdef DEBUG_CEGAR string epsilon_zero_file_name = benchmark_name_without_extension; epsilon_zero_file_name += "_epsilon_zero"; cout << "\nepsilon_zero computed\n"; writeFormulaToFile(pub_aig_manager, epsilon_zero, epsilon_zero_file_name, ".v", cegar_iteration_number, 0); cout << endl << "Adding clauses of epsilon_zero to SAT-Solver, and calling SAT-Solver\n"; #endif #ifdef DETAILED_RECORD_KEEP unsigned long long int solver_ms; struct timeval solver_start_ms, solver_finish_ms; gettimeofday (&solver_start_ms, NULL); #endif // Give to SAT-Solver and get unsat / sat with model unsigned long long int cnf_time; int formula_size; unsigned long long int simplification_time; bool result_of_exactnesscheck = isExactnessCheckSatisfiable(pub_aig_manager, epsilon_zero, Model_of_ExactnessCheck, cnf_time, formula_size, simplification_time, positive_assumptions_in_exactness_check, negative_assumptions_in_exactness_check, pSat_for_exactness_check, IncrementalLabelTableForExactnessCheck, IncrementalLabelCountForExactnessCheck, Ci_name_to_Ci_label_mapForExactnessCheck, Ci_label_to_Ci_name_mapForExactnessCheck); #ifdef DETAILED_RECORD_KEEP gettimeofday (&solver_finish_ms, NULL); solver_ms = solver_finish_ms.tv_sec * 1000 + solver_finish_ms.tv_usec / 1000; solver_ms -= solver_start_ms.tv_sec * 1000 + solver_start_ms.tv_usec / 1000; cout << "\nsolver finished in " << solver_ms << " milliseconds\n"; total_time_in_smt_solver = total_time_in_smt_solver + solver_ms; total_time_in_exactness_checking_in_cegar = total_time_in_exactness_checking_in_cegar + solver_ms; number_of_exactness_checking_in_cegar++; #endif #ifdef RECORD_KEEP fprintf(record_fp, "\t%llu(%llu,%llu)(%d)", solver_ms, cnf_time, simplification_time, formula_size); fclose(record_fp); #endif #ifdef DEBUG_SKOLEM displayModelFromSATSolver(Model_of_ExactnessCheck); cout << endl << "result_of_exactnesscheck = " << result_of_exactnesscheck << endl; #endif removeTemporaryVariablesFromModel(Model_of_ExactnessCheck); #ifdef DEBUG_CEGAR cout << "\nModel after removing temporary variables\n"; displayModelFromSATSolver(Model_of_ExactnessCheck); cout << endl << "result_of_exactnesscheck = " << result_of_exactnesscheck << endl; #endif if(!result_of_exactnesscheck) // ExactnessCheck unsat i.e. skolem function at correction_index is exact { return true; } else // skolem function at correction_index is inexact { return false; } } // if(cegar_iteration_number == 0) ends here else if(cegar_iteration_for_correction_index == 0) { assert(correction_index < number_of_vars_to_elim); Aig_Obj_t* delta_epsilon_i; int corrected_index = correction_index + 1; // obtaining object for x_{corrected_index} string var_to_elim = searchVarIndexToVarNameMap(var_index_to_var_name_map, corrected_index); map::iterator Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it = Ci_to_eliminate_name_to_Ci_to_eliminate_object_map.find(var_to_elim); assert(Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it != Ci_to_eliminate_name_to_Ci_to_eliminate_object_map.end()); Aig_Obj_t* var_to_elim_obj = Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it->second; assert(var_to_elim_obj != NULL); // obtaining dag for x_{corrected_index}' map::iterator Ci_to_eliminate_renamed_to_Ci_to_eliminate_renamed_object_map_it = Ci_to_eliminate_renamed_to_Ci_to_eliminate_renamed_object_map.find(corrected_index); assert(Ci_to_eliminate_renamed_to_Ci_to_eliminate_renamed_object_map_it != Ci_to_eliminate_renamed_to_Ci_to_eliminate_renamed_object_map.end()); Aig_Obj_t* var_to_elim_renamed_obj = Ci_to_eliminate_renamed_to_Ci_to_eliminate_renamed_object_map_it->second; assert(var_to_elim_renamed_obj != NULL); // creating (x_{corrected_index} = x_{corrected_index}') Aig_Obj_t* x_equivalence = createEquivalence(var_to_elim_obj, var_to_elim_renamed_obj, pub_aig_manager); assert(x_equivalence != NULL); // connect to some output to avoid unwanted deletion Aig_Obj_t* x_equivalence_CO = Aig_ObjCreateCo(pub_aig_manager, x_equivalence ); assert(x_equivalence_CO != NULL); #ifdef DEBUG_SKOLEM string x_equivalence_file_name = benchmark_name_without_extension; x_equivalence_file_name += "_x_equivalence"; cout << "\nx_equivalence computed\n"; writeFormulaToFile(pub_aig_manager, x_equivalence, x_equivalence_file_name, ".v", cegar_iteration_number, 0); #endif delta_epsilon_i = x_equivalence; assert(delta_epsilon_i != NULL); // connect to some output to avoid unwanted deletion Aig_Obj_t* delta_epsilon_i_CO = Aig_ObjCreateCo(pub_aig_manager, delta_epsilon_i ); assert(delta_epsilon_i_CO != NULL); #ifdef DEBUG_CEGAR string delta_epsilon_i_file_name = benchmark_name_without_extension; delta_epsilon_i_file_name += "_delta_epsilon_i"; cout << "\ndelta_epsilon_i computed\n"; writeFormulaToFile(pub_aig_manager, delta_epsilon_i, delta_epsilon_i_file_name, ".v", cegar_iteration_number, 0); cout << endl << "Adding clauses of delta_epsilon_i to SAT-Solver, and calling SAT-Solver\n"; #endif vector positive_assumptions_in_exactness_check; vector negative_assumptions_in_exactness_check; obtainAssumptionsInExactnessCheck_using_Generic_Skolem_Functions_With_Incremental_Solving(correction_index, positive_assumptions_in_exactness_check, negative_assumptions_in_exactness_check); assert(positive_assumptions_in_exactness_check.size() != 0); assert(negative_assumptions_in_exactness_check.size() != 0); // Use incremental solver call #ifdef DEBUG_CEGAR cout << endl << "Adding clauses of delta_epsilon_i to SAT-Solver, and calling SAT-Solver\n"; #endif #ifdef DETAILED_RECORD_KEEP unsigned long long int solver_ms; struct timeval solver_start_ms, solver_finish_ms; gettimeofday (&solver_start_ms, NULL); #endif // Give to SAT-Solver and get unsat / sat with model unsigned long long int cnf_time; int formula_size; unsigned long long int simplification_time; bool result_of_exactnesscheck = isExactnessCheckSatisfiable(pub_aig_manager, delta_epsilon_i, Model_of_ExactnessCheck, cnf_time, formula_size, simplification_time, positive_assumptions_in_exactness_check, negative_assumptions_in_exactness_check, pSat_for_exactness_check, IncrementalLabelTableForExactnessCheck, IncrementalLabelCountForExactnessCheck, Ci_name_to_Ci_label_mapForExactnessCheck, Ci_label_to_Ci_name_mapForExactnessCheck); #ifdef DETAILED_RECORD_KEEP gettimeofday (&solver_finish_ms, NULL); solver_ms = solver_finish_ms.tv_sec * 1000 + solver_finish_ms.tv_usec / 1000; solver_ms -= solver_start_ms.tv_sec * 1000 + solver_start_ms.tv_usec / 1000; cout << "\nsolver finished in " << solver_ms << " milliseconds\n"; total_time_in_smt_solver = total_time_in_smt_solver + solver_ms; total_time_in_exactness_checking_in_cegar = total_time_in_exactness_checking_in_cegar + solver_ms; number_of_exactness_checking_in_cegar++; #endif #ifdef RECORD_KEEP fprintf(record_fp, "\t%llu(%llu,%llu)(%d)", solver_ms, cnf_time, simplification_time, formula_size); fclose(record_fp); #endif #ifdef DEBUG_SKOLEM displayModelFromSATSolver(Model_of_ExactnessCheck); cout << endl << "result_of_exactnesscheck = " << result_of_exactnesscheck << endl; #endif removeTemporaryVariablesFromModel(Model_of_ExactnessCheck); #ifdef DEBUG_CEGAR cout << "\nModel after removing temporary variables\n"; displayModelFromSATSolver(Model_of_ExactnessCheck); cout << endl << "result_of_exactnesscheck = " << result_of_exactnesscheck << endl; #endif if(!result_of_exactnesscheck) // ExactnessCheck unsat i.e. skolem function at correction_index is exact { return true; } else // skolem function at correction_index is inexact { return false; } } else // if(cegar_iteration_for_correction_index > 0) { #ifdef DEBUG_CEGAR show_present_refinement_hint(Refinement_Hint_Of_CannotBe_One_To_Eliminate_This_CEX, Refinement_Hint_Of_CannotBe_Zero_To_Eliminate_This_CEX); #endif Aig_Obj_t* delta_epsilon_i; // Create the dag for delta_epsilon_i: // for each o_j added in Refinement_Hint_Of_CannotBe_One_To_Eliminate_This_CEX // (o_j = dag_j) \wedge // (Z_i_k = Z_i_{k+1} \wedge o_j) \wedge // for each o_l added in Refinement_Hint_Of_CannotBe_Zero_To_Eliminate_This_CEX // (o_l = dag_l) \wedge // (Y_i_k = Y_i_{k+1} \wedge o_l) \wedge Aig_Obj_t* Cb_part; set Cb_objects; Aig_Obj_t* Z_part; set Z_objects; Aig_Obj_t* Y_part; set Y_objects; for(map::iterator hint_it = Refinement_Hint_Of_CannotBe_One_To_Eliminate_This_CEX.begin(); hint_it != Refinement_Hint_Of_CannotBe_One_To_Eliminate_This_CEX.end(); hint_it++) { int destination = hint_it->first; Aig_Obj_t* new_cannot_be_one_object_at_destination = hint_it->second; map::iterator cannot_be_object_to_cannot_be_dag_map_it = cannot_be_object_to_cannot_be_dag_map.find(new_cannot_be_one_object_at_destination); assert(cannot_be_object_to_cannot_be_dag_map_it != cannot_be_object_to_cannot_be_dag_map.end()); Aig_Obj_t* new_cannot_be_one_dag_at_destination = cannot_be_object_to_cannot_be_dag_map_it->second; Aig_Obj_t* Cb_one_equivalence = createEquivalence(new_cannot_be_one_object_at_destination, new_cannot_be_one_dag_at_destination, pub_aig_manager); assert(Cb_one_equivalence != NULL); Cb_objects.insert(Cb_one_equivalence); int present_z_j_k_count = Z_variable_counter[destination]; int next_z_j_k_count = present_z_j_k_count + 1; Z_variable_counter[destination] = next_z_j_k_count; string present_z_j_k_string = obtainZVariableString(destination, present_z_j_k_count); // obtain the string Z_{destination}_{present_z_j_k_count} Aig_Obj_t* present_z_j_k_object = obtainExistingObjectOfTemporaryVariableForIncrementalSolving(present_z_j_k_string); assert(present_z_j_k_object != NULL); string next_z_j_k_string = obtainZVariableString(destination, next_z_j_k_count); // obtain the string Z_{destination}_{next_z_j_k_count} Aig_Obj_t* next_z_j_k_object = obtainObjectOfTemporaryVariableForIncrementalSolving(next_z_j_k_string); assert(next_z_j_k_object != NULL); Aig_Obj_t* R_i_j_increment = createEquivalence(present_z_j_k_object, createAnd(createNot(new_cannot_be_one_object_at_destination, pub_aig_manager), next_z_j_k_object, pub_aig_manager), pub_aig_manager); assert(R_i_j_increment != NULL); Z_objects.insert(R_i_j_increment); } for(map::iterator hint_it = Refinement_Hint_Of_CannotBe_Zero_To_Eliminate_This_CEX.begin(); hint_it != Refinement_Hint_Of_CannotBe_Zero_To_Eliminate_This_CEX.end(); hint_it++) { int destination = hint_it->first; Aig_Obj_t* new_cannot_be_zero_object_at_destination = hint_it->second; map::iterator cannot_be_object_to_cannot_be_dag_map_it = cannot_be_object_to_cannot_be_dag_map.find(new_cannot_be_zero_object_at_destination); assert(cannot_be_object_to_cannot_be_dag_map_it != cannot_be_object_to_cannot_be_dag_map.end()); Aig_Obj_t* new_cannot_be_zero_dag_at_destination = cannot_be_object_to_cannot_be_dag_map_it->second; Aig_Obj_t* Cb_zero_equivalence = createEquivalence(new_cannot_be_zero_object_at_destination, new_cannot_be_zero_dag_at_destination, pub_aig_manager); assert(Cb_zero_equivalence != NULL); Cb_objects.insert(Cb_zero_equivalence); int present_y_j_k_count = Y_variable_counter[destination]; int next_y_j_k_count = present_y_j_k_count + 1; Y_variable_counter[destination] = next_y_j_k_count; string present_y_j_k_string = obtainYVariableString(destination, present_y_j_k_count); // obtain the string Y_{destination}_{present_y_j_k_count} Aig_Obj_t* present_y_j_k_object = obtainExistingObjectOfTemporaryVariableForIncrementalSolving(present_y_j_k_string); assert(present_y_j_k_object != NULL); string next_y_j_k_string = obtainYVariableString(destination, next_y_j_k_count); // obtain the string Y_{destination}_{next_y_j_k_count} Aig_Obj_t* next_y_j_k_object = obtainObjectOfTemporaryVariableForIncrementalSolving(next_y_j_k_string); assert(next_y_j_k_object != NULL); Aig_Obj_t* R_i_j_increment = createEquivalence(present_y_j_k_object, createAnd(createNot(new_cannot_be_zero_object_at_destination, pub_aig_manager), next_y_j_k_object, pub_aig_manager), pub_aig_manager); assert(R_i_j_increment != NULL); Y_objects.insert(R_i_j_increment); } assert(!Cb_objects.empty()); Cb_part = createAnd(Cb_objects, pub_aig_manager); assert(Cb_part != NULL); // connect to some output to avoid unwanted deletion Aig_Obj_t* Cb_part_CO = Aig_ObjCreateCo(pub_aig_manager, Cb_part ); assert(Cb_part_CO != NULL); assert(!Z_objects.empty()); Z_part = createAnd(Z_objects, pub_aig_manager); assert(Z_part != NULL); // connect to some output to avoid unwanted deletion Aig_Obj_t* Z_part_CO = Aig_ObjCreateCo(pub_aig_manager, Z_part ); assert(Z_part_CO != NULL); if(Y_objects.empty()) { Y_part = createTrue(pub_aig_manager); } else { Y_part = createAnd(Y_objects, pub_aig_manager); assert(Y_part != NULL); // connect to some output to avoid unwanted deletion Aig_Obj_t* Y_part_CO = Aig_ObjCreateCo(pub_aig_manager, Y_part ); assert(Y_part_CO != NULL); } #ifdef DEBUG_SKOLEM string Cb_part_file_name = benchmark_name_without_extension; Cb_part_file_name += "_Cb_part"; string Z_part_file_name = benchmark_name_without_extension; Z_part_file_name += "_Z_part"; string Y_part_file_name = benchmark_name_without_extension; Y_part_file_name += "_Y_part"; cout << "\nCb_part computed\n"; cout << "\nZ_part computed\n"; cout << "\nY_part computed\n"; writeFormulaToFile(pub_aig_manager, Cb_part, Cb_part_file_name, ".v", cegar_iteration_number, 0); writeFormulaToFile(pub_aig_manager, Z_part, Z_part_file_name, ".v", cegar_iteration_number, 0); writeFormulaToFile(pub_aig_manager, Y_part, Y_part_file_name, ".v", cegar_iteration_number, 0); #endif delta_epsilon_i = createAnd( createAnd(Cb_part, Z_part, pub_aig_manager), Y_part, pub_aig_manager); assert(delta_epsilon_i != NULL); // connect to some output to avoid unwanted deletion Aig_Obj_t* delta_epsilon_i_CO = Aig_ObjCreateCo(pub_aig_manager, delta_epsilon_i ); assert(delta_epsilon_i_CO != NULL); #ifdef DEBUG_CEGAR string delta_epsilon_i_file_name = benchmark_name_without_extension; delta_epsilon_i_file_name += "_delta_epsilon_i"; cout << "\ndelta_epsilon_i computed\n"; writeFormulaToFile(pub_aig_manager, delta_epsilon_i, delta_epsilon_i_file_name, ".v", cegar_iteration_number, 0); cout << endl << "Adding clauses of delta_epsilon_i to SAT-Solver, and calling SAT-Solver\n"; #endif vector positive_assumptions_in_exactness_check; vector negative_assumptions_in_exactness_check; obtainAssumptionsInExactnessCheck_using_Generic_Skolem_Functions_With_Incremental_Solving(correction_index, positive_assumptions_in_exactness_check, negative_assumptions_in_exactness_check); assert(positive_assumptions_in_exactness_check.size() != 0); assert(negative_assumptions_in_exactness_check.size() != 0); // Use incremental solver call #ifdef DEBUG_CEGAR cout << endl << "Adding clauses of delta_epsilon_i to SAT-Solver, and calling SAT-Solver\n"; #endif #ifdef DETAILED_RECORD_KEEP unsigned long long int solver_ms; struct timeval solver_start_ms, solver_finish_ms; gettimeofday (&solver_start_ms, NULL); #endif // Give to SAT-Solver and get unsat / sat with model unsigned long long int cnf_time; int formula_size; unsigned long long int simplification_time; bool result_of_exactnesscheck = isExactnessCheckSatisfiable(pub_aig_manager, delta_epsilon_i, Model_of_ExactnessCheck, cnf_time, formula_size, simplification_time, positive_assumptions_in_exactness_check, negative_assumptions_in_exactness_check, pSat_for_exactness_check, IncrementalLabelTableForExactnessCheck, IncrementalLabelCountForExactnessCheck, Ci_name_to_Ci_label_mapForExactnessCheck, Ci_label_to_Ci_name_mapForExactnessCheck); #ifdef DETAILED_RECORD_KEEP gettimeofday (&solver_finish_ms, NULL); solver_ms = solver_finish_ms.tv_sec * 1000 + solver_finish_ms.tv_usec / 1000; solver_ms -= solver_start_ms.tv_sec * 1000 + solver_start_ms.tv_usec / 1000; cout << "\nsolver finished in " << solver_ms << " milliseconds\n"; total_time_in_smt_solver = total_time_in_smt_solver + solver_ms; total_time_in_exactness_checking_in_cegar = total_time_in_exactness_checking_in_cegar + solver_ms; number_of_exactness_checking_in_cegar++; #endif #ifdef RECORD_KEEP fprintf(record_fp, "\t%llu(%llu,%llu)(%d)", solver_ms, cnf_time, simplification_time, formula_size); fclose(record_fp); #endif #ifdef DEBUG_SKOLEM displayModelFromSATSolver(Model_of_ExactnessCheck); cout << endl << "result_of_exactnesscheck = " << result_of_exactnesscheck << endl; #endif removeTemporaryVariablesFromModel(Model_of_ExactnessCheck); #ifdef DEBUG_CEGAR cout << "\nModel after removing temporary variables\n"; displayModelFromSATSolver(Model_of_ExactnessCheck); cout << endl << "result_of_exactnesscheck = " << result_of_exactnesscheck << endl; #endif if(!result_of_exactnesscheck) // ExactnessCheck unsat i.e. skolem function at correction_index is exact { return true; } else // skolem function at correction_index is inexact { return false; } } // if(cegar_iteration_for_correction_index > 0) ends here } void AIGBasedSkolem::obtainAssumptionsInExactnessCheck_using_Generic_Skolem_Functions_With_Incremental_Solving(int correction_index, vector &positive_assumptions_in_exactness_check, vector &negative_assumptions_in_exactness_check) { // positive_assumptions_in_exactness_check includes // Z_i_j for each i = variable_to_eliminate and j = Z_variable_counter[i] for(int var_to_elim_index = 1; var_to_elim_index <= number_of_vars_to_elim; var_to_elim_index++) { map::iterator Z_variable_counter_it = Z_variable_counter.find(var_to_elim_index); assert(Z_variable_counter_it != Z_variable_counter.end()); int z_i_count = Z_variable_counter_it->second; string z_i_string = obtainZVariableString(var_to_elim_index, z_i_count); // obtain the string Z_{var_to_elim_index}_{z_i_count} Aig_Obj_t* z_i_object = obtainExistingObjectOfTemporaryVariableForIncrementalSolving(z_i_string); assert(z_i_object != NULL); positive_assumptions_in_exactness_check.push_back(z_i_object); } // positive_assumptions_in_exactness_check includes // Y_i_j for each i = variable_to_eliminate and j = Y_variable_counter[i] for(int var_to_elim_index = 1; var_to_elim_index <= number_of_vars_to_elim; var_to_elim_index++) { map::iterator Y_variable_counter_it = Y_variable_counter.find(var_to_elim_index); assert(Y_variable_counter_it != Y_variable_counter.end()); int y_i_count = Y_variable_counter_it->second; string y_i_string = obtainYVariableString(var_to_elim_index, y_i_count); // obtain the string Y_{var_to_elim_index}_{y_i_count} Aig_Obj_t* y_i_object = obtainExistingObjectOfTemporaryVariableForIncrementalSolving(y_i_string); assert(y_i_object != NULL); positive_assumptions_in_exactness_check.push_back(y_i_object); } // obtaining dag for x_{correction_index} string var_to_elim = searchVarIndexToVarNameMap(var_index_to_var_name_map, correction_index); map::iterator Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it = Ci_to_eliminate_name_to_Ci_to_eliminate_object_map.find(var_to_elim); assert(Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it != Ci_to_eliminate_name_to_Ci_to_eliminate_object_map.end()); Aig_Obj_t* var_to_elim_obj = Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it->second; assert(var_to_elim_obj != NULL); positive_assumptions_in_exactness_check.push_back(var_to_elim_obj); // obtaining dag for x_{correction_index}' map::iterator Ci_to_eliminate_renamed_to_Ci_to_eliminate_renamed_object_map_it = Ci_to_eliminate_renamed_to_Ci_to_eliminate_renamed_object_map.find(correction_index); assert(Ci_to_eliminate_renamed_to_Ci_to_eliminate_renamed_object_map_it != Ci_to_eliminate_renamed_to_Ci_to_eliminate_renamed_object_map.end()); Aig_Obj_t* var_to_elim_renamed_obj = Ci_to_eliminate_renamed_to_Ci_to_eliminate_renamed_object_map_it->second; assert(var_to_elim_renamed_obj != NULL); negative_assumptions_in_exactness_check.push_back(var_to_elim_renamed_obj); // obtaining object of N_{correction_index} map::iterator N_i_index_to_N_i_object_map_iterator = N_i_index_to_N_i_object_map.find(correction_index); assert(N_i_index_to_N_i_object_map_iterator != N_i_index_to_N_i_object_map.end()); Aig_Obj_t* N_i_obj = N_i_index_to_N_i_object_map_iterator->second; assert(N_i_obj != NULL); positive_assumptions_in_exactness_check.push_back(N_i_obj); bool use_support_based_bad_exclusion = true; if(use_support_based_bad_exclusion) { if(correction_index < number_of_vars_to_elim) { map >::iterator bads_to_exclude_it = bads_to_exclude.find(correction_index); set bads_to_exclude_for_correction_index = bads_to_exclude_it->second; for(set::iterator bads_to_exclude_for_correction_index_it = bads_to_exclude_for_correction_index.begin(); bads_to_exclude_for_correction_index_it != bads_to_exclude_for_correction_index.end(); bads_to_exclude_for_correction_index_it++) { int bad_index = *bads_to_exclude_for_correction_index_it; map::iterator B_i_index_to_B_i_object_map_iterator = B_i_index_to_B_i_object_map.find(bad_index); assert(B_i_index_to_B_i_object_map_iterator != B_i_index_to_B_i_object_map.end()); Aig_Obj_t* B_obj = B_i_index_to_B_i_object_map_iterator->second; assert(B_obj != NULL); negative_assumptions_in_exactness_check.push_back(B_obj); } } } else { for(int var_to_elim_index = number_of_vars_to_elim; var_to_elim_index >= correction_index+1; var_to_elim_index--) { map::iterator B_i_index_to_B_i_object_map_iterator = B_i_index_to_B_i_object_map.find(var_to_elim_index); assert(B_i_index_to_B_i_object_map_iterator != B_i_index_to_B_i_object_map.end()); Aig_Obj_t* B_obj = B_i_index_to_B_i_object_map_iterator->second; assert(B_obj != NULL); negative_assumptions_in_exactness_check.push_back(B_obj); } } } string AIGBasedSkolem::obtainYVariableString(int var_to_elim_index, int y_i_count) { // Return the string Y_{var_to_elim_index}_{y_i_count} string Y_string = "Y_"; char var_char[100]; sprintf(var_char, "%d", var_to_elim_index); string var_string(var_char); Y_string += var_string; Y_string += "_"; char count_char[100]; sprintf(count_char, "%d", y_i_count); string count_string(count_char); Y_string += count_string; return Y_string; } void AIGBasedSkolem::skolemFunctionGeneratorUsingBloqqer(set &Factors_new, list &VariablesToEliminate) { unsigned long long int total_ms; struct timeval total_start_ms, total_finish_ms; gettimeofday (&total_start_ms, NULL); set VariablesToEliminate_Set(VariablesToEliminate.begin(), VariablesToEliminate.end()); set Factors; if(drop_free_factors) { for(set::iterator factor_it = Factors_new.begin(); factor_it != Factors_new.end(); factor_it++) { Aig_Obj_t* factor = *factor_it; assert(factor != NULL); set support_factor; computeSupport(factor, support_factor, pub_aig_manager); set varstoelim_in_support_factor; set_intersection(support_factor.begin(), support_factor.end(), VariablesToEliminate_Set.begin(), VariablesToEliminate_Set.end(), inserter(varstoelim_in_support_factor, varstoelim_in_support_factor.begin())); if(!varstoelim_in_support_factor.empty()) { Factors.insert(factor); } }//for }//if(drop_free_factors) ends here else { Factors = Factors_new; } conjunction_of_factors = createAnd(Factors, pub_aig_manager); string qdimacs_file = benchmark_name_without_extension; qdimacs_file += "_bloqqer.qdimacs"; string model_file = benchmark_name_without_extension; model_file += "_bloqqer.model"; unsigned long long int con_ms; struct timeval con_start_ms, con_finish_ms; gettimeofday (&con_start_ms, NULL); convertToQDimacs(conjunction_of_factors, VariablesToEliminate_Set, pub_aig_manager, qdimacs_file); gettimeofday (&con_finish_ms, NULL); con_ms = con_finish_ms.tv_sec * 1000 + con_finish_ms.tv_usec / 1000; con_ms -= con_start_ms.tv_sec * 1000 + con_start_ms.tv_usec / 1000; cout << "\nConversion to QDIMACS in " << con_ms << " milliseconds\n"; string plot_file; plot_file = logfile_prefix; plot_file += "skolem_function_generation_details_to_plot.txt"; FILE* plot_fp = fopen(plot_file.c_str(), "a+"); assert(plot_fp != NULL); fprintf(plot_fp, "\n%s\t%s\t%s\tbloqqer\t%llu\t", benchmark_type.c_str(), benchmark_name.c_str(), machine.c_str(), con_ms); bool satisfiable; if(skip_satisfiability_check_before_bloqqer) { satisfiable = true; } else { if(qbf_solver_to_use == "depqbf") { string command = "depqbf "; command += qdimacs_file; command += " > "; command += model_file; system(command.c_str()); ifstream *model_file_ptr = new ifstream(); model_file_ptr->open(model_file.c_str()); // open the model_file assert(model_file_ptr->is_open()); string word = ""; *model_file_ptr>>word; if(word == "SAT") { satisfiable = true; } else if(word == "UNSAT") { satisfiable = false; } else { assert(false); } } else if(qbf_solver_to_use == "QuBE7") { string command = "QuBE7 "; command += qdimacs_file; command += " > "; command += model_file; system(command.c_str()); ifstream *model_file_ptr = new ifstream(); model_file_ptr->open(model_file.c_str()); // open the model_file assert(model_file_ptr->is_open()); string word = ""; *model_file_ptr>>word; if(word == "SAT") { satisfiable = true; } else if(word == "UNSAT") { satisfiable = false; } else { assert(false); } } else { assert(false); } } if(!satisfiable) { cout << "\nProblem is unsat! Bloqqer cannot solve this!\n"; fprintf(plot_fp, "\tunsat\t0"); } else { cout << "\nProblem is sat! Bloqqer can solve this!\n"; unsigned long long int step_ms; struct timeval step_start_ms, step_finish_ms; gettimeofday (&step_start_ms, NULL); string qrat_file; string qrat_tmp_file; string out_file; string log_file; qrat_file = qdimacs_file; qrat_file += ".qrat"; qrat_tmp_file = qdimacs_file; qrat_tmp_file += ".qrat.tmp"; out_file = qdimacs_file; out_file += ".out"; log_file = qdimacs_file; log_file += ".log"; string command = "bloqqer --qrat="; command += qrat_tmp_file; command += " "; command += qdimacs_file; command += " "; command += out_file; cout << endl << command << endl; system(command.c_str()); command = "./filter "; command += qrat_tmp_file; command += " > "; command += qrat_file; cout << endl << command << endl; system(command.c_str()); command = "qrat-trim "; command += qdimacs_file; command += " "; command += qrat_file; command += " -S"; command += " > "; command += log_file; cout << endl << command << endl; system(command.c_str()); gettimeofday (&step_finish_ms, NULL); step_ms = step_finish_ms.tv_sec * 1000 + step_finish_ms.tv_usec / 1000; step_ms -= step_start_ms.tv_sec * 1000 + step_start_ms.tv_usec / 1000; cout << "\nbloqqer found Skolem functions in " << step_ms << " milliseconds\n"; fprintf(plot_fp, "\tsat\t%llu", step_ms); } gettimeofday (&total_finish_ms, NULL); total_ms = total_finish_ms.tv_sec * 1000 + total_finish_ms.tv_usec / 1000; total_ms -= total_start_ms.tv_sec * 1000 + total_start_ms.tv_usec / 1000; cout << "\nTotal time = " << total_ms << " milliseconds\n"; fprintf(plot_fp, "\t%llu", total_ms); fclose(plot_fp); } Aig_Obj_t* AIGBasedSkolem::computeCofactorOneOrNegCofactorZero(int var_to_elim_index) { // Let us compute ~cofactorzero_{var_to_elim_index}\vee cofactorone_{var_to_elim_index} // Suppose i = var_to_elim_index // ~cofactorzero_{i} is // ~(conjunction of co-factor-0_i_j's) // cofactorone_{i} is // (conjunction of co-factor-1_i_j's) set cofactor_zero_components; set cofactor_one_components; #ifdef DEBUG_SKOLEM cout << "\ncomputing components of cofactor_zero and cofactor_one\n"; #endif #ifdef RECORD_KEEP int number_of_factors_containing_var_to_elim_index = FactorsWithVariable.size(); #endif for(set::iterator factor_it = FactorsWithVariable.begin(); factor_it != FactorsWithVariable.end(); factor_it++) { int factor_index = *factor_it; #ifdef DEBUG_SKOLEM cout << "\nfactor_index = " << factor_index << endl; #endif Aig_Obj_t* cofactor_1_i_j; cofactor_1_i_j = computeCofactorOne(var_to_elim_index, factor_index); assert(cofactor_1_i_j != NULL); Aig_Obj_t* cofactor_0_i_j; cofactor_0_i_j = computeCofactorZero(var_to_elim_index, factor_index); assert(cofactor_0_i_j != NULL); #ifdef DEBUG_SKOLEM writeFormulaToFile(pub_aig_manager, cofactor_1_i_j, "cofactor_1_i_j", ".v", var_to_elim_index, factor_index); writeFormulaToFile(pub_aig_manager, cofactor_0_i_j, "cofactor_0_i_j", ".v", var_to_elim_index, factor_index); #endif cofactor_one_components.insert(cofactor_1_i_j); cofactor_zero_components.insert(cofactor_0_i_j); FactorsAffectingSkolemFunction.push_back(factor_index); }// for each factor ends here Aig_Obj_t* cofactor_zero; if(cofactor_zero_components.size() == 0) { cofactor_zero = createTrue(pub_aig_manager); assert(cofactor_zero != NULL); } else { cofactor_zero = createAnd(cofactor_zero_components, pub_aig_manager); assert(cofactor_zero != NULL); } Aig_Obj_t* cofactor_one; if(cofactor_one_components.size() == 0) { cofactor_one = createTrue(pub_aig_manager); assert(cofactor_one != NULL); } else { cofactor_one = createAnd(cofactor_one_components, pub_aig_manager); assert(cofactor_one != NULL); } Aig_Obj_t* cofactor_one_or_neg_cofactor_zero; cofactor_one_or_neg_cofactor_zero = createOr(cofactor_one, createNot(cofactor_zero, pub_aig_manager), pub_aig_manager); assert(cofactor_one_or_neg_cofactor_zero != NULL); #ifdef DEBUG_SKOLEM writeFormulaToFile(pub_aig_manager, cofactor_one_or_neg_cofactor_zero, "cofactor_one_or_neg_cofactor_zero", ".v", var_to_elim_index, 0); #endif #ifdef RECORD_KEEP NumberOfFactors = number_of_factors_containing_var_to_elim_index; #endif return cofactor_one_or_neg_cofactor_zero; } bool AIGBasedSkolem::checkIfSkolemFunctionAtGivenIndexIsExact_using_Mu_Based_Scheme_With_Optimizations_With_Unified_Code_And_Incremental_Solving(int correction_index, map &Model_of_ExactnessCheck, map &Refinement_Hint_Of_CannotBe_One_To_Eliminate_This_CEX, map &Refinement_Hint_Of_CannotBe_Zero_To_Eliminate_This_CEX, list &VariablesToEliminate) { #ifdef RECORD_KEEP string record_file; record_file = logfile_prefix; record_file += "skolem_function_generation_details.txt"; FILE* record_fp = fopen(record_file.c_str(), "a+"); assert(record_fp != NULL); #endif if(cegar_iteration_number == 0) { #ifdef DEBUG_CEGAR cout << "\nCase with cegar_iteration_number == 0 \n"; #endif Aig_Obj_t* epsilon_zero; // correction_index must be number_of_vars_to_elim assert(correction_index == number_of_vars_to_elim); // Create the dag for epsilon_zero: // dag for epsilon_zero is: // F(x_1',...,x_n',Y) \wedge // (B_1 \vee ... \vee B_{n-1}) \wedge (B_1 = dag for bad_1) \wedge ... (B_{n-1} = dag for bad_{n-1}) \wedge // (x_2 = psi_2) \wedge ... \wedge (x_n = psi_n) \wedge // (eta_1 = dag for eta_1) \wedge ... \wedge (eta_l = dag for eta_l) \wedge // (sigma_1 = dag for sigma_1) \wedge ... \wedge (sigma_s = dag for sigma_s) \wedge // we need to consider eta's and sigma's of all x_i's // Let's first create dag for // (eta_1 = dag for eta_1) \wedge ... \wedge (eta_l = dag for eta_l) \wedge // (sigma_1 = dag for sigma_1) \wedge ... \wedge (sigma_s = dag for sigma_s) // in Cb_part Aig_Obj_t* Cb_part; set Cb_objects; for(map >::iterator cannot_be_one_set_it = cannot_be_one_set.begin(); cannot_be_one_set_it != cannot_be_one_set.end(); cannot_be_one_set_it++) { int var_to_elim_index = cannot_be_one_set_it->first; set cannot_be_one_set_objects = cannot_be_one_set_it->second; // let's find the corresponding dags for(set::iterator cannot_be_one_set_objects_it = cannot_be_one_set_objects.begin(); cannot_be_one_set_objects_it != cannot_be_one_set_objects.end(); cannot_be_one_set_objects_it++) { Aig_Obj_t* cannot_be_object = *cannot_be_one_set_objects_it; assert(cannot_be_object != NULL); map::iterator cannot_be_object_to_cannot_be_dag_map_it = cannot_be_object_to_cannot_be_dag_map.find(cannot_be_object); assert(cannot_be_object_to_cannot_be_dag_map_it != cannot_be_object_to_cannot_be_dag_map.end()); Aig_Obj_t* cannot_be_dag = cannot_be_object_to_cannot_be_dag_map_it->second; assert(cannot_be_dag != NULL); Aig_Obj_t* Cb_equivalence = createEquivalence(cannot_be_object, cannot_be_dag, pub_aig_manager); Cb_objects.insert(Cb_equivalence); } } for(map >::iterator cannot_be_zero_set_it = cannot_be_zero_set.begin(); cannot_be_zero_set_it != cannot_be_zero_set.end(); cannot_be_zero_set_it++) { int var_to_elim_index = cannot_be_zero_set_it->first; set cannot_be_zero_set_objects = cannot_be_zero_set_it->second; // let's find the corresponding dags for(set::iterator cannot_be_zero_set_objects_it = cannot_be_zero_set_objects.begin(); cannot_be_zero_set_objects_it != cannot_be_zero_set_objects.end(); cannot_be_zero_set_objects_it++) { Aig_Obj_t* cannot_be_object = *cannot_be_zero_set_objects_it; assert(cannot_be_object != NULL); map::iterator cannot_be_object_to_cannot_be_dag_map_it = cannot_be_object_to_cannot_be_dag_map.find(cannot_be_object); assert(cannot_be_object_to_cannot_be_dag_map_it != cannot_be_object_to_cannot_be_dag_map.end()); Aig_Obj_t* cannot_be_dag = cannot_be_object_to_cannot_be_dag_map_it->second; assert(cannot_be_dag != NULL); Aig_Obj_t* Cb_equivalence = createEquivalence(cannot_be_object, cannot_be_dag, pub_aig_manager); Cb_objects.insert(Cb_equivalence); } } assert(!Cb_objects.empty()); Cb_part = createAnd(Cb_objects, pub_aig_manager); assert(Cb_part != NULL); // connect to some output to avoid unwanted deletion Aig_Obj_t* Cb_part_CO = Aig_ObjCreateCo(pub_aig_manager, Cb_part ); assert(Cb_part_CO != NULL); // Let's create dag for (x_2 = psi_2) \wedge ... \wedge (x_n = psi_n) // We need to add exact Skolem functions for Tsietin variables if apply_tsietin_encoding_on_benchmarks is true Aig_Obj_t* S_equivalence_part; set S_equivalence_objects; // we need to create psi_i as disjunction of elements in initial_cannot_be_zero_objects[i] // \vee negation of disjunction of elements in cannot-be-one-set[i] for(map >::iterator cannot_be_one_set_it = cannot_be_one_set.begin(); cannot_be_one_set_it != cannot_be_one_set.end(); cannot_be_one_set_it++) { int var_to_elim_index = cannot_be_one_set_it->first; if(apply_tsietin_encoding_on_benchmarks) { if(var_to_elim_index <= number_of_tsietin_variables) { #ifdef DEBUG_SKOLEM cout << endl << var_to_elim_index << " <= " << number_of_tsietin_variables <<", hence exact Skolem fuctions to be used\n"; #endif continue; // no need to add abstract Skolem functions } } // obtaining dag for x_i string var_to_elim = searchVarIndexToVarNameMap(var_index_to_var_name_map, var_to_elim_index); map::iterator Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it = Ci_to_eliminate_name_to_Ci_to_eliminate_object_map.find(var_to_elim); assert(Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it != Ci_to_eliminate_name_to_Ci_to_eliminate_object_map.end()); Aig_Obj_t* var_to_elim_obj = Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it->second; // obtaining \psi_i_part2 Aig_Obj_t* psi_i_part2; set psi_i_part2_components = cannot_be_one_set_it->second; if(psi_i_part2_components.empty()) { psi_i_part2 = createTrue(pub_aig_manager); } else { psi_i_part2 = createOr(psi_i_part2_components, pub_aig_manager); psi_i_part2 = createNot(psi_i_part2, pub_aig_manager); } assert(psi_i_part2 != NULL); // initialize Z_variable_counter[var_to_elim_index] to 0 Z_variable_counter.insert(make_pair(var_to_elim_index, 0)); int z_i_count = Z_variable_counter[var_to_elim_index]; // 0 here string z_i_string = obtainZVariableString(var_to_elim_index, z_i_count); // obtain the string Z_{var_to_elim_index}_0 // check if object for z_i_string is already existing; if yes return it; otherwise create, // update temporary_variable_for_incremental_solving_to_object_map and return Aig_Obj_t* z_i_object = obtainObjectOfTemporaryVariableForIncrementalSolving(z_i_string); assert(z_i_object != NULL); psi_i_part2 = createAnd(psi_i_part2, z_i_object, pub_aig_manager); assert(psi_i_part2 != NULL); // obtaining \psi_i_part1 Aig_Obj_t* psi_i_part1; map::iterator initial_cannot_be_zero_objects_it = initial_cannot_be_zero_objects.find(var_to_elim_index); assert(initial_cannot_be_zero_objects_it != initial_cannot_be_zero_objects.end()); psi_i_part1 = initial_cannot_be_zero_objects_it->second; assert(psi_i_part1 != NULL); // obtaining \psi_i Aig_Obj_t* psi_i; psi_i = createOr(createAnd(use_cbzero_in_unified_cegar_aig, psi_i_part1, pub_aig_manager), psi_i_part2, pub_aig_manager); assert(psi_i != NULL); Aig_Obj_t* S_equivalence_i = createEquivalence(var_to_elim_obj, psi_i, pub_aig_manager); if(true) //var_to_elim_index > 1 is sufficeint; but may need code change { S_equivalence_objects.insert(S_equivalence_i); } } if(apply_tsietin_encoding_on_benchmarks) { for(int tsietin_location_index = 1; tsietin_location_index <= number_of_tsietin_variables; tsietin_location_index++) { // obtaining dag for x_i string var_to_elim = searchVarIndexToVarNameMap(var_index_to_var_name_map, tsietin_location_index); map::iterator Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it = Ci_to_eliminate_name_to_Ci_to_eliminate_object_map.find(var_to_elim); assert(Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it != Ci_to_eliminate_name_to_Ci_to_eliminate_object_map.end()); Aig_Obj_t* var_to_elim_obj = Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it->second; // obtaining \psi_i Aig_Obj_t* psi_i; map::iterator tsietin_variable_to_exact_skolem_function_map_it = tsietin_variable_to_exact_skolem_function_map.find(var_to_elim); assert(tsietin_variable_to_exact_skolem_function_map_it != tsietin_variable_to_exact_skolem_function_map.end()); psi_i = tsietin_variable_to_exact_skolem_function_map_it->second; assert(psi_i != NULL); Aig_Obj_t* S_equivalence_i = createEquivalence(var_to_elim_obj, psi_i, pub_aig_manager); S_equivalence_objects.insert(S_equivalence_i); #ifdef DEBUG_SKOLEM cout << endl << "Exact Skolem function used for x[" << tsietin_location_index << "] = " << var_to_elim << endl; #endif } } if(S_equivalence_objects.empty()) { S_equivalence_part = createTrue(pub_aig_manager); } else { S_equivalence_part = createAnd(S_equivalence_objects, pub_aig_manager); } assert(S_equivalence_part != NULL); // connect to some output to avoid unwanted deletion Aig_Obj_t* S_equivalence_part_CO = Aig_ObjCreateCo(pub_aig_manager, S_equivalence_part ); assert(S_equivalence_part_CO != NULL); // Let's create dag for // (B_1 = dag for bad_1) \wedge ... \wedge (B_{i} = dag for bad_{i}) // We need to exclude Tsietin variables if apply_tsietin_encoding_on_benchmarks is true Aig_Obj_t* B_equivalence_part; set B_equivalence_objects; Aig_Obj_t* B_part; set B_objects; for(int bad_location_index = 1; bad_location_index <= number_of_vars_to_elim; bad_location_index++) { if(apply_tsietin_encoding_on_benchmarks) { if(bad_location_index <= number_of_tsietin_variables) { #ifdef DEBUG_SKOLEM cout << endl << bad_location_index << " <= " << number_of_tsietin_variables <<", hence exact Skolem fuctions to be used\n"; #endif continue; // no need to add bads for these locations; Skolem functions already exact } } Aig_Obj_t* bad_set_obj; bad_set_obj = searchOneDimensionalMatrix(BadSets, number_of_vars_to_elim, bad_location_index); assert(bad_set_obj != NULL); // Obtaining dag for bad_set_obj map::iterator B_i_index_to_B_i_object_map_iterator = B_i_index_to_B_i_object_map.find(bad_location_index); assert(B_i_index_to_B_i_object_map_iterator != B_i_index_to_B_i_object_map.end()); Aig_Obj_t* B_obj = B_i_index_to_B_i_object_map_iterator->second; assert(B_obj != NULL); B_objects.insert(B_obj); Aig_Obj_t* B_equivalence_i = createEquivalence(bad_set_obj, B_obj, pub_aig_manager); B_equivalence_objects.insert(B_equivalence_i); } assert(!B_equivalence_objects.empty()); B_equivalence_part = createAnd(B_equivalence_objects, pub_aig_manager); assert(B_equivalence_part != NULL); // connect to some output to avoid unwanted deletion Aig_Obj_t* B_equivalence_part_CO = Aig_ObjCreateCo(pub_aig_manager, B_equivalence_part ); assert(B_equivalence_part_CO != NULL); Aig_Obj_t* negated_conjunction_of_factors = createNot(conjunction_of_factors, pub_aig_manager); assert(negated_conjunction_of_factors != NULL); // create aig for ite(use_bads_in_unified_cegar_aig, B_equivalence_part wedge disjunction_of_bad_symbols, negated_conjunction_of_factors) Aig_Obj_t* prevention_part; prevention_part = createIte(use_bads_in_unified_cegar_aig, createAnd(B_equivalence_part, disjunction_of_bad_symbols, pub_aig_manager), negated_conjunction_of_factors, pub_aig_manager); // connect to some output to avoid unwanted deletion Aig_Obj_t* prevention_part_CO = Aig_ObjCreateCo(pub_aig_manager, prevention_part ); assert(prevention_part_CO != NULL); #ifdef DEBUG_SKOLEM string Cb_part_file_name = benchmark_name_without_extension; Cb_part_file_name += "_Cb_part"; string S_equivalence_part_file_name = benchmark_name_without_extension; S_equivalence_part_file_name += "_S_equivalence_part"; string B_equivalence_part_file_name = benchmark_name_without_extension; B_equivalence_part_file_name += "_B_equivalence_part"; string prevention_part_file_name = benchmark_name_without_extension; prevention_part_file_name += "_prevention_part"; cout << "\nCb_part computed\n"; cout << "\nS_equivalence_part computed\n"; cout << "\nB_equivalence_part computed\n"; cout << "\nprevention_part computed\n"; writeFormulaToFile(pub_aig_manager, Cb_part, Cb_part_file_name, ".v", cegar_iteration_number, 0); writeFormulaToFile(pub_aig_manager, S_equivalence_part, S_equivalence_part_file_name, ".v", cegar_iteration_number, 0); writeFormulaToFile(pub_aig_manager, B_equivalence_part, B_equivalence_part_file_name, ".v", cegar_iteration_number, 0); writeFormulaToFile(pub_aig_manager, prevention_part, prevention_part_file_name, ".v", cegar_iteration_number, 0); #endif set epsilon_zero_objects; epsilon_zero_objects.insert(Cb_part); epsilon_zero_objects.insert(S_equivalence_part); epsilon_zero_objects.insert(prevention_part); epsilon_zero_objects.insert(renamed_conjunction_of_factors); epsilon_zero = createAnd(epsilon_zero_objects, pub_aig_manager); assert(epsilon_zero != NULL); // connect to some output to avoid unwanted deletion Aig_Obj_t* epsilon_zero_CO = Aig_ObjCreateCo(pub_aig_manager, epsilon_zero ); assert(epsilon_zero_CO != NULL); if(Aig_IsComplement(epsilon_zero) && Aig_Regular(epsilon_zero) == createTrue(pub_aig_manager)) // epsilon_zero is false { #ifdef DEBUG_CEGAR cout << "\nAIG for epsilon_zero is false; no need to call the sat-solver\n"; #endif #ifdef RECORD_KEEP number_of_exactness_checking_in_cegar++; fprintf(record_fp, "\t0(0,0)(1)"); fclose(record_fp); #endif return true; } vector positive_assumptions_in_exactness_check; vector negative_assumptions_in_exactness_check; obtainAssumptionsInExactnessCheck_using_Generic_Skolem_Functions_With_Unified_Code_And_Incremental_Solving(correction_index, positive_assumptions_in_exactness_check, negative_assumptions_in_exactness_check); assert(positive_assumptions_in_exactness_check.size() != 0); if(assumptions_flag == 0) { assert(negative_assumptions_in_exactness_check.size() == 0); } else if(assumptions_flag == 1) { assert(negative_assumptions_in_exactness_check.size() == 1); } else { assert(false); } // Use incremental solver call #ifdef DEBUG_CEGAR string epsilon_zero_file_name = benchmark_name_without_extension; epsilon_zero_file_name += "_epsilon_zero"; cout << "\nepsilon_zero computed\n"; writeFormulaToFile(pub_aig_manager, epsilon_zero, epsilon_zero_file_name, ".v", cegar_iteration_number, 0); cout << endl << "Adding clauses of epsilon_zero to SAT-Solver, and calling SAT-Solver\n"; #endif #ifdef DETAILED_RECORD_KEEP unsigned long long int solver_ms; struct timeval solver_start_ms, solver_finish_ms; gettimeofday (&solver_start_ms, NULL); #endif // Give to SAT-Solver and get unsat / sat with model unsigned long long int cnf_time; int formula_size; unsigned long long int simplification_time; bool result_of_exactnesscheck = isExactnessCheckSatisfiable(pub_aig_manager, epsilon_zero, Model_of_ExactnessCheck, cnf_time, formula_size, simplification_time, positive_assumptions_in_exactness_check, negative_assumptions_in_exactness_check, pSat_for_exactness_check, IncrementalLabelTableForExactnessCheck, IncrementalLabelCountForExactnessCheck, Ci_name_to_Ci_label_mapForExactnessCheck, Ci_label_to_Ci_name_mapForExactnessCheck); #ifdef DETAILED_RECORD_KEEP gettimeofday (&solver_finish_ms, NULL); solver_ms = solver_finish_ms.tv_sec * 1000 + solver_finish_ms.tv_usec / 1000; solver_ms -= solver_start_ms.tv_sec * 1000 + solver_start_ms.tv_usec / 1000; cout << "\nsolver finished in " << solver_ms << " milliseconds\n"; total_time_in_smt_solver = total_time_in_smt_solver + solver_ms; total_time_in_exactness_checking_in_cegar = total_time_in_exactness_checking_in_cegar + solver_ms; number_of_exactness_checking_in_cegar++; #endif #ifdef RECORD_KEEP fprintf(record_fp, "\t%llu(%llu,%llu)(%d)", solver_ms, cnf_time, simplification_time, formula_size); fclose(record_fp); #endif #ifdef DEBUG_SKOLEM displayModelFromSATSolver(Model_of_ExactnessCheck); cout << endl << "result_of_exactnesscheck = " << result_of_exactnesscheck << endl; #endif removeTemporaryVariablesFromModel(Model_of_ExactnessCheck); #ifdef DEBUG_CEGAR cout << "\nModel after removing temporary variables\n"; displayModelFromSATSolver(Model_of_ExactnessCheck); cout << endl << "result_of_exactnesscheck = " << result_of_exactnesscheck << endl; #endif if(!result_of_exactnesscheck) // ExactnessCheck unsat i.e. skolem function at correction_index is exact { return true; } else // skolem function at correction_index is inexact { return false; } } // if(cegar_iteration_number == 0) ends here else if(cegar_iteration_for_correction_index == 0) { #ifdef DEBUG_CEGAR cout << "\nCase with cegar_iteration_for_correction_index == 0 \n"; #endif assert(correction_index < number_of_vars_to_elim); Aig_Obj_t* delta_epsilon_i; int corrected_index = correction_index + 1; // obtaining object for x_{corrected_index} string var_to_elim = searchVarIndexToVarNameMap(var_index_to_var_name_map, corrected_index); map::iterator Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it = Ci_to_eliminate_name_to_Ci_to_eliminate_object_map.find(var_to_elim); assert(Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it != Ci_to_eliminate_name_to_Ci_to_eliminate_object_map.end()); Aig_Obj_t* var_to_elim_obj = Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it->second; assert(var_to_elim_obj != NULL); // obtaining dag for x_{corrected_index}' map::iterator Ci_to_eliminate_renamed_to_Ci_to_eliminate_renamed_object_map_it = Ci_to_eliminate_renamed_to_Ci_to_eliminate_renamed_object_map.find(corrected_index); assert(Ci_to_eliminate_renamed_to_Ci_to_eliminate_renamed_object_map_it != Ci_to_eliminate_renamed_to_Ci_to_eliminate_renamed_object_map.end()); Aig_Obj_t* var_to_elim_renamed_obj = Ci_to_eliminate_renamed_to_Ci_to_eliminate_renamed_object_map_it->second; assert(var_to_elim_renamed_obj != NULL); // creating (x_{corrected_index} = x_{corrected_index}') Aig_Obj_t* x_equivalence = createEquivalence(var_to_elim_obj, var_to_elim_renamed_obj, pub_aig_manager); assert(x_equivalence != NULL); // connect to some output to avoid unwanted deletion Aig_Obj_t* x_equivalence_CO = Aig_ObjCreateCo(pub_aig_manager, x_equivalence ); assert(x_equivalence_CO != NULL); #ifdef DEBUG_SKOLEM string x_equivalence_file_name = benchmark_name_without_extension; x_equivalence_file_name += "_x_equivalence"; cout << "\nx_equivalence computed\n"; writeFormulaToFile(pub_aig_manager, x_equivalence, x_equivalence_file_name, ".v", cegar_iteration_number, 0); #endif if(allow_intermediate_generic_sat_calls) { // There can be hints; incorporate them if(!Refinement_Hint_Of_CannotBe_One_To_Eliminate_This_CEX.empty() || !Refinement_Hint_Of_CannotBe_Zero_To_Eliminate_This_CEX.empty()) { Aig_Obj_t* Cb_part; set Cb_objects; Aig_Obj_t* Z_part; set Z_objects; for(map::iterator hint_it = Refinement_Hint_Of_CannotBe_One_To_Eliminate_This_CEX.begin(); hint_it != Refinement_Hint_Of_CannotBe_One_To_Eliminate_This_CEX.end(); hint_it++) { int destination = hint_it->first; Aig_Obj_t* new_cannot_be_one_object_at_destination = hint_it->second; map::iterator cannot_be_object_to_cannot_be_dag_map_it = cannot_be_object_to_cannot_be_dag_map.find(new_cannot_be_one_object_at_destination); assert(cannot_be_object_to_cannot_be_dag_map_it != cannot_be_object_to_cannot_be_dag_map.end()); Aig_Obj_t* new_cannot_be_one_dag_at_destination = cannot_be_object_to_cannot_be_dag_map_it->second; Aig_Obj_t* Cb_one_equivalence = createEquivalence(new_cannot_be_one_object_at_destination, new_cannot_be_one_dag_at_destination, pub_aig_manager); assert(Cb_one_equivalence != NULL); Cb_objects.insert(Cb_one_equivalence); int present_z_j_k_count = Z_variable_counter[destination]; int next_z_j_k_count = present_z_j_k_count + 1; Z_variable_counter[destination] = next_z_j_k_count; string present_z_j_k_string = obtainZVariableString(destination, present_z_j_k_count); // obtain the string Z_{destination}_{present_z_j_k_count} Aig_Obj_t* present_z_j_k_object = obtainExistingObjectOfTemporaryVariableForIncrementalSolving(present_z_j_k_string); assert(present_z_j_k_object != NULL); string next_z_j_k_string = obtainZVariableString(destination, next_z_j_k_count); // obtain the string Z_{destination}_{next_z_j_k_count} Aig_Obj_t* next_z_j_k_object = obtainObjectOfTemporaryVariableForIncrementalSolving(next_z_j_k_string); assert(next_z_j_k_object != NULL); Aig_Obj_t* R_i_j_increment = createEquivalence(present_z_j_k_object, createAnd(createNot(new_cannot_be_one_object_at_destination, pub_aig_manager), next_z_j_k_object, pub_aig_manager), pub_aig_manager); assert(R_i_j_increment != NULL); Z_objects.insert(R_i_j_increment); } for(map::iterator hint_it = Refinement_Hint_Of_CannotBe_Zero_To_Eliminate_This_CEX.begin(); hint_it != Refinement_Hint_Of_CannotBe_Zero_To_Eliminate_This_CEX.end(); hint_it++) { int destination = hint_it->first; Aig_Obj_t* new_cannot_be_zero_object_at_destination = hint_it->second; map::iterator cannot_be_object_to_cannot_be_dag_map_it = cannot_be_object_to_cannot_be_dag_map.find(new_cannot_be_zero_object_at_destination); assert(cannot_be_object_to_cannot_be_dag_map_it != cannot_be_object_to_cannot_be_dag_map.end()); Aig_Obj_t* new_cannot_be_zero_dag_at_destination = cannot_be_object_to_cannot_be_dag_map_it->second; Aig_Obj_t* Cb_zero_equivalence = createEquivalence(new_cannot_be_zero_object_at_destination, new_cannot_be_zero_dag_at_destination, pub_aig_manager); assert(Cb_zero_equivalence != NULL); Cb_objects.insert(Cb_zero_equivalence); } if(Cb_objects.empty() && Z_objects.empty()) { delta_epsilon_i = createTrue(pub_aig_manager); } else { assert(!Cb_objects.empty()); Cb_part = createAnd(Cb_objects, pub_aig_manager); assert(Cb_part != NULL); // connect to some output to avoid unwanted deletion Aig_Obj_t* Cb_part_CO = Aig_ObjCreateCo(pub_aig_manager, Cb_part ); assert(Cb_part_CO != NULL); assert(!Z_objects.empty()); Z_part = createAnd(Z_objects, pub_aig_manager); assert(Z_part != NULL); // connect to some output to avoid unwanted deletion Aig_Obj_t* Z_part_CO = Aig_ObjCreateCo(pub_aig_manager, Z_part ); assert(Z_part_CO != NULL); #ifdef DEBUG_SKOLEM string Cb_part_file_name = benchmark_name_without_extension; Cb_part_file_name += "_Cb_part"; string Z_part_file_name = benchmark_name_without_extension; Z_part_file_name += "_Z_part"; cout << "\nCb_part computed\n"; cout << "\nZ_part computed\n"; writeFormulaToFile(pub_aig_manager, Cb_part, Cb_part_file_name, ".v", cegar_iteration_number, 0); writeFormulaToFile(pub_aig_manager, Z_part, Z_part_file_name, ".v", cegar_iteration_number, 0); #endif delta_epsilon_i = createAnd(Cb_part, Z_part, pub_aig_manager); } }// There are hints ends here else { delta_epsilon_i = createTrue(pub_aig_manager); }// No hints delta_epsilon_i = createAnd(delta_epsilon_i, x_equivalence, pub_aig_manager); } else { assert(Refinement_Hint_Of_CannotBe_One_To_Eliminate_This_CEX.empty() && Refinement_Hint_Of_CannotBe_Zero_To_Eliminate_This_CEX.empty()); delta_epsilon_i = x_equivalence; } assert(delta_epsilon_i != NULL); // connect to some output to avoid unwanted deletion Aig_Obj_t* delta_epsilon_i_CO = Aig_ObjCreateCo(pub_aig_manager, delta_epsilon_i ); assert(delta_epsilon_i_CO != NULL); #ifdef DEBUG_CEGAR string delta_epsilon_i_file_name = benchmark_name_without_extension; delta_epsilon_i_file_name += "_delta_epsilon_i"; cout << "\ndelta_epsilon_i computed\n"; writeFormulaToFile(pub_aig_manager, delta_epsilon_i, delta_epsilon_i_file_name, ".v", cegar_iteration_number, 0); cout << endl << "Adding clauses of delta_epsilon_i to SAT-Solver, and calling SAT-Solver\n"; #endif vector positive_assumptions_in_exactness_check; vector negative_assumptions_in_exactness_check; obtainAssumptionsInExactnessCheck_using_Generic_Skolem_Functions_With_Unified_Code_And_Incremental_Solving(correction_index, positive_assumptions_in_exactness_check, negative_assumptions_in_exactness_check); //assert(positive_assumptions_in_exactness_check.size() != 0); //assert(negative_assumptions_in_exactness_check.size() != 0); // Use incremental solver call #ifdef DEBUG_CEGAR cout << endl << "Adding clauses of delta_epsilon_i to SAT-Solver, and calling SAT-Solver\n"; #endif #ifdef DETAILED_RECORD_KEEP unsigned long long int solver_ms; struct timeval solver_start_ms, solver_finish_ms; gettimeofday (&solver_start_ms, NULL); #endif // Give to SAT-Solver and get unsat / sat with model unsigned long long int cnf_time; int formula_size; unsigned long long int simplification_time; bool result_of_exactnesscheck = isExactnessCheckSatisfiable(pub_aig_manager, delta_epsilon_i, Model_of_ExactnessCheck, cnf_time, formula_size, simplification_time, positive_assumptions_in_exactness_check, negative_assumptions_in_exactness_check, pSat_for_exactness_check, IncrementalLabelTableForExactnessCheck, IncrementalLabelCountForExactnessCheck, Ci_name_to_Ci_label_mapForExactnessCheck, Ci_label_to_Ci_name_mapForExactnessCheck); #ifdef DETAILED_RECORD_KEEP gettimeofday (&solver_finish_ms, NULL); solver_ms = solver_finish_ms.tv_sec * 1000 + solver_finish_ms.tv_usec / 1000; solver_ms -= solver_start_ms.tv_sec * 1000 + solver_start_ms.tv_usec / 1000; cout << "\nsolver finished in " << solver_ms << " milliseconds\n"; total_time_in_smt_solver = total_time_in_smt_solver + solver_ms; total_time_in_exactness_checking_in_cegar = total_time_in_exactness_checking_in_cegar + solver_ms; number_of_exactness_checking_in_cegar++; #endif #ifdef RECORD_KEEP fprintf(record_fp, "\t%llu(%llu,%llu)(%d)", solver_ms, cnf_time, simplification_time, formula_size); fclose(record_fp); #endif #ifdef DEBUG_SKOLEM displayModelFromSATSolver(Model_of_ExactnessCheck); cout << endl << "result_of_exactnesscheck = " << result_of_exactnesscheck << endl; #endif removeTemporaryVariablesFromModel(Model_of_ExactnessCheck); #ifdef DEBUG_CEGAR cout << "\nModel after removing temporary variables\n"; displayModelFromSATSolver(Model_of_ExactnessCheck); cout << endl << "result_of_exactnesscheck = " << result_of_exactnesscheck << endl; #endif if(!result_of_exactnesscheck) // ExactnessCheck unsat i.e. skolem function at correction_index is exact { return true; } else // skolem function at correction_index is inexact { return false; } }// if(cegar_iteration_for_correction_index == 0) ends here else // if(cegar_iteration_for_correction_index > 0) { #ifdef DEBUG_CEGAR cout << "\nCase with cegar_iteration_for_correction_index > 0 \n"; if(Refinement_Hint_Of_CannotBe_One_To_Eliminate_This_CEX.empty() && Refinement_Hint_Of_CannotBe_Zero_To_Eliminate_This_CEX.empty()) { cout << "\nRefinement hints are empty\n"; } else { cout << "\nRefinement hints are NOT empty\n"; } #endif #ifdef DEBUG_CEGAR show_present_refinement_hint(Refinement_Hint_Of_CannotBe_One_To_Eliminate_This_CEX, Refinement_Hint_Of_CannotBe_Zero_To_Eliminate_This_CEX); #endif Aig_Obj_t* delta_epsilon_i; // Create the dag for delta_epsilon_i: // for each o_j added in Refinement_Hint_Of_CannotBe_One_To_Eliminate_This_CEX // (o_j = dag_j) \wedge // (Z_i_k = Z_i_{k+1} \wedge o_j) \wedge Aig_Obj_t* Cb_part; set Cb_objects; Aig_Obj_t* Z_part; set Z_objects; for(map::iterator hint_it = Refinement_Hint_Of_CannotBe_One_To_Eliminate_This_CEX.begin(); hint_it != Refinement_Hint_Of_CannotBe_One_To_Eliminate_This_CEX.end(); hint_it++) { int destination = hint_it->first; Aig_Obj_t* new_cannot_be_one_object_at_destination = hint_it->second; map::iterator cannot_be_object_to_cannot_be_dag_map_it = cannot_be_object_to_cannot_be_dag_map.find(new_cannot_be_one_object_at_destination); assert(cannot_be_object_to_cannot_be_dag_map_it != cannot_be_object_to_cannot_be_dag_map.end()); Aig_Obj_t* new_cannot_be_one_dag_at_destination = cannot_be_object_to_cannot_be_dag_map_it->second; Aig_Obj_t* Cb_one_equivalence = createEquivalence(new_cannot_be_one_object_at_destination, new_cannot_be_one_dag_at_destination, pub_aig_manager); assert(Cb_one_equivalence != NULL); Cb_objects.insert(Cb_one_equivalence); int present_z_j_k_count = Z_variable_counter[destination]; int next_z_j_k_count = present_z_j_k_count + 1; Z_variable_counter[destination] = next_z_j_k_count; string present_z_j_k_string = obtainZVariableString(destination, present_z_j_k_count); // obtain the string Z_{destination}_{present_z_j_k_count} Aig_Obj_t* present_z_j_k_object = obtainExistingObjectOfTemporaryVariableForIncrementalSolving(present_z_j_k_string); assert(present_z_j_k_object != NULL); string next_z_j_k_string = obtainZVariableString(destination, next_z_j_k_count); // obtain the string Z_{destination}_{next_z_j_k_count} Aig_Obj_t* next_z_j_k_object = obtainObjectOfTemporaryVariableForIncrementalSolving(next_z_j_k_string); assert(next_z_j_k_object != NULL); Aig_Obj_t* R_i_j_increment = createEquivalence(present_z_j_k_object, createAnd(createNot(new_cannot_be_one_object_at_destination, pub_aig_manager), next_z_j_k_object, pub_aig_manager), pub_aig_manager); assert(R_i_j_increment != NULL); Z_objects.insert(R_i_j_increment); } for(map::iterator hint_it = Refinement_Hint_Of_CannotBe_Zero_To_Eliminate_This_CEX.begin(); hint_it != Refinement_Hint_Of_CannotBe_Zero_To_Eliminate_This_CEX.end(); hint_it++) { int destination = hint_it->first; Aig_Obj_t* new_cannot_be_zero_object_at_destination = hint_it->second; map::iterator cannot_be_object_to_cannot_be_dag_map_it = cannot_be_object_to_cannot_be_dag_map.find(new_cannot_be_zero_object_at_destination); assert(cannot_be_object_to_cannot_be_dag_map_it != cannot_be_object_to_cannot_be_dag_map.end()); Aig_Obj_t* new_cannot_be_zero_dag_at_destination = cannot_be_object_to_cannot_be_dag_map_it->second; Aig_Obj_t* Cb_zero_equivalence = createEquivalence(new_cannot_be_zero_object_at_destination, new_cannot_be_zero_dag_at_destination, pub_aig_manager); assert(Cb_zero_equivalence != NULL); Cb_objects.insert(Cb_zero_equivalence); } if(Cb_objects.empty() && Z_objects.empty()) { delta_epsilon_i = createTrue(pub_aig_manager); } else { assert(!Cb_objects.empty()); Cb_part = createAnd(Cb_objects, pub_aig_manager); assert(Cb_part != NULL); // connect to some output to avoid unwanted deletion Aig_Obj_t* Cb_part_CO = Aig_ObjCreateCo(pub_aig_manager, Cb_part ); assert(Cb_part_CO != NULL); assert(!Z_objects.empty()); Z_part = createAnd(Z_objects, pub_aig_manager); assert(Z_part != NULL); // connect to some output to avoid unwanted deletion Aig_Obj_t* Z_part_CO = Aig_ObjCreateCo(pub_aig_manager, Z_part ); assert(Z_part_CO != NULL); #ifdef DEBUG_SKOLEM string Cb_part_file_name = benchmark_name_without_extension; Cb_part_file_name += "_Cb_part"; string Z_part_file_name = benchmark_name_without_extension; Z_part_file_name += "_Z_part"; cout << "\nCb_part computed\n"; cout << "\nZ_part computed\n"; writeFormulaToFile(pub_aig_manager, Cb_part, Cb_part_file_name, ".v", cegar_iteration_number, 0); writeFormulaToFile(pub_aig_manager, Z_part, Z_part_file_name, ".v", cegar_iteration_number, 0); #endif delta_epsilon_i = createAnd(Cb_part, Z_part, pub_aig_manager); } assert(delta_epsilon_i != NULL); // connect to some output to avoid unwanted deletion Aig_Obj_t* delta_epsilon_i_CO = Aig_ObjCreateCo(pub_aig_manager, delta_epsilon_i ); assert(delta_epsilon_i_CO != NULL); #ifdef DEBUG_CEGAR string delta_epsilon_i_file_name = benchmark_name_without_extension; delta_epsilon_i_file_name += "_delta_epsilon_i"; cout << "\ndelta_epsilon_i computed\n"; writeFormulaToFile(pub_aig_manager, delta_epsilon_i, delta_epsilon_i_file_name, ".v", cegar_iteration_number, 0); cout << endl << "Adding clauses of delta_epsilon_i to SAT-Solver, and calling SAT-Solver\n"; #endif vector positive_assumptions_in_exactness_check; vector negative_assumptions_in_exactness_check; obtainAssumptionsInExactnessCheck_using_Generic_Skolem_Functions_With_Unified_Code_And_Incremental_Solving(correction_index, positive_assumptions_in_exactness_check, negative_assumptions_in_exactness_check); //assert(positive_assumptions_in_exactness_check.size() != 0); //assert(negative_assumptions_in_exactness_check.size() != 0); // Use incremental solver call #ifdef DEBUG_CEGAR cout << endl << "Adding clauses of delta_epsilon_i to SAT-Solver, and calling SAT-Solver\n"; #endif #ifdef DETAILED_RECORD_KEEP unsigned long long int solver_ms; struct timeval solver_start_ms, solver_finish_ms; gettimeofday (&solver_start_ms, NULL); #endif // Give to SAT-Solver and get unsat / sat with model unsigned long long int cnf_time; int formula_size; unsigned long long int simplification_time; bool result_of_exactnesscheck = isExactnessCheckSatisfiable(pub_aig_manager, delta_epsilon_i, Model_of_ExactnessCheck, cnf_time, formula_size, simplification_time, positive_assumptions_in_exactness_check, negative_assumptions_in_exactness_check, pSat_for_exactness_check, IncrementalLabelTableForExactnessCheck, IncrementalLabelCountForExactnessCheck, Ci_name_to_Ci_label_mapForExactnessCheck, Ci_label_to_Ci_name_mapForExactnessCheck); #ifdef DETAILED_RECORD_KEEP gettimeofday (&solver_finish_ms, NULL); solver_ms = solver_finish_ms.tv_sec * 1000 + solver_finish_ms.tv_usec / 1000; solver_ms -= solver_start_ms.tv_sec * 1000 + solver_start_ms.tv_usec / 1000; cout << "\nsolver finished in " << solver_ms << " milliseconds\n"; total_time_in_smt_solver = total_time_in_smt_solver + solver_ms; total_time_in_exactness_checking_in_cegar = total_time_in_exactness_checking_in_cegar + solver_ms; number_of_exactness_checking_in_cegar++; #endif #ifdef RECORD_KEEP fprintf(record_fp, "\t%llu(%llu,%llu)(%d)", solver_ms, cnf_time, simplification_time, formula_size); fclose(record_fp); #endif #ifdef DEBUG_SKOLEM displayModelFromSATSolver(Model_of_ExactnessCheck); cout << endl << "result_of_exactnesscheck = " << result_of_exactnesscheck << endl; #endif removeTemporaryVariablesFromModel(Model_of_ExactnessCheck); #ifdef DEBUG_CEGAR cout << "\nModel after removing temporary variables\n"; displayModelFromSATSolver(Model_of_ExactnessCheck); cout << endl << "result_of_exactnesscheck = " << result_of_exactnesscheck << endl; #endif if(!result_of_exactnesscheck) // ExactnessCheck unsat i.e. skolem function at correction_index is exact { return true; } else // skolem function at correction_index is inexact { return false; } } // if(cegar_iteration_for_correction_index > 0) ends here } void AIGBasedSkolem::obtainAssumptionsInExactnessCheck_using_Generic_Skolem_Functions_With_Unified_Code_And_Incremental_Solving(int correction_index, vector &positive_assumptions_in_exactness_check, vector &negative_assumptions_in_exactness_check) { // positive_assumptions_in_exactness_check includes // Z_i_j for each i = variable_to_eliminate and j = Z_variable_counter[i] for(int var_to_elim_index = 1; var_to_elim_index <= number_of_vars_to_elim; var_to_elim_index++) { if(apply_tsietin_encoding_on_benchmarks) { if(var_to_elim_index <= number_of_tsietin_variables) { #ifdef DEBUG_SKOLEM cout << endl << var_to_elim_index << " <= " << number_of_tsietin_variables <<", hence exact Skolem fuctions to be used\n"; #endif continue; // no need to add abstract Skolem functions } } map::iterator Z_variable_counter_it = Z_variable_counter.find(var_to_elim_index); assert(Z_variable_counter_it != Z_variable_counter.end()); int z_i_count = Z_variable_counter_it->second; string z_i_string = obtainZVariableString(var_to_elim_index, z_i_count); // obtain the string Z_{var_to_elim_index}_{z_i_count} Aig_Obj_t* z_i_object = obtainExistingObjectOfTemporaryVariableForIncrementalSolving(z_i_string); assert(z_i_object != NULL); positive_assumptions_in_exactness_check.push_back(z_i_object); } if(assumptions_flag == 1) { // obtaining dag for x_{correction_index} string var_to_elim = searchVarIndexToVarNameMap(var_index_to_var_name_map, correction_index); map::iterator Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it = Ci_to_eliminate_name_to_Ci_to_eliminate_object_map.find(var_to_elim); assert(Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it != Ci_to_eliminate_name_to_Ci_to_eliminate_object_map.end()); Aig_Obj_t* var_to_elim_obj = Ci_to_eliminate_name_to_Ci_to_eliminate_object_map_it->second; assert(var_to_elim_obj != NULL); positive_assumptions_in_exactness_check.push_back(var_to_elim_obj); // obtaining dag for x_{correction_index}' map::iterator Ci_to_eliminate_renamed_to_Ci_to_eliminate_renamed_object_map_it = Ci_to_eliminate_renamed_to_Ci_to_eliminate_renamed_object_map.find(correction_index); assert(Ci_to_eliminate_renamed_to_Ci_to_eliminate_renamed_object_map_it != Ci_to_eliminate_renamed_to_Ci_to_eliminate_renamed_object_map.end()); Aig_Obj_t* var_to_elim_renamed_obj = Ci_to_eliminate_renamed_to_Ci_to_eliminate_renamed_object_map_it->second; assert(var_to_elim_renamed_obj != NULL); negative_assumptions_in_exactness_check.push_back(var_to_elim_renamed_obj); if(use_bads_in_unified_cegar == 1) { bool use_support_based_bad_exclusion = true; if(use_support_based_bad_exclusion) { if(correction_index < number_of_vars_to_elim) { map >::iterator bads_to_exclude_it = bads_to_exclude.find(correction_index); set bads_to_exclude_for_correction_index = bads_to_exclude_it->second; for(set::iterator bads_to_exclude_for_correction_index_it = bads_to_exclude_for_correction_index.begin(); bads_to_exclude_for_correction_index_it != bads_to_exclude_for_correction_index.end(); bads_to_exclude_for_correction_index_it++) { int bad_index = *bads_to_exclude_for_correction_index_it; map::iterator B_i_index_to_B_i_object_map_iterator = B_i_index_to_B_i_object_map.find(bad_index); assert(B_i_index_to_B_i_object_map_iterator != B_i_index_to_B_i_object_map.end()); Aig_Obj_t* B_obj = B_i_index_to_B_i_object_map_iterator->second; assert(B_obj != NULL); negative_assumptions_in_exactness_check.push_back(B_obj); } } } else { for(int var_to_elim_index = number_of_vars_to_elim; var_to_elim_index >= correction_index+1; var_to_elim_index--) { map::iterator B_i_index_to_B_i_object_map_iterator = B_i_index_to_B_i_object_map.find(var_to_elim_index); assert(B_i_index_to_B_i_object_map_iterator != B_i_index_to_B_i_object_map.end()); Aig_Obj_t* B_obj = B_i_index_to_B_i_object_map_iterator->second; assert(B_obj != NULL); negative_assumptions_in_exactness_check.push_back(B_obj); } } }//if(use_bads_in_unified_cegar == 1) ends here }//if(assumptions_flag == 1) ends here } void AIGBasedSkolem::generateSkolemFunctionsForGameBenchmarks(set &original_factors, vector< list > &VariablesToEliminateForGameBenchmarks, char TypeOfInnerQuantifier) { assert(!original_factors.empty()); assert(TypeOfInnerQuantifier == 'e' || TypeOfInnerQuantifier == 'u'); assert(VariablesToEliminateForGameBenchmarks.size() > 0); Aig_Obj_t* present_formula = createAnd(original_factors, pub_aig_manager); assert(present_formula != NULL); Aig_Obj_t* present_formula_CO = Aig_ObjCreateCo( pub_aig_manager, present_formula ); // to aviod // unwanted cleanup of present_formula assert(present_formula_CO != NULL); for(int quantifier_block = 0; quantifier_block < VariablesToEliminateForGameBenchmarks.size(); quantifier_block++) { char TypeOfQuantifier; if(quantifier_block % 2 == 0) { TypeOfQuantifier = TypeOfInnerQuantifier; } else { if(TypeOfInnerQuantifier == 'e') { TypeOfQuantifier = 'a'; } else { TypeOfQuantifier = 'e'; } } list VariablesToEliminate = VariablesToEliminateForGameBenchmarks[quantifier_block]; if(TypeOfQuantifier == 'a') { // present_formula should become \neg present_formula present_formula = createNot(present_formula, pub_aig_manager); } set Factors; Factors.clear(); // obtain factors by factorizing the present_formula andFlattening(present_formula, Factors); assert(Factors.size() > 0); recreateCiMaps(VariablesToEliminate); #ifdef DEBUG_SKOLEM cout << "\nCalling Skolem function generator for quantifier block " << TypeOfQuantifier << "_" << quantifier_block << endl; cout << "\nFactors\n"; int factor_index = 1; for(set::iterator Factors_it = Factors.begin(); Factors_it != Factors.end(); Factors_it++) { writeFormulaToFile(pub_aig_manager, *Factors_it, "game_factor", ".v", quantifier_block, factor_index); factor_index++; } cout << "\nVariablesToEliminate\n"; showList(VariablesToEliminate); #endif map variable_to_skolem_function_map; variable_to_skolem_function_map.clear(); obtainSkolemFunctionsInGameBenchmarks(Factors, VariablesToEliminate, variable_to_skolem_function_map, quantifier_block, TypeOfQuantifier); #ifdef DEBUG_SKOLEM cout << "\nSkolem function generator for quantifier block " << TypeOfQuantifier << "_" << quantifier_block << " finished " << endl; cout << "\nSkolem functions\n"; int variable_index = 1; for(map::iterator map_it = variable_to_skolem_function_map.begin(); map_it != variable_to_skolem_function_map.end(); map_it++) { writeFormulaToFile(pub_aig_manager, map_it->second, "game_skolem_function", ".v", quantifier_block, variable_index); variable_index++; } #endif // finding \exists X. (present_formula) Aig_Obj_t* exists_present_formula; exists_present_formula = replaceVariablesByFormulas(present_formula, variable_to_skolem_function_map); assert(exists_present_formula != NULL); Aig_Obj_t* exists_present_formula_CO = Aig_ObjCreateCo( pub_aig_manager, exists_present_formula ); assert(exists_present_formula_CO != NULL); if(TypeOfQuantifier == 'a') { // present_formula should become \neg \exists X. (present_formula) present_formula = createNot(exists_present_formula, pub_aig_manager); } else { present_formula = exists_present_formula; } #ifdef DEBUG_SKOLEM writeFormulaToFile(pub_aig_manager, present_formula, "present_formula", ".v", quantifier_block, 0); #endif #ifdef DEBUG_SKOLEM cout << "\nPress any key to continue..."; char c = getchar(); #endif }// for ends here }// function ends here void AIGBasedSkolem::obtainSkolemFunctionsInGameBenchmarks(set &Factors, list &VariablesToEliminate, map &variable_to_skolem_function_map, int quantifier_block, char TypeOfQuantifier) { // set the logfile_prefix appropriately logfile_prefix = original_logfile_prefix; char quantifier_block_char[100]; sprintf(quantifier_block_char, "%d", quantifier_block+1); string quantifier_block_string(quantifier_block_char); if(TypeOfQuantifier == 'e') { logfile_prefix += "exists_"; } else { logfile_prefix += "forall_"; } logfile_prefix += quantifier_block_string; logfile_prefix += "_"; // change the benchmark_name appropriately benchmark_name = original_benchmark_name; if(TypeOfQuantifier == 'e') { benchmark_name += "_exists_"; } else { benchmark_name += "_forall_"; } benchmark_name += quantifier_block_string; // initialize the times unsigned long long int total_duration_ms; struct timeval total_start_ms, total_finish_ms; gettimeofday (&total_start_ms, NULL); // initialize the details.txt file string record_file; record_file = logfile_prefix; record_file += "skolem_function_generation_details.txt"; FILE* record_fp = fopen(record_file.c_str(), "a+"); assert(record_fp != NULL); fprintf(record_fp, "\n\n\n\n"); fprintf(record_fp, "benchmark type = %s\n", benchmark_type.c_str()); fprintf(record_fp, "benchmark name = %s\n", benchmark_name.c_str()); fprintf(record_fp, "problem = %s\n", problem_kind.c_str()); fprintf(record_fp, "machine = %s\n", machine.c_str()); fclose(record_fp); // restart the timeout settings if(time_out_enabled) { time_t elim_start_time; time(&elim_start_time); time_out_start = elim_start_time; } // both CEGAR and MONOLITHIC are in factorizedSkolemFunctionGenerator list VariablesToEliminate_Copy; VariablesToEliminate_Copy = VariablesToEliminate; factorizedSkolemFunctionGenerator(Factors, VariablesToEliminate_Copy); if(time_out_enabled && timed_out) { cout << "\nTime-out from skolem-function generator\n"; } // printing the statitics gettimeofday (&total_finish_ms, NULL); total_duration_ms = total_finish_ms.tv_sec * 1000 + total_finish_ms.tv_usec / 1000; total_duration_ms -= total_start_ms.tv_sec * 1000 + total_start_ms.tv_usec / 1000; assert(problem_kind == "variable_elimination"); total_duration_ms = total_duration_ms - total_time_in_compute_size; string order_string_to_print; if(order_of_elimination_of_variables == 0) { order_string_to_print = "alphabetical"; } else if(order_of_elimination_of_variables == 1) { order_string_to_print = "least-occurring-first"; } else if(order_of_elimination_of_variables == 2) { order_string_to_print = "factor-graph-based"; } else if(order_of_elimination_of_variables == 3) { order_string_to_print = "externally-supplied"; } string algorithm_string; if(enable_cegar) { algorithm_string = "cegar"; if(use_mu_based_scheme_with_optimizations_in_cegar && unify_code_for_mu_based_scheme_in_cegar) { if(use_assumptions_in_unified_cegar) { algorithm_string += "_optimized"; } else { algorithm_string += "_unoptimized"; } if(use_bads_in_unified_cegar) { algorithm_string += "_withbads"; } else { algorithm_string += "_withnegf"; } if(accumulate_formulae_in_cbzero_in_cegar) { algorithm_string += "_withaccumulate"; } else { algorithm_string += "_noaccumulate"; } } } else { algorithm_string = "monolithic"; if(compute_quantifier_eliminated_result_using_skolem_functions) { algorithm_string += "_compositionqe"; } else { algorithm_string += "_bddlikeqe"; } if(use_interpolant_as_skolem_function) { algorithm_string += "_interpolantskf"; } else { algorithm_string += "_cofactorskf"; } if(skolem_function_type_in_jiang == "cofactorone") { algorithm_string += "_cofactorone"; } else { algorithm_string += "_bothcofactors"; } } record_file = logfile_prefix; record_file += "skolem_function_generation_details.txt"; record_fp = fopen(record_file.c_str(), "a+"); assert(record_fp != NULL); if(enable_cegar) { if(use_mu_based_scheme_in_cegar || use_mu_based_scheme_with_optimizations_in_cegar) { fprintf(record_fp, "\n\n\ntotal-time-in-evaluation-of-mu = %llu milliseconds\ntotal-time-in-interpolant-computation-in-cegar = %llu milliseconds\ntotal-time-in-dont-care-optimization-in-cegar = %llu milliseconds\ntotal-time-in-generalization-in-refinement-from-bottom-in-cegar = %llu milliseconds\ntotal-time-in-initial-abstraction-generation-without-size-computation-time = %llu milliseconds\ntotal-time-in-cegar-loops-without-size-computation-time = %llu milliseconds\ntotal-time-in-reverse-substitution-without-size-computation-time = %llu milliseconds\nsolver-used = %s\nnumber-of-cegar-iterations = %d\n\ntotal-time-without-size-computation-time = %llu milliseconds\n", total_time_in_mu_evaluation_in_cegar, total_time_in_interpolant_computation_in_cegar, total_time_in_dontcare_optimization_in_cegar, total_time_in_generalization_in_mu_based_scheme_with_optimizations_in_cegar, total_time_in_initial_abstraction_generation_in_cegar, total_time_in_cegar_loops_in_cegar, total_time_in_reverse_substitution_in_cegar, solver.c_str(), cegar_iteration_number, total_duration_ms); } else { fprintf(record_fp, "\n\n\ntotal-time-in-initial-abstraction-generation-without-size-computation-time = %llu milliseconds\ntotal-time-in-cegar-loops-without-size-computation-time = %llu milliseconds\nsolver-used = %s\nnumber-of-cegar-iterations = %d\ntotal-time-in-connection-substitution-without-size-computation-time = %llu milliseconds\ntotal-time-in-reverse-substitution-without-size-computation-time = %llu milliseconds\ntotal-time-without-size-computation-time = %llu milliseconds\nmaximum-length-of-connection = %d\nnumber-of-connections = %d\n", total_time_in_initial_abstraction_generation_in_cegar, total_time_in_cegar_loops_in_cegar, solver.c_str(), cegar_iteration_number, total_time_in_connection_substitution_in_cegar, total_time_in_reverse_substitution_in_cegar, total_duration_ms, maximum_length_of_connection_in_connection_based_scheme, number_of_connections_in_connection_based_scheme); fprintf(record_fp, "\n\nsizes-of-exactness-formulae-after-simplification = "); for(list::iterator sfs_it = sizes_of_exactness_formulae_in_cegar.begin(); sfs_it != sizes_of_exactness_formulae_in_cegar.end(); sfs_it++) { fprintf(record_fp, "%d, ", *sfs_it); } unsigned long long int total_time_in_cnf_generation_in_cegar = 0; unsigned long long int total_time_in_aig_simplification_in_cegar = 0; unsigned long long int total_time_in_sat_solving_in_cegar_computed = 0; fprintf(record_fp, "\ntimes-in-simplification = "); for(list::iterator sfs_it = times_in_aig_simplification_in_cegar.begin(); sfs_it != times_in_aig_simplification_in_cegar.end(); sfs_it++) { fprintf(record_fp, "%llu, ", *sfs_it); total_time_in_aig_simplification_in_cegar = total_time_in_aig_simplification_in_cegar + *sfs_it; } fprintf(record_fp, "\ntimes-in-cnf-generation = "); for(list::iterator sfs_it = times_in_cnf_generation_in_cegar.begin(); sfs_it != times_in_cnf_generation_in_cegar.end(); sfs_it++) { fprintf(record_fp, "%llu, ", *sfs_it); total_time_in_cnf_generation_in_cegar = total_time_in_cnf_generation_in_cegar + *sfs_it; } fprintf(record_fp, "\ntimes-in-sat-solving = "); for(list::iterator sfs_it = times_in_sat_solving_in_cegar.begin(); sfs_it != times_in_sat_solving_in_cegar.end(); sfs_it++) { fprintf(record_fp, "%llu, ", *sfs_it); total_time_in_sat_solving_in_cegar_computed = total_time_in_sat_solving_in_cegar_computed + *sfs_it; } fprintf(record_fp, "\ntotal_time_in_cnf_generation_in_cegar = %llu milliseconds\ntotal_time_in_aig_simplification_in_cegar = %llu milliseconds\ntotal_time_in_sat_solving_in_cegar = %llu milliseconds", total_time_in_cnf_generation_in_cegar, total_time_in_aig_simplification_in_cegar, total_time_in_sat_solving_in_cegar_computed); fprintf(record_fp, "\n\ntotal_time_in_exactness_checking_in_cegar = %llu milliseconds\ntotal_time_in_x_new_recompution_in_cegar = %llu milliseconds\ntotal_time_in_reevaluation_in_cegar = %llu milliseconds\nnumber_of_exactness_checking_in_cegar = %d\nnumber_of_x_new_recompution_in_cegar = %d\nnumber_of_reevaluation_in_cegar = %d ", total_time_in_exactness_checking_in_cegar, total_time_in_x_new_recompution_in_cegar, total_time_in_reevaluation_in_cegar, number_of_exactness_checking_in_cegar, number_of_x_new_recompution_in_cegar, number_of_reevaluation_in_cegar); fprintf(record_fp, "\n\nordering-used = %s\nbad_to_be_pulled_in_each_iteration = %s\ntotal time in ordering = %llu milliseconds\ntotal time in compute-size = %llu\ntotal time in compute-support = %llu\ntotal time in initialization of skolem function generator-without-size-computation-time = %llu", order_string_to_print.c_str(), bad_to_be_pulled_in_each_iteration.c_str(), total_time_in_ordering, total_time_in_compute_size, total_time_in_compute_support, total_time_in_generator_initialization); fprintf(record_fp, "\n\nsize_computation_time_in_initialization = %llu milliseconds\nsize_computation_time_in_initial_abstraction_generation_in_cegar = %llu milliseconds\nsize_computation_time_in_reverse_substitution_in_cegar = %llu milliseconds\nsize_computation_time_in_cegar_loops_in_cegar = %llu milliseconds\nsize_computation_time_in_connection_substitution_in_cegar = %llu milliseconds\ntotal_time_in_compute_size = %llu milliseconds", size_computation_time_in_initialization, size_computation_time_in_initial_abstraction_generation_in_cegar, size_computation_time_in_reverse_substitution_in_cegar, size_computation_time_in_cegar_loops_in_cegar, size_computation_time_in_connection_substitution_in_cegar, total_time_in_compute_size); } } else { fprintf(record_fp, "\ntotal-time-in-initial-skolem-function-generation-without-size-computation-time = %llu milliseconds\ntotal-time-in-reverse-substitution-without-size-computation-time = %llu milliseconds\ntotal-time-without-size-computation-time = %llu milliseconds\ntotal-time-in-interpolant-computation = %llu", total_time_in_initial_abstraction_generation_in_cegar, total_time_in_reverse_substitution_in_cegar, total_duration_ms, total_time_in_interpolant_computation); fprintf(record_fp, "\n\nalgorithm-used = %s\nordering-used = %s\ntotal time in ordering = %llu milliseconds\ntotal time in compute-size = %llu\ntotal time in compute-support = %llu\ntotal time in initialization of skolem function generator-without-size-computation-time = %llu\ntotal time in sat solving = %llu\nsolver used = %s\nnumber of cegar iterations = %d", algorithm_string.c_str(), order_string_to_print.c_str(), total_time_in_ordering, total_time_in_compute_size, total_time_in_compute_support, total_time_in_generator_initialization, total_time_in_smt_solver, solver.c_str(), cegar_iteration_number); fprintf(record_fp, "\n\nCompose Details:\nHit_1 = %llu\nMiss_1 = %llu\nHit_2 = %llu\nMiss_2 = %llu\nLeaves = %llu\nNon-leaves = %llu\nNo-create-expr = %llu\nCreate-expr = %llu\nCreate-expr/Miss_2 = %f", first_level_cache_hits, first_level_cache_misses, second_level_cache_hits, second_level_cache_misses, leaf_cases, node_cases, no_recreation_cases, recreation_cases, (float)recreation_cases/(float)second_level_cache_misses); fprintf(record_fp, "\n\nsize_computation_time_in_initialization = %llu milliseconds\nsize_computation_time_in_initial_abstraction_generation_in_cegar = %llu milliseconds\nsize_computation_time_in_reverse_substitution_in_cegar = %llu milliseconds\nsize_computation_time_in_cegar_loops_in_cegar = %llu milliseconds\nsize_computation_time_in_connection_substitution_in_cegar = %llu milliseconds\ntotal_time_in_compute_size = %llu milliseconds", size_computation_time_in_initialization, size_computation_time_in_initial_abstraction_generation_in_cegar, size_computation_time_in_reverse_substitution_in_cegar, size_computation_time_in_cegar_loops_in_cegar, size_computation_time_in_connection_substitution_in_cegar, total_time_in_compute_size); } if(enable_cegar && perform_reverse_substitution) { fprintf(record_fp, "\nnumber-of-composes-in-reverse-substitution = %d", number_of_compose_operations_for_variable); fprintf(record_fp, "\nfinal-skolem-function-sizes = "); for(list::iterator sfs_it = skolem_function_sizes_after_reverse_substitution.begin(); sfs_it != skolem_function_sizes_after_reverse_substitution.end(); sfs_it++) { fprintf(record_fp, "%d, ", *sfs_it); } } else if(perform_reverse_substitution) { fprintf(record_fp, "\ncompose-in-reverse-substitution = %d", number_of_compose_operations_for_variable); fprintf(record_fp, "\ntime-in-reverse-substitution = %llu", ComposeTime); fprintf(record_fp, "\nfinal-skolem-function-sizes = "); for(list::iterator sfs_it = skolem_function_sizes_after_reverse_substitution.begin(); sfs_it != skolem_function_sizes_after_reverse_substitution.end(); sfs_it++) { fprintf(record_fp, "%d, ", *sfs_it); } } else { fprintf(record_fp, "\ncompose-in-reverse-substitution = -"); fprintf(record_fp, "\ntime-in-reverse-substitution = -"); fprintf(record_fp, "\nfinal-skolem-function-sizes = -"); } fclose(record_fp); if(!use_bloqqer) { string plot_file; plot_file = logfile_prefix; plot_file += "skolem_function_generation_details_to_plot.txt"; FILE* plot_fp = fopen(plot_file.c_str(), "a+"); assert(plot_fp != NULL); if(disable_factorization) { if(time_out_enabled && timed_out) { fprintf(plot_fp, "\t%f\t%f", (float)sum_of_number_of_factors_containing_variable/(float)(number_of_variables_eliminated), (float)sum_of_skolem_function_sizes/(float)(number_of_variables_eliminated)); } else { fprintf(plot_fp, "\t%f\t%f", (float)sum_of_number_of_factors_containing_variable/(float)(number_of_vars_to_elim), (float)sum_of_skolem_function_sizes/(float)(number_of_vars_to_elim)); } //fprintf(plot_fp, "\t%llu\t%llu\t-\t-\t-\t-\t-\t", total_number_of_compose_operations, total_time_in_compose_operations); } else { if(time_out_enabled && timed_out) { if(enable_cegar) { fprintf(plot_fp, "\t-\t%f", (float)sum_of_number_of_factors_containing_variable/(float)(number_of_variables_eliminated)); } else { fprintf(plot_fp, "\t%f\t%f", (float)sum_of_number_of_factors_containing_variable/(float)(number_of_variables_eliminated), (float)sum_of_skolem_function_sizes/(float)(number_of_variables_eliminated)); } } else { fprintf(plot_fp, "\t%f\t%f", (float)sum_of_number_of_factors_containing_variable/(float)(number_of_vars_to_elim), (float)sum_of_skolem_function_sizes/(float)(number_of_vars_to_elim)); } //fprintf(plot_fp, "\t%llu\t%llu\t%llu\t%llu\t%llu\t%llu\t%llu\t", total_number_of_compose_operations, total_time_in_compose_operations, total_time_in_alpha_combined, total_time_in_delta_part, total_time_in_correction_part, total_time_in_delta_combined, total_time_in_next_factor); } if(time_out_enabled && timed_out) { fprintf(plot_fp, "\t%llu\t", time_out*1000); } else { fprintf(plot_fp, "\t%llu\t", total_duration_ms); } if(time_out_enabled && timed_out) { //fprintf(plot_fp, "-\t-\t%s\t%llu\t%llu\t%llu\t%f\t", order_string_to_print.c_str(), total_time_in_ordering, total_time_in_compute_size, total_time_in_ordering+total_time_in_compute_size, (float)sum_of_numbers_of_affecting_factors/(float)(number_of_variables_eliminated)); fprintf(plot_fp, "%d\t-\t-\t%s\t%llu\t", cegar_iteration_number, order_string_to_print.c_str(), total_time_in_ordering); } else if(!perform_reverse_substitution) { //fprintf(plot_fp, "-\t-\t%s\t%llu\t%llu\t%llu\t%f\t", order_string_to_print.c_str(), total_time_in_ordering, total_time_in_compute_size, total_time_in_ordering+total_time_in_compute_size, (float)sum_of_numbers_of_affecting_factors/(float)(AIGBasedSkolemObj->number_of_vars_to_elim)); fprintf(plot_fp, "%d\t-\t-\t%s\t%llu\t", cegar_iteration_number, order_string_to_print.c_str(), total_time_in_ordering); } else { //fprintf(plot_fp, "%llu\t%f\t%s\t%llu\t%llu\t%llu\t%f\t", AIGBasedSkolemObj->ComposeTime, (float)sum_of_skolem_function_sizes_after_reverse_substitution/(float)(AIGBasedSkolemObj->number_of_vars_to_elim), order_string_to_print.c_str(), total_time_in_ordering, total_time_in_compute_size, total_time_in_ordering+total_time_in_compute_size, (float)sum_of_numbers_of_affecting_factors/(float)(AIGBasedSkolemObj->number_of_vars_to_elim)); fprintf(plot_fp, "%d\t%llu\t%f\t%s\t%llu\t", cegar_iteration_number, total_time_in_reverse_substitution_in_cegar, (float)sum_of_skolem_function_sizes_after_reverse_substitution/(float)(number_of_vars_to_elim), order_string_to_print.c_str(), total_time_in_ordering); } if(enable_cegar) { fprintf(plot_fp, "%llu\t%llu\t%llu\t%llu\t%llu\t%llu\t%llu\t%llu\t%llu\n", total_time_in_mu_evaluation_in_cegar, total_time_in_interpolant_computation_in_cegar, total_time_in_dontcare_optimization_in_cegar, total_time_in_generalization_in_mu_based_scheme_with_optimizations_in_cegar, total_time_in_initial_abstraction_generation_in_cegar, total_time_in_cegar_loops_in_cegar, total_time_in_sat_solving_in_cegar, total_time_in_true_sat_solving_in_cegar, total_time_in_false_sat_solving_in_cegar); } else { fprintf(plot_fp, "%llu\t%llu\t%llu\t%llu\t%llu\t%llu\t%llu\t%llu\t%llu\n", total_time_in_mu_evaluation_in_cegar, total_time_in_interpolant_computation, total_time_in_dontcare_optimization_in_cegar, total_time_in_generalization_in_mu_based_scheme_with_optimizations_in_cegar, total_time_in_initial_abstraction_generation_in_cegar, total_time_in_cegar_loops_in_cegar, total_time_in_sat_solving_in_cegar, total_time_in_true_sat_solving_in_cegar, total_time_in_false_sat_solving_in_cegar); } fclose(plot_fp); } #ifdef DEBUG_SKOLEM string map_file_name = "Ci_id_to_Ci_name_map.txt"; FILE* map_fp = fopen(map_file_name.c_str(), "w+"); assert(map_fp != NULL); for(map::iterator map_it = Ci_id_to_Ci_name_map.begin(); map_it != Ci_id_to_Ci_name_map.end(); map_it++) { fprintf(map_fp, "\n%d\t%s\n", map_it->first, (map_it->second).c_str()); } fclose(map_fp); map_file_name = "Ci_name_to_Ci_number_map.txt"; map_fp = fopen(map_file_name.c_str(), "w+"); assert(map_fp != NULL); for(map::iterator map_it = Ci_name_to_Ci_number_map.begin(); map_it != Ci_name_to_Ci_number_map.end(); map_it++) { fprintf(map_fp, "\n%s\t%d\n", (map_it->first).c_str(), map_it->second); } fclose(map_fp); map_file_name = "Ci_name_to_Ci_label_map.txt"; map_fp = fopen(map_file_name.c_str(), "w+"); assert(map_fp != NULL); for(map::iterator map_it = Ci_name_to_Ci_label_mapForGetCNF.begin(); map_it != Ci_name_to_Ci_label_mapForGetCNF.end(); map_it++) { fprintf(map_fp, "\n%s\t%d\n", (map_it->first).c_str(), map_it->second); } fclose(map_fp); //char dump_file[100]; //strcpy(dump_file, "dump.v"); //Aig_ManDumpVerilog( aig_manager, dump_file ); Aig_ManShow(pub_aig_manager, 0, NULL); #endif // get the Skolem functions in a map for(list::iterator list_it = VariablesToEliminate.begin(); list_it != VariablesToEliminate.end(); list_it++) { string variable_to_eliminate = *list_it; int index_of_variable_to_eliminate = searchVarNameToVarIndexMap(var_name_to_var_index_map, variable_to_eliminate); Aig_Obj_t* skolem_function; if(index_of_variable_to_eliminate == -1) // Factors free of variable_to_eliminate { skolem_function = createTrue(pub_aig_manager); assert(skolem_function != NULL); } else { skolem_function = searchOneDimensionalMatrix(SkolemFunctions, number_of_vars_to_elim, index_of_variable_to_eliminate); assert(skolem_function != NULL); } variable_to_skolem_function_map.insert(make_pair(variable_to_eliminate, skolem_function)); } clearAllDataStructures(); } void AIGBasedSkolem::recreateCiMaps(list &VariablesToEliminate) { // recreate the Ci_... maps Ci_id_to_Ci_name_map.clear(); for(map::iterator map_it = initial_Ci_id_to_Ci_name_map.begin(); map_it != initial_Ci_id_to_Ci_name_map.end(); map_it++) { Ci_id_to_Ci_name_map.insert(make_pair(map_it->first, map_it->second)); } Ci_name_to_Ci_number_map.clear(); for(map::iterator map_it = initial_Ci_name_to_Ci_number_map.begin(); map_it != initial_Ci_name_to_Ci_number_map.end(); map_it++) { Ci_name_to_Ci_number_map.insert(make_pair(map_it->first, map_it->second)); } Ci_name_to_Ci_object_map.clear(); for(map::iterator map_it = initial_Ci_name_to_Ci_object_map.begin(); map_it != initial_Ci_name_to_Ci_object_map.end(); map_it++) { Ci_name_to_Ci_object_map.insert(make_pair(map_it->first, map_it->second)); } number_of_Cis = initial_number_of_Cis; // recreate Ci_to_eliminate_name_to_Ci_to_eliminate_object_map Ci_to_eliminate_name_to_Ci_to_eliminate_object_map.clear(); for(list::iterator VariablesToEliminate_it = VariablesToEliminate.begin(); VariablesToEliminate_it != VariablesToEliminate.end(); VariablesToEliminate_it++) { string variable_to_eliminate = *VariablesToEliminate_it; map::iterator Ci_name_to_Ci_object_map_it = Ci_name_to_Ci_object_map.find(variable_to_eliminate); assert(Ci_name_to_Ci_object_map_it != Ci_name_to_Ci_object_map.end()); Aig_Obj_t* variable_to_eliminate_obj = Ci_name_to_Ci_object_map_it->second; Ci_to_eliminate_name_to_Ci_to_eliminate_object_map.insert(make_pair(variable_to_eliminate, variable_to_eliminate_obj)); } // some maps are to be cleared aig_bad_set = NULL; B_i_index_to_B_i_object_map.clear(); connection_string_to_connection_object_map.clear(); Ci_to_eliminate_renamed_to_Ci_to_eliminate_renamed_object_map.clear(); Ci_to_eliminate_renamed_name_to_Ci_to_eliminate_renamed_object_map.clear(); } void AIGBasedSkolem::satisfiableBenchmarkGeneration(set &transition_function_factors, map &output_string_to_transition_function_parts, list &VariablesToEliminate) { int number_of_variables_to_eliminate = VariablesToEliminate.size(); int original_no_of_cis = number_of_Cis; assert(!transition_function_factors.empty()); // each element is x_i' \equiv f_i(X, I) assert(!output_string_to_transition_function_parts.empty()); // each element is string x_i' \mapsto f_i(X, I) map variable_to_skolem_function_map; // This stores I_i ---> some (complex) formula int toggle_counter = 1; // to decide whether to use true/false for(list::iterator list_it = VariablesToEliminate.begin(); list_it != VariablesToEliminate.end(); list_it++) { string variable_to_eliminate = *list_it; Aig_Obj_t* skolem_function; if(toggle_counter % 2 == 1) { cout << endl << variable_to_eliminate << " ---> true\n"; skolem_function = createTrue(pub_aig_manager); } else { if(make_alternate_entries_toggle_in_initial_variable_to_skolem_function_map) { skolem_function = createFalse(pub_aig_manager); cout << endl << variable_to_eliminate << " ---> false\n"; } else { skolem_function = createTrue(pub_aig_manager); cout << endl << variable_to_eliminate << " ---> true\n"; } } assert(skolem_function != NULL); variable_to_skolem_function_map.insert(make_pair(variable_to_eliminate, skolem_function)); toggle_counter++; } // let's see output_string_to_transition_function_parts #ifdef DEBUG_SKOLEM cout << "\noutput_string_to_transition_function_parts\n"; for(map::iterator map_it = output_string_to_transition_function_parts.begin(); map_it != output_string_to_transition_function_parts.end(); map_it++) { cout << endl << map_it->first << "\t" << map_it->second << endl; string transition_function_part_file_name = benchmark_name_without_extension; transition_function_part_file_name += "_"; transition_function_part_file_name += map_it->first; transition_function_part_file_name += "_transition_function_part"; writeFormulaToFile(pub_aig_manager, map_it->second, transition_function_part_file_name, ".v", 0, 0); } #endif Aig_Obj_t* full_transition_function_part = NULL; map input_object_to_transition_function_parts; for(map::iterator map_it = output_string_to_transition_function_parts.begin(); map_it != output_string_to_transition_function_parts.end(); map_it++) { string latchout_name = map_it->first; int index_of_uscore = latchout_name.find_last_of("_"); string latchout_part = latchout_name.substr(0, index_of_uscore); assert(latchout_part == "LATCHOUT"); string location_str = latchout_name.substr(index_of_uscore+1); string latchin_name = "LATCHIN_"; latchin_name += location_str; map::iterator Ci_name_to_Ci_object_map_it = Ci_name_to_Ci_object_map.find(latchin_name); assert(Ci_name_to_Ci_object_map_it != Ci_name_to_Ci_object_map.end()); Aig_Obj_t* input_object = Ci_name_to_Ci_object_map_it->second; assert(input_object != NULL); input_object_to_transition_function_parts.insert(make_pair(input_object, map_it->second)); if(make_variable_to_skolem_function_map_complex && function_to_make_variable_to_skolem_function_map_complex == "F") { if(full_transition_function_part == NULL) { full_transition_function_part = map_it->second; } else { full_transition_function_part = createAnd(full_transition_function_part, map_it->second, pub_aig_manager); } } } #ifdef DEBUG_SKOLEM cout << "\ninput_object_to_transition_function_parts\n"; int file_counter = 1; for(map::iterator map_it = input_object_to_transition_function_parts.begin(); map_it != input_object_to_transition_function_parts.end(); map_it++) { string transition_function_part_file_name = benchmark_name_without_extension; transition_function_part_file_name += "_transition_function_part"; writeFormulaToFile(pub_aig_manager, map_it->second, transition_function_part_file_name, ".v", 0, file_counter); string transition_function_name_file_name = benchmark_name_without_extension; transition_function_name_file_name += "_transition_function_name"; writeFormulaToFile(pub_aig_manager, map_it->first, transition_function_name_file_name, ".v", 0, file_counter); file_counter++; } #endif if(make_initial_variable_to_skolem_function_map_a_formula) { map::iterator input_object_to_transition_function_parts_it = input_object_to_transition_function_parts.begin(); for(map::iterator initial_variable_to_skolem_function_map_it = variable_to_skolem_function_map.begin(); initial_variable_to_skolem_function_map_it != variable_to_skolem_function_map.end(); initial_variable_to_skolem_function_map_it++) { if(input_object_to_transition_function_parts_it == input_object_to_transition_function_parts.end()) //end reached; wrap-wround { input_object_to_transition_function_parts_it = input_object_to_transition_function_parts.begin(); } initial_variable_to_skolem_function_map_it->second = input_object_to_transition_function_parts_it->first; // to show the entry map::iterator Ci_id_to_Ci_name_map_it = Ci_id_to_Ci_name_map.find(Aig_ObjId(initial_variable_to_skolem_function_map_it->second)); assert(Ci_id_to_Ci_name_map_it != Ci_id_to_Ci_name_map.end()); cout << endl << initial_variable_to_skolem_function_map_it->first << " ---> " << Ci_id_to_Ci_name_map_it->second << endl; input_object_to_transition_function_parts_it++; } } set all_bit_differing_from_cycle_components; set all_bit_same_as_true_components; int part_number = 1; int number_of_parts = input_object_to_transition_function_parts.size(); map::iterator variable_to_skolem_function_map_it = variable_to_skolem_function_map.begin(); assert(variable_to_skolem_function_map_it != variable_to_skolem_function_map.end()); bool end_of_variable_to_skolem_function_map_reached = false; int location_in_variable_to_skolem_function_map = 1; for(map::iterator map_it = input_object_to_transition_function_parts.begin(); map_it != input_object_to_transition_function_parts.end(); map_it++) { Aig_Obj_t* transition_function_part = map_it->second; // f_i(X, I) Aig_Obj_t* transition_function_name = map_it->first; // x_i #ifdef DEBUG_SKOLEM // Just see the sizes of elements in variable_to_skolem_function_map cout << endl << "variable_to_skolem_function_map"; for(map::iterator variable_to_skolem_function_map_it2 = variable_to_skolem_function_map.begin(); variable_to_skolem_function_map_it2 != variable_to_skolem_function_map.end(); variable_to_skolem_function_map_it2++) { cout << endl << variable_to_skolem_function_map_it2->first << "\t" << computeSize(variable_to_skolem_function_map_it2->second, pub_aig_manager); } cout << endl; #endif Aig_Obj_t* transition_function_part_after_replacement; transition_function_part_after_replacement = replaceVariablesByFormulas(transition_function_part, variable_to_skolem_function_map); // replace I in f_i(X, I) by corresponding formulae in map, initially all true's assert(transition_function_part_after_replacement != NULL); // f_i(x, true) cout << "\nSize of transition_function_part_after_replacement = " << computeSize(transition_function_part_after_replacement, pub_aig_manager) << endl; Aig_Obj_t* full_transition_function_part_after_replacement; if(make_variable_to_skolem_function_map_complex && function_to_make_variable_to_skolem_function_map_complex == "F") { full_transition_function_part_after_replacement = replaceVariablesByFormulas(full_transition_function_part, variable_to_skolem_function_map); // replace I in f_i(X, I)\wedge ... \wedge f_n(X, I) by corresponding formulae in map assert(full_transition_function_part_after_replacement != NULL); cout << "\nSize of full_transition_function_part_after_replacement = " << computeSize(full_transition_function_part_after_replacement, pub_aig_manager) << endl; if(full_transition_function_part_after_replacement == createFalse(pub_aig_manager)) { cout << "\nfull_transition_function_part_after_replacement is False\n"; } else if(full_transition_function_part_after_replacement == createTrue(pub_aig_manager)) { cout << "\nfull_transition_function_part_after_replacement is True\n"; } } if(make_variable_to_skolem_function_map_complex && !end_of_variable_to_skolem_function_map_reached) { variable_to_skolem_function_map_it++; location_in_variable_to_skolem_function_map++; if(variable_to_skolem_function_map_it != variable_to_skolem_function_map.end()) { if(function_to_make_variable_to_skolem_function_map_complex == "F") { variable_to_skolem_function_map_it->second = full_transition_function_part_after_replacement; } else { variable_to_skolem_function_map_it->second = transition_function_part_after_replacement; } cout << "\nlocation " << location_in_variable_to_skolem_function_map << "in variable_to_skolem_function_map changed\n"; } else { // we have reached at the end of map end_of_variable_to_skolem_function_map_reached = true; cout << "\nwe have reached at the end of map; we will start from the beginning\n"; variable_to_skolem_function_map_it = variable_to_skolem_function_map.begin(); location_in_variable_to_skolem_function_map = 1; if(function_to_make_variable_to_skolem_function_map_complex == "F") { variable_to_skolem_function_map_it->second = full_transition_function_part_after_replacement; } else { variable_to_skolem_function_map_it->second = transition_function_part_after_replacement; } cout << "\nlocation " << location_in_variable_to_skolem_function_map << "in variable_to_skolem_function_map changed\n"; end_of_variable_to_skolem_function_map_reached = false; } } Aig_Obj_t* single_bit_same_as_true_component; single_bit_same_as_true_component = createEquivalence(transition_function_part_after_replacement, transition_function_name, pub_aig_manager); assert(single_bit_same_as_true_component != NULL); // f_i(X, true) \equiv x_i if(limit_on_number_of_extra_conjuncts == -1) { all_bit_same_as_true_components.insert(single_bit_same_as_true_component); } else if(part_number <= limit_on_number_of_extra_conjuncts) { cout << endl << "factor_" << part_number << " added\n"; all_bit_same_as_true_components.insert(single_bit_same_as_true_component); } else { cout << endl << "factor_" << part_number << " NOT added\n"; } Aig_Obj_t* single_bit_differing_from_cycle_component; single_bit_differing_from_cycle_component = createEquivalence(transition_function_part, transition_function_name, pub_aig_manager); assert(single_bit_differing_from_cycle_component != NULL); // f_i(X, I) \equiv x_i Aig_Obj_t* all_bit_differing_from_cycle_component = createNot(single_bit_differing_from_cycle_component, pub_aig_manager); assert(all_bit_differing_from_cycle_component != NULL); // f_i(X, I) \neq x_i all_bit_differing_from_cycle_components.insert(all_bit_differing_from_cycle_component); part_number++; } Aig_Obj_t* all_bit_same_as_true; if(all_bit_same_as_true_components.empty()) { all_bit_same_as_true = createFalse(pub_aig_manager); } else { all_bit_same_as_true = createAnd(all_bit_same_as_true_components, pub_aig_manager); } // (f_1(X, true) \equiv x_1 \wedge ... \wedge f_n(X, true) \equiv x_n) assert(all_bit_same_as_true != NULL); #ifdef DEBUG_SKOLEM string all_bit_same_as_true_file_name = benchmark_name_without_extension; all_bit_same_as_true_file_name += "_all_bit_same_as_true"; writeFormulaToFile(pub_aig_manager, all_bit_same_as_true, all_bit_same_as_true_file_name, ".v", 0, 0); #endif int fresh_count = 1; int no_of_cis_with_f_variables = number_of_Cis; set all_bit_differing_from_cycle_tseitin_components; set fresh_objects_for_all_bit_differing_from_cycle_tseitin_components; for(set::iterator all_bit_differing_from_cycle_components_it = all_bit_differing_from_cycle_components.begin(); all_bit_differing_from_cycle_components_it != all_bit_differing_from_cycle_components.end(); all_bit_differing_from_cycle_components_it++) { Aig_Obj_t* all_bit_differing_from_cycle_component = *all_bit_differing_from_cycle_components_it; Aig_Obj_t* fresh_object = Aig_ObjCreateCi(pub_aig_manager); assert(fresh_object != NULL); fresh_objects_for_all_bit_differing_from_cycle_tseitin_components.insert(fresh_object); char fresh_count_char[100]; sprintf(fresh_count_char, "%d", fresh_count); string fresh_count_string(fresh_count_char); string fresh_object_string = "g_"; fresh_object_string += fresh_count_string; fresh_count++; int fresh_object_id = Aig_ObjId(fresh_object); Ci_id_to_Ci_name_map.insert(make_pair(fresh_object_id, fresh_object_string)); Ci_name_to_Ci_number_map.insert(make_pair(fresh_object_string, number_of_Cis)); number_of_Cis++; Aig_Obj_t* all_bit_differing_from_cycle_tseitin_component = createEquivalence(fresh_object, all_bit_differing_from_cycle_component, pub_aig_manager); assert(all_bit_differing_from_cycle_tseitin_component != NULL); all_bit_differing_from_cycle_tseitin_components.insert(all_bit_differing_from_cycle_tseitin_component); } if(extend_tsietin_encoding_to_extra_part) { Aig_Obj_t* fresh_object = Aig_ObjCreateCi(pub_aig_manager); assert(fresh_object != NULL); fresh_objects_for_all_bit_differing_from_cycle_tseitin_components.insert(fresh_object); char fresh_count_char[100]; sprintf(fresh_count_char, "%d", fresh_count); string fresh_count_string(fresh_count_char); string fresh_object_string = "g_"; fresh_object_string += fresh_count_string; fresh_count++; int fresh_object_id = Aig_ObjId(fresh_object); Ci_id_to_Ci_name_map.insert(make_pair(fresh_object_id, fresh_object_string)); Ci_name_to_Ci_number_map.insert(make_pair(fresh_object_string, number_of_Cis)); number_of_Cis++; Aig_Obj_t* all_bit_same_as_true_component = createEquivalence(fresh_object, all_bit_same_as_true, pub_aig_manager); assert(all_bit_same_as_true_component != NULL); all_bit_differing_from_cycle_tseitin_components.insert(all_bit_same_as_true_component); } int total_no_of_cis = number_of_Cis; assert(fresh_objects_for_all_bit_differing_from_cycle_tseitin_components.size() > 0); Aig_Obj_t* all_bit_differing_from_cycle_tseitin_component = createOr(fresh_objects_for_all_bit_differing_from_cycle_tseitin_components, pub_aig_manager); assert(all_bit_differing_from_cycle_tseitin_component != NULL); all_bit_differing_from_cycle_tseitin_components.insert(all_bit_differing_from_cycle_tseitin_component); assert(all_bit_differing_from_cycle_tseitin_components.size() > 0); cout << "\nNumber of top-level conjuncts = " << all_bit_differing_from_cycle_tseitin_components.size() << endl; Aig_Obj_t* all_bit_differing_from_cycle_tseitin = createAnd(all_bit_differing_from_cycle_tseitin_components, pub_aig_manager); assert(all_bit_differing_from_cycle_tseitin != NULL); if(!extend_tsietin_encoding_to_extra_part) { // disjoin this with all_bit_same_as_true all_bit_differing_from_cycle_tseitin = createOr(all_bit_differing_from_cycle_tseitin, all_bit_same_as_true, pub_aig_manager); } #ifdef DEBUG_SKOLEM string all_bit_differing_from_cycle_tseitin_file_name = benchmark_name_without_extension; all_bit_differing_from_cycle_tseitin_file_name += "_all_bit_differing_from_cycle_tseitin"; writeFormulaToFile(pub_aig_manager, all_bit_differing_from_cycle_tseitin, all_bit_differing_from_cycle_tseitin_file_name, ".v", 0, 0); #endif // Printing in files Aig_Obj_t* all_bit_differing_from_cycle_tseitin_CO; all_bit_differing_from_cycle_tseitin_CO = Aig_ObjCreateCo( pub_aig_manager, all_bit_differing_from_cycle_tseitin ); assert(all_bit_differing_from_cycle_tseitin_CO != NULL); Aig_Man_t* all_bit_differing_from_cycle_tseitin_aig_manager; all_bit_differing_from_cycle_tseitin_aig_manager = simplifyUsingConeOfInfluence( pub_aig_manager, Aig_ManCoNum(pub_aig_manager)-1, 1 ); assert(all_bit_differing_from_cycle_tseitin_aig_manager != NULL); char pname[100]; char verilog_file_char[100]; char limit_on_number_of_extra_conjuncts_char[100]; sprintf(limit_on_number_of_extra_conjuncts_char, "%d", limit_on_number_of_extra_conjuncts); string limit_on_number_of_extra_conjuncts_string(limit_on_number_of_extra_conjuncts_char); string verilog_file = benchmark_name_without_extension; verilog_file += "_sat_"; if(make_variable_to_skolem_function_map_complex) { if(function_to_make_variable_to_skolem_function_map_complex == "F") { verilog_file += "F_"; } } else { verilog_file += "simple_"; } if(make_initial_variable_to_skolem_function_map_a_formula) { verilog_file += "init_formula_"; } verilog_file += limit_on_number_of_extra_conjuncts_string; if(extend_tsietin_encoding_to_extra_part) { verilog_file += "_flattened"; } verilog_file += "_extra_bit_differing_from_cycle_tseitin"; strcpy(pname, verilog_file.c_str()); all_bit_differing_from_cycle_tseitin_aig_manager->pName = pname; verilog_file += ".v"; strcpy(verilog_file_char, verilog_file.c_str()); writeCombinationalCircuitInVerilog(all_bit_differing_from_cycle_tseitin_aig_manager, number_of_variables_to_eliminate, original_no_of_cis, no_of_cis_with_f_variables, total_no_of_cis, verilog_file_char, true); cout << "\nBenchmark file " << verilog_file << " written\n"; }