def get_constraints(current_spec): '''Generates a new distinguishing input which is not a part of the existing specification Arguments: - current_spec (str): The specification for the problem including the existing constraints for the problem. Returns: - list: contains all the specifications ''' file_sexp = parser.sexpFromFile(current_spec) benchmark_tuple = parser.extract_benchmark(file_sexp) ( theories, syn_ctx, synth_instantiator, macro_instantiator, uf_instantiator, constraints, grammar_map, forall_vars_map, default_grammar_sfs ) = benchmark_tuple inputs = [] vals= [] for constraint in constraints: inputs.append(constraint.children[0].children[0].value_object.value_object) vals.append(constraint.children[1].value_object.value_object) result=[] for i in range(0,len(inputs)): result.append(inputs[i]+'; '+vals[i]) #print(result) return result
def make_solver(file_sexp): benchmark_tuple = parser.extract_benchmark(file_sexp) (theories, syn_ctx, synth_instantiator, macro_instantiator, uf_instantiator, constraints, grammar_map, forall_vars_map) = benchmark_tuple assert len(theories) == 1 theory = theories[0] solvers = [ #("LIA Unification", lia_unification_solver), ("STD Unification", std_unification_solver), #("Classic Esolver", classic_esolver), #("Memoryless Esolver", memoryless_esolver) ] rewritten_constraints = utils.timeout( massage_constraints, (syn_ctx, macro_instantiator, uf_instantiator, theory, constraints), {}, timeout_duration=120, default=None) if rewritten_constraints is not None: constraints = rewritten_constraints else: solvers = [("Memoryless Esolver", memoryless_esolver)] synth_funs = list(synth_instantiator.get_functions().values()) specification, verifier = make_specification(synth_funs, theory, syn_ctx, constraints) solver_args = (theory, syn_ctx, synth_funs, grammar_map, specification, verifier) for solver_name, solver in solvers: try: print("Trying solver:", solver_name) final_solutions = solver(*solver_args) if final_solutions == "NO SOLUTION": print("(fail)") else: print("FINAL_SOLUTION") print_solutions(synth_funs, final_solutions) break except UnsuitableSolverException as exception: print(exception) pass else: # print("Unable to solve!") pass
def evaluate(expr, input, synth_file='./euphony/benchmarks/string/test/phone-5-test.sl'): '''Evaluate an expression for a given input Arguments: - expr(FunctionExpression): The expression to evaluate - input(str): the input to the given expression. - synth_file(str): path to a synthesis file defining the available available grammar. This file doesn't need to correspond to the same file that the expression was generated from. It just needs to have the same grammar definition. Constraints are not used in any way. It's required in order to load the proper logic into the expression evaluator. This is set to a file containing string logic by default. Returns: - (str): output from evaluating expression against given input ''' eval_ctx = EvaluationContext() val_map = (Value(input, value_type=StringType()),) eval_ctx.set_valuation_map(val_map) # print('attempting to eval: {}'.format(expr)) # print('eval ctx: {} -- {}'.format(val_map, type(val_map))) # This is pretty flow since it needs to re-read the synthesis file to know # the grammar that it needs to parse. Personally, I am not so concerned # about performance, but rather just getting it to work in the first place. file_sexp = parser.sexpFromFile(synth_file) benchmark_tuple = parser.extract_benchmark(file_sexp) ( theories, syn_ctx, synth_instantiator, macro_instantiator, uf_instantiator, constraints, grammar_map, forall_vars_map, default_grammar_sfs ) = benchmark_tuple # We should only have one grammar, so just grab the only key to this map. # The type of the object is a SynthFun #print(constraints) synth_fun = list(grammar_map.keys())[0] # Pass this into the interpretation along with the expression we're # attempting to evaluate, or else we'll get an UnboundLetException eval_ctx.set_interpretation(synth_fun, expr) return evaluate_expression_raw(expr, eval_ctx)
def get_specification(file_sexp): benchmark_tuple = parser.extract_benchmark(file_sexp) (theories, syn_ctx, synth_instantiator, macro_instantiator, uf_instantiator, constraints, grammar_map, forall_vars_map, default_grammar_sfs) = benchmark_tuple assert len(theories) == 1 theory = theories[0] # XXX : to avoid getting stuck in massaging constraints # rewritten_constraints = utils.timeout( # massage_constraints, # (syn_ctx, macro_instantiator, uf_instantiator, theory, constraints), # {}, # timeout_duration=120, # default=None # ) # constraints = rewritten_constraints synth_funs = list(synth_instantiator.get_functions().values()) specification, _ = make_specification(synth_funs, theory, syn_ctx, constraints) return specification
def print_stat(benchmark_files, phog_file): from os.path import basename for benchmark_file in benchmark_files: # print('loading: ', benchmark_file) file_sexp = parser.sexpFromFile(benchmark_file) benchmark_tuple = parser.extract_benchmark(file_sexp) (theories, syn_ctx, synth_instantiator, macro_instantiator, uf_instantiator, constraints, grammar_map, forall_vars_map, default_grammar_sfs) = benchmark_tuple assert len(theories) == 1 theory = theories[0] specification = get_specification(file_sexp) synth_funs = list(synth_instantiator.get_functions().values()) grammar = grammar_map[synth_funs[0]] phog = SPhog(grammar, phog_file, synth_funs[0].range_type, specification) if options.use_sphog() else \ Phog(grammar, phog_file, synth_funs[0].range_type) defs, _ = parser.filter_sexp_for('define-fun', file_sexp) if defs is None or len(defs) == 0: print('cannot find a solution!') exit(0) [name, args_data, ret_type_data, interpretation] = defs[-1] ((arg_vars, arg_types, arg_var_map), return_type) = parser._process_function_defintion( args_data, ret_type_data) expr = parser.sexp_to_expr(interpretation, syn_ctx, arg_var_map) i = 0 subs_pairs = [] for (var_expr, ty) in zip(arg_vars, arg_types): param_expr = exprs.FormalParameterExpression(None, ty, i) subs_pairs.append((var_expr, param_expr)) i += 1 expr = exprs.substitute_all(expr, subs_pairs) score = phog.get_score(expr) print(basename(benchmark_file), ' \t', score)
def make_solver(file_sexp, phog_file, rcfg_file): benchmark_tuple = parser.extract_benchmark(file_sexp) (theories, syn_ctx, synth_instantiator, macro_instantiator, uf_instantiator, constraints, grammar_map, forall_vars_map, default_grammar_sfs) = benchmark_tuple assert len(theories) == 1 theory = theories[0] solvers = [("LIA Unification", lia_unification_solver), ("STD Unification", std_unification_solver), ("Classic Esolver", classic_esolver), ("Memoryless Esolver", memoryless_esolver)] # for constraint in constraints: # inputs = constraint.children[0].children # output = constraint.children[1] # print('%s\t%s' % (' '.join([exprs.expression_to_string(input) for input in inputs]), exprs.expression_to_string(output))) # # exit(0) rewritten_constraints = utils.timeout( massage_constraints, (syn_ctx, macro_instantiator, uf_instantiator, theory, constraints), {}, timeout_duration=120, default=None) if rewritten_constraints is not None: constraints = rewritten_constraints else: solvers = [ # ("LIA Unification", lia_unification_solver), ("Memoryless Esolver", memoryless_esolver) ] # add constant rules + add nt addrs (for PHOG) # for sf in grammar_map.keys(): # if sf in default_grammar_sfs: # grammar_map[sf].add_constant_rules(phog.collect_constants_from_phog(phog_file, sf.range_type)) # RCFG for sf in grammar_map.keys(): if not sf in default_grammar_sfs: grammar_map[ sf] = grammar_map[sf] if rcfg_file == '' else augment_grammar( grammar_map[sf], rcfg_file) grammar_map[sf].compute_rule_to_nt_addrs() synth_funs = list(synth_instantiator.get_functions().values()) specification, verifier = make_specification(synth_funs, theory, syn_ctx, constraints) solver_args = (theory, syn_ctx, synth_funs, grammar_map, specification, verifier, phog_file) for solver_name, solver in solvers: try: #print("Trying solver:", solver_name) final_solutions = solver(*solver_args) if final_solutions == "NO SOLUTION": print("(fail)") else: print_solutions(synth_funs, final_solutions) break except UnsuitableSolverException as exception: pass #print(exception) else: print("Unable to solve!")
def generate_distinguishing_input(current_spec, candidate_programs, failure_threshold=100, args=None): '''Generates a new distinguishing input which is not a part of the existing specification Arguments: - current_spec (str): The specification for the problem including the existing constraints for the problem. Returns: - str: a string representing the distinguishing input not part of the current specification. Also can return None if no distinguishing input can be found. ''' file_sexp = parser.sexpFromFile(current_spec) benchmark_tuple = parser.extract_benchmark(file_sexp) ( theories, syn_ctx, synth_instantiator, macro_instantiator, uf_instantiator, constraints, grammar_map, forall_vars_map, default_grammar_sfs ) = benchmark_tuple inputs = [] for constraint in constraints: inputs.append(constraint.children[0].children[0].value_object.value_object) #print(inputs) import string_builder inputs_r = [string_builder.RString(inp) for inp in inputs] #print(inputs_r) print_grid = lambda x: [print(item) for item in x] def distances(input_list, distfunc): dists = [] for x in input_list: # print(x) # print(x.groupstr) curr_dists = [] for y in input_list: curr_dists.append(distfunc(x, y)) dists.append(curr_dists) # print_grid(dists) return dists # find the metric which varies the least between all the examples char_dist = distances(inputs_r, lambda x, y: x.orig_distance(y)) class_dist = distances(inputs_r, lambda x, y: x.class_distance(y)) group_dist = distances(inputs_r, lambda x, y: x.group_distance(y)) vals = { 'char': char_dist, 'class': class_dist, 'group': group_dist } stats = {} for key in vals: val = vals[key] tril = np.tril(np.array(val)) mu = tril.mean() std = tril.std() stats[key] = string_builder.TextStats(mu, std) # print("{}: mean: {}; std: {}".format(key, mu, std)) stat_set = string_builder.EditStatSet(stats['char'], stats['class'], stats['group']) distinguishing_input = None loop_count = 0 total_generated = 0 while True: distinguished = None for constraint_input in inputs_r: mutated = constraint_input.generate_mutation(stat_set) total_generated += 1 # run input across all outputs to see if there is an input which returns more # than one unique result. results = set([evaluate(expression, mutated, current_spec) for expression in candidate_programs]) if len(results) > 1: if args is not None and args.auto: distinguishing_input = mutated distinguished = True break selected = input('Found a distinguishing input ({}). Programs generated outputs: {}. Acceptable? (Y)es/(n)o/(f)inish: '.format(mutated, results)).lower() if selected == '' or selected == 'y' or selected == 'f': distinguishing_input = mutated distinguished = True break if distinguished is not None: break loop_count += 1 if loop_count > failure_threshold: break if args is not None and args.verbose: print("returning input {}. Total generated inputs: {}".format(distinguishing_input, total_generated)) return distinguishing_input