def validate_input_generation(patch_list, new_path): global pool, result_list, found_one result_list = [] if values.DEFAULT_OPERATION_MODE in ["sequential"]: for patch in patch_list: patch_formula = app.generator.generate_formula_from_patch(patch) patch_formula_extended = generator.generate_extended_patch_formula( patch_formula, new_path) patch_space_constraint = patch_formula_extended if values.DEFAULT_PATCH_TYPE == values.OPTIONS_PATCH_TYPE[1]: patch_formula_str = str(patch_formula.serialize()) patch_index = utilities.get_hash(patch_formula_str) patch_space = values.LIST_PATCH_SPACE[patch_index] parameter_constraint = smt2.generate_constraint_for_patch_space( patch_space) if parameter_constraint: patch_space_constraint = And(patch_formula_extended, parameter_constraint) index = list(patch_list).index(patch) # emitter.emit_patch(patch, message="\tabstract patch " + str(index) + " :") result_list.append( oracle.check_input_feasibility(index, patch_space_constraint, new_path)) else: emitter.normal("\t\tstarting parallel computing") pool = mp.Pool(mp.cpu_count(), initializer=mute) lock = None thread_list = [] interrupt_event = threading.Event() for patch in patch_list: try: patch_formula = app.generator.generate_formula_from_patch( patch) patch_formula_extended = generator.generate_extended_patch_formula( patch_formula, new_path) patch_space_constraint = patch_formula if values.DEFAULT_PATCH_TYPE == values.OPTIONS_PATCH_TYPE[1]: patch_formula_str = str(patch_formula.serialize()) patch_index = utilities.get_hash(patch_formula_str) patch_space = values.LIST_PATCH_SPACE[patch_index] parameter_constraint = smt2.generate_constraint_for_patch_space( patch_space) if parameter_constraint: patch_space_constraint = And(patch_formula_extended, parameter_constraint) index = list(patch_list).index(patch) # emitter.emit_patch(patch, message="\tabstract patch " + str(index) + " :") thread = pool.apply_async(oracle.check_input_feasibility, args=(index, patch_space_constraint, new_path), callback=collect_result_one) thread_list.append(thread) except ValueError: emitter.warning("\t\tvalue found before completing pool") break pool.close() emitter.normal("\t\twaiting for thread completion") pool.join() return result_list
def rank_patches(patch_list): filtered_list = [] # rank first based on coverage emitter.normal("\tcomputing rank for each patch") for patch in patch_list: patch_formula = app.generator.generate_formula_from_patch(patch) patch_constraint_str = patch_formula.serialize() patch_code_str = "" for (lid, prog) in patch.items(): patch_code_str = lid + ": " + (program_to_code(prog)) for comp_var, prog_var in values.MAP_PROG_VAR.items(): patch_code_str = patch_code_str.replace(comp_var, prog_var) patch_index = utilities.get_hash(patch_constraint_str) patch_score = values.LIST_PATCH_SCORE[patch_index] over_approx_score = 10 if values.LIST_PATCH_OVERAPPROX_CHECK[patch_index]: over_approx_score = 0 under_approx_score = 10 if values.LIST_PATCH_UNDERAPPROX_CHECK[patch_index]: under_approx_score = 0 patch_len = 10000 - len(patch_constraint_str) # if oracle.is_always_true(patch) or oracle.is_always_false(patch): # patch_len = 10000 - 1 patch_count = 1000 - utilities.count_concrete_patches_per_template( patch) filtered_list.append((patch, under_approx_score, over_approx_score, patch_score, patch_count, patch_len)) ranked_list = sorted(filtered_list, key=operator.itemgetter(3, 1, 2, 4, 5)) ranked_list.reverse() patch_list = numpy.array(ranked_list)[:, 0] return list(patch_list)
def update_patch_list(result_list, patch_list, path_condition, assertion): updated_patch_list = [] if len(result_list) != len(patch_list): recover_list = recover_patch_list(result_list, patch_list, path_condition, assertion) result_list = result_list + recover_list for result in result_list: refined_space, index, patch_score, is_under_approx, is_over_approx = result patch = patch_list[index] patch_constraint = app.generator.generate_formula_from_patch(patch) patch_constraint_str = patch_constraint.serialize() patch_index = utilities.get_hash(patch_constraint_str) values.LIST_PATCH_SCORE[patch_index] += patch_score if is_under_approx is not None: current_state = values.LIST_PATCH_UNDERAPPROX_CHECK[patch_index] final_state = is_under_approx values.LIST_PATCH_UNDERAPPROX_CHECK[patch_index] = final_state if is_over_approx is not None: current_state = values.LIST_PATCH_OVERAPPROX_CHECK[patch_index] final_state = is_over_approx values.LIST_PATCH_OVERAPPROX_CHECK[patch_index] = final_state if values.DEFAULT_REFINE_METHOD == values.OPTIONS_REFINE_METHOD[3]: updated_patch_list.append(patch) else: if refined_space: values.LIST_PATCH_SPACE[patch_index] = refined_space updated_patch_list.append(patch) else: # emitter.debug("Removing Patch", patch_list[index]) emitter.emit_patch(patch, message="\t\tRemoving Patch: ") return updated_patch_list
def refine_patch_space(patch_list, path_condition, assertion, force_sequential=False): global pool, result_list result_list = [] emitter.normal("\tupdating patch pool") if values.DEFAULT_OPERATION_MODE in ["sequential"] or force_sequential: for patch in patch_list: index = list(patch_list).index(patch) patch_formula = app.generator.generate_formula_from_patch(patch) patch_formula_extended = generator.generate_extended_patch_formula( patch_formula, path_condition) # emitter.emit_patch(patch, message="\tabstract patch " + str(index) + " :") patch_formula_str = patch_formula.serialize() patch_index = utilities.get_hash(patch_formula_str) patch_space = values.LIST_PATCH_SPACE[patch_index] result_list.append( refine.refine_patch(assertion, patch_formula_extended, path_condition, index, patch_space)) else: emitter.normal("\t\tstarting parallel computing") pool = mp.Pool(mp.cpu_count(), initializer=mute) for patch in patch_list: index = list(patch_list).index(patch) patch_formula = app.generator.generate_formula_from_patch(patch) patch_formula_extended = generator.generate_extended_patch_formula( patch_formula, path_condition) # emitter.emit_patch(patch, message="\tabstract patch " + str(index) + " :") patch_formula_str = patch_formula.serialize() patch_index = utilities.get_hash(patch_formula_str) patch_space = values.LIST_PATCH_SPACE[patch_index] pool.apply_async(refine.refine_patch, args=(assertion, patch_formula_extended, path_condition, index, patch_space), callback=collect_result) pool.close() emitter.normal("\t\twaiting for thread completion") pool.join() return result_list
def run(project_path, program_path): emitter.title("Repairing Program") ## Generate all possible solutions by running the synthesizer. time_check = time.time() # satisfied = utilities.check_budget(values.DEFAULT_TIME_DURATION) initial_patch_list = generator.generate_patch_set(project_path) result_list = parallel.remove_duplicate_patches_parallel( initial_patch_list) filtered_patch_list = [] for result in result_list: is_redundant, index = result patch = initial_patch_list[index] if not is_redundant: filtered_patch_list.append(patch) index_map = generator.generate_patch_index_map(filtered_patch_list) writer.write_as_json(index_map, definitions.FILE_PATCH_RANK_INDEX) for patch in filtered_patch_list: patch_constraint_str = app.generator.generate_formula_from_patch( patch).serialize() patch_index = utilities.get_hash(patch_constraint_str) if patch_index in values.LIST_PATCH_SCORE: emitter.warning("\tcollision detected in patch score map") values.LIST_PATCH_SCORE[patch_index] = 0 values.LIST_PATCH_OVERAPPROX_CHECK[patch_index] = False values.LIST_PATCH_UNDERAPPROX_CHECK[patch_index] = False values.LIST_PATCH_SPACE[patch_index] = generator.generate_patch_space( patch) emitter.note("\t\t|P|=" + str(utilities.count_concrete_patches(filtered_patch_list)) + ":" + str(len(filtered_patch_list))) if values.DEFAULT_PATCH_TYPE == values.OPTIONS_PATCH_TYPE[1]: values.COUNT_PATCH_START = utilities.count_concrete_patches( filtered_patch_list) values.COUNT_TEMPLATE_START = len(filtered_patch_list) else: values.COUNT_PATCH_START = len(filtered_patch_list) duration = format((time.time() - time_check) / 60, '.3f') values.TIME_TO_GENERATE = str(duration) definitions.FILE_PATCH_SET = definitions.DIRECTORY_OUTPUT + "/patch-set-gen" writer.write_patch_set(filtered_patch_list, definitions.FILE_PATCH_SET) if values.CONF_ONLY_GEN: return if values.DEFAULT_REDUCE_METHOD == "cpr": run_cpr(program_path, filtered_patch_list) elif values.DEFAULT_REDUCE_METHOD == "cegis": run_cegis(program_path, project_path, filtered_patch_list) values.COUNT_PATHS_EXPLORED_GEN = len(concolic.list_path_explored) values.COUNT_PATHS_DETECTED = len(concolic.list_path_detected) values.COUNT_PATHS_SKIPPED = len(concolic.list_path_infeasible)
def update_rank_matrix(ranked_patch_list, iteration): rank = 0 for patch in ranked_patch_list: rank = rank + 1 patch_formula = app.generator.generate_formula_from_patch(patch) patch_formula_str = patch_formula.serialize() patch_index = str(utilities.get_hash(patch_formula_str)) if patch_index in values.LIST_PATCH_RANKING: rank_list = values.LIST_PATCH_RANKING[patch_index] rank_list[iteration] = rank else: rank_list = {iteration: rank} values.LIST_PATCH_RANKING[patch_index] = rank_list
def generate_patch_index_map(patch_list): index_map = dict() rank = 0 for patch in patch_list: rank = rank + 1 patch_formula = generate_formula_from_patch(patch) patch_formula_str = patch_formula.serialize() patch_index = utilities.get_hash(patch_formula_str) for (lid, prog) in patch.items(): code = lid + ": " + (program_to_code(prog)) for comp_var, prog_var in values.MAP_PROG_VAR.items(): code = code.replace(comp_var, prog_var) index_map[str(patch_index)] = str(code) values.LIST_PATCH_RANKING[str(patch_index)] = {0: rank} return index_map
def print_patch_list(patch_list): template_count = 0 emitter.sub_title("List of Top " + str(values.DEFAULT_PATCH_RANK_LIMIT) + " Correct Patches") if not patch_list: emitter.warning("\t[warning] unable to generate any patch") return for patch in patch_list: template_count = template_count + 1 emitter.sub_sub_title("Patch #" + str(template_count)) emitter.emit_patch(patch, message="\t\t") patch_formula = app.generator.generate_formula_from_patch(patch) patch_formula_str = patch_formula.serialize() patch_index = utilities.get_hash(patch_formula_str) patch_score = values.LIST_PATCH_SCORE[patch_index] concrete_patch_count = 1 if values.DEFAULT_PATCH_TYPE == values.OPTIONS_PATCH_TYPE[1]: patch_space = values.LIST_PATCH_SPACE[patch_index] partition_count = 0 for partition in patch_space: partition_count = partition_count + 1 emitter.highlight("\t\tPartition: " + str(partition_count)) for constant_name in partition: emitter.highlight("\t\t\tConstant: " + constant_name) constant_info = partition[constant_name] lower_bound = str(constant_info['lower-bound']) upper_bound = str(constant_info['upper-bound']) emitter.highlight("\t\t\tRange: " + lower_bound + " <= " + constant_name + " <= " + upper_bound) dimension = len( range(int(lower_bound), int(upper_bound) + 1)) emitter.highlight("\t\t\tDimension: " + str(dimension)) concrete_patch_count = utilities.count_concrete_patches_per_template( patch) emitter.highlight("\t\tPatch Count: " + str(concrete_patch_count)) emitter.highlight("\t\tPath Coverage: " + str(patch_score)) emitter.highlight( "\t\tIs Under-approximating: " + str(values.LIST_PATCH_UNDERAPPROX_CHECK[patch_index])) emitter.highlight("\t\tIs Over-approximating: " + str(values.LIST_PATCH_OVERAPPROX_CHECK[patch_index])) if template_count == values.DEFAULT_PATCH_RANK_LIMIT: break
def select_patch_constraint_for_input(patch_list, selected_new_path): # relationship = extractor.extract_var_relationship(var_expr_map) # relationship = TRUE # selected_new_path = And(selected_new_path, relationship) result_list = parallel.validate_input_generation(patch_list, selected_new_path) sorted_result_list = sorted(result_list, key=operator.itemgetter(1)) filtered_patch_list = list() for result in sorted_result_list: is_valid, index = result selected_patch = patch_list[index] if is_valid: filtered_patch_list.append(selected_patch) if not filtered_patch_list: # emitter.note("\t\tCount paths explored: " + str(len(list_path_explored))) # emitter.note("\t\tCount paths remaining: " + str(len(list_path_detected))) return None if values.DEFAULT_SELECTION_STRATEGY == "deterministic": selected_patch = filtered_patch_list[0] else: selected_patch = random.choice(filtered_patch_list) emitter.emit_patch(selected_patch, message="\t\tSelected patch: ") patch_formula = app.generator.generate_formula_from_patch(selected_patch) patch_formula_extended = generator.generate_extended_patch_formula( patch_formula, selected_new_path) patch_space_constraint = patch_formula_extended if values.DEFAULT_PATCH_TYPE == values.OPTIONS_PATCH_TYPE[1]: patch_formula_str = str(patch_formula.serialize()) patch_index = utilities.get_hash(patch_formula_str) patch_space = values.LIST_PATCH_SPACE[patch_index] parameter_constraint = smt2.generate_constraint_for_patch_space( patch_space) if parameter_constraint: patch_space_constraint = And(patch_formula_extended, parameter_constraint) # add patch constraint and user-input->prog-var relationship return patch_space_constraint
def write_patch_set(patch_list, output_file_path): emitter.normal("\twriting patch list to file") template_count = 0 txt_lines = [] for patch in patch_list: template_count = template_count + 1 txt_lines.append("Patch #" + str(template_count)) for (lid, prog) in patch.items(): code = lid + ": " + (program_to_code(prog)) for comp_var, prog_var in values.MAP_PROG_VAR.items(): code = code.replace(comp_var, prog_var) txt_lines.append(code) patch_formula = generator.generate_formula_from_patch(patch) patch_formula_str = patch_formula.serialize() patch_index = utilities.get_hash(patch_formula_str) patch_score = values.LIST_PATCH_SCORE[patch_index] concrete_patch_count = 1 if values.DEFAULT_PATCH_TYPE == values.OPTIONS_PATCH_TYPE[1]: patch_space = values.LIST_PATCH_SPACE[patch_index] partition_count = 0 for partition in patch_space: partition_count = partition_count + 1 txt_lines.append("\t\tPartition: " + str(partition_count)) for constant_name in partition: txt_lines.append("\t\t\tConstant: " + constant_name) constant_info = partition[constant_name] lower_bound = str(constant_info['lower-bound']) upper_bound = str(constant_info['upper-bound']) txt_lines.append("\t\t\tRange: " + lower_bound + " <= " + constant_name + " <= " + upper_bound) dimension = len(range(int(lower_bound), int(upper_bound) + 1)) txt_lines.append("\t\t\tDimension: " + str(dimension)) concrete_patch_count = utilities.count_concrete_patches_per_template(patch) txt_lines.append("\t\tPatch Count: " + str(concrete_patch_count)) txt_lines.append("\t\tPath Coverage: " + str(patch_score)) txt_lines.append("\t\tIs Under-approximating: " + str(values.LIST_PATCH_UNDERAPPROX_CHECK[patch_index])) txt_lines.append("\t\tIs Over-approximating: " + str(values.LIST_PATCH_OVERAPPROX_CHECK[patch_index])) with open(output_file_path, 'w') as out_file: out_file.writelines(line + "\n" for line in txt_lines)