def which_fix_goes_first(program, fix1, fix2): try: fix1_location = extract_line_number(' '.join(fix1.split()[1:])) fix2_location = extract_line_number(' '.join(fix2.split()[1:])) except Exception: #print fix1 #print fix2 raise if not fix_ids_are_in_program(recompose_program(get_lines(program)[fix2_location:]), fix2) and fix_ids_are_in_program(recompose_program(get_lines(program)[fix1_location:]), fix1): return fix1 if not fix_ids_are_in_program(recompose_program(get_lines(program)[fix1_location:]), fix1) and fix_ids_are_in_program(recompose_program(get_lines(program)[fix2_location:]), fix2): return fix2 if not fix_ids_are_in_program(recompose_program(get_lines(program)[fix1_location:]), fix1) and not fix_ids_are_in_program(recompose_program(get_lines(program)[fix2_location:]), fix2): raise CouldNotFindUsesForEitherException if fix1_location < fix2_location: return fix1 elif fix2_location < fix1_location: return fix2 prog_lines = get_lines(program) id_in_fix1 = None id_in_fix2 = None for token in fix1.split(): if '_<id>_' in token: assert id_in_fix1 == None, fix1 id_in_fix1 = token elif token == '_<op>_[': break for token in fix2.split(): if '_<id>_' in token: assert id_in_fix2 == None, fix2 id_in_fix2 = token elif token == '_<op>_[': break assert id_in_fix1 != id_in_fix2, fix1 + ' & ' + fix2 assert fix1_location == fix2_location for i in range(fix1_location, len(prog_lines)): for token in prog_lines[i].split(): if token == id_in_fix1: return fix1 elif token == id_in_fix2: return fix2 assert False, 'unreachable code' raise CouldNotFindUsesForEitherException
def id_mutate(rng, prog, max_num_mutations, num_mutated_progs, exact=False, name_dict=None): assert max_num_mutations > 0 and num_mutated_progs > 0, "Invalid argument(s) supplied to the function token_mutate" corrupted = [] fixes = [] for _ in range(num_mutated_progs): tokens = prog if exact: num_mutations = max_num_mutations else: num_mutations = rng.choice(range(max_num_mutations)) + 1 mutation_count = 0 fix_line = None for _ in range(num_mutations): # Step 2: Induce _[ONE]_ mutation, removing empty lines and shifting program if required try: mutated, this_fix, _ = undeclare_variable(rng, tokens, tokens) mutation_count += 1 # Couldn't delete anything except NothingToMutateException: break # Insertion or something failed except FailedToMutateException: raise # Deleted something that can't be fixed (all uses gone from the program) else: # REPLACE! program with mutated version tokens = mutated if not fix_ids_are_in_program(mutated, this_fix): # Discarding previous fix: all uses are gone continue # Update fix line if fix_line is not None: fix_line = which_fix_goes_first(mutated, fix_line, this_fix) else: fix_line = this_fix if fix_line is not None: corrupted.append(tokens) fixes.append(fix_line) for fix in fixes: assert fix is not None return zip(corrupted, fixes)
def token_mutate(prog, max_num_mutations, num_mutated_progs, exact=False, name_dict=None): assert max_num_mutations > 0 and num_mutated_progs > 0, "Invalid argument(s) supplied to the function token_mutate" corrupted = [] fixes = [] for _ in range(num_mutated_progs): tokens = prog if exact: num_mutations = max_num_mutations else: num_mutations = random.choice(range(max_num_mutations)) + 1 # num_undeclared = np.min([np.random.poisson(num_mutations/5), num_mutations]) deleted_vars = [] mutation_count = 0 # loop_counter = 0 # loop_count_threshold = 50 fix = None fix_line = None # last_id = get_last_id(tokens) # extra_ids = {} #print tokens_to_source(tokens, name_dict, clang_format=True) for _ in range(num_mutations): # Step 2: Induce _[ONE]_ mutation, removing empty lines and shifting program if required try: mutated, this_fix, _ = undeclare_variable(tokens, tokens, deleted_vars, name_dict) mutation_count += 1 #print tokens_to_source(mutated, name_dict, clang_format=True) #print pretty_fix(this_fix, name_dict) #print #print "--------" #print # Couldn't delete anything except NothingToMutateException: break # Insertion or something failed except FailedToMutateException: #print '{insertion position} or {declaration} localization failed' #print prog raise continue # Deleted something that can't be fixed (all uses gone from the program) else: # REPLACE! program with mutated version tokens = mutated if not fix_ids_are_in_program(mutated, this_fix): #print 'Discarding previous fix: all uses are gone' continue # Update fix line if fix_line is not None: fix_line = which_fix_goes_first(mutated, fix_line, this_fix) else: fix_line = this_fix if fix_line != None: corrupted.append(tokens) fixes.append(fix_line) for fix in fixes: assert (fix is not None) return zip(corrupted, fixes)