def massage_full_lia_solution(syn_ctx, synth_funs, final_solution, massaging): # for sf in final_solution: # print(exprs.expression_to_string(sf)) try: new_final_solution = [] for sf, sol in zip(synth_funs, final_solution): if sf not in massaging: new_final_solution.append(sol) continue (boolean_combs, comparators, consts, negatives, constant_multiplication, div, mod) = massaging[sf] # Don't try to rewrite div's and mod's # It is futile if not div and exprs.find_application(sol, 'div') != None: return None if not mod and exprs.find_application(sol, 'mod') != None: return None terms = get_terms(sol) for term in terms: termp = rewrite_term(syn_ctx, term, negatives, consts, constant_multiplication) if termp is None: return None sol = exprs.substitute(sol, term, termp) aps = get_atomic_preds(sol) for ap in aps: new_ap = rewrite_pred(syn_ctx, ap, boolean_combs, comparators, negatives, consts, constant_multiplication) if new_ap is None: # print(exprs.expression_to_string(ap)) return None sol = exprs.substitute(sol, ap, new_ap) sol = simplify(syn_ctx, sol) if not boolean_combs: # print(exprs.expression_to_string(sol)) # sol = rewrite_boolean_combs(syn_ctx, sol) sol = dt_rewrite_boolean_combs(syn_ctx, sol, sf) else: sol = rewrite_arbitrary_arity_and_or(syn_ctx, sol) if not \ verify(sol, boolean_combs, comparators, consts, negatives, constant_multiplication, div, mod): return None new_final_solution.append(sol) return new_final_solution except: raise
def rewrite_boolean_combs(syn_ctx, sol): import functools if not exprs.is_application_of(sol, 'ite'): return sol cond = sol.children[0] child1 = rewrite_boolean_combs(syn_ctx, sol.children[1]) child2 = rewrite_boolean_combs(syn_ctx, sol.children[2]) if not exprs.is_function_expression(cond): return syn_ctx.make_function_expr('ite', cond, child1, child2) fun = cond.function_info.function_name if fun not in ['and', 'or', 'not']: return syn_ctx.make_function_expr('ite', cond, child1, child2) if fun == 'not': return syn_ctx.make_function_expr('ite', cond.children[0], child2, child1) elif len(cond.children) == 1: return syn_ctx.make_function_expr('ite', cond.children[0], child1, child2) if fun == 'or': init = child2 combine = lambda a, b: syn_ctx.make_function_expr('ite', b, child1, a) cond_children = cond.children if any([ exprs.find_application(c, 'and') is not None or exprs.find_application(c, 'or') is not None for c in cond_children ]): ret = rewrite_boolean_combs( syn_ctx, functools.reduce(combine, cond.children, init)) else: ret = functools.reduce(combine, cond.children, init) return ret else: init = child1 combine = lambda a, b: syn_ctx.make_function_expr('ite', b, a, child2) cond_children = cond.children if any([ exprs.find_application(c, 'and') is not None or exprs.find_application(c, 'or') is not None for c in cond_children ]): ret = rewrite_boolean_combs( syn_ctx, functools.reduce(combine, cond.children, init)) else: ret = functools.reduce(combine, cond.children, init) return ret
def rewrite_solution(synth_funs, solution, reverse_mapping): # Rewrite any predicates introduced in grammar decomposition if reverse_mapping is not None: for function_info, cond, orig_expr_template, expr_template in reverse_mapping: while True: app = exprs.find_application(solution, function_info.function_name) if app is None: break assert exprs.is_application_of(expr_template, 'ite') ite = exprs.parent_of(solution, app) ite_without_dummy = exprs.FunctionExpression(ite.function_info, (app.children[0], ite.children[1], ite.children[2])) var_mapping = exprs.match(expr_template, ite_without_dummy) new_ite = exprs.substitute_all(orig_expr_template, var_mapping.items()) solution = exprs.substitute(solution, ite, new_ite) # Rewrite back into formal parameters if len(synth_funs) == 1: sols = [solution] else: # The solution will be a comma operator combination of solution # to each function sols = solution.children rewritten_solutions = [] for sol, synth_fun in zip(sols, synth_funs): variables = exprs.get_all_formal_parameters(sol) substitute_pairs = [] orig_vars = synth_fun.get_named_vars() for v in variables: substitute_pairs.append((v, orig_vars[v.parameter_position])) sol = exprs.substitute_all(sol, substitute_pairs) rewritten_solutions.append(sol) return rewritten_solutions
def __init__(self, spec): super().__init__() self.points = [] self.signatures = {} self.cache = {} self.base_generators = {} self.finished_generators = {} self.eval_ctx = evaluation.EvaluationContext() self.cache_sizes = [] self.all_caches = [] if spec.is_multipoint: assert len(spec.synth_funs) == 1 self.applications = spec.get_applications()[spec.synth_funs[0]] for app in self.applications: for child in app.children: if exprs.find_application( child, spec.synth_funs[0].function_name) is not None: raise Exception( "Unable to form point out of forall variables") self.point_profiles = [] else: self.applications = None self.point_profiles = None
def get_all_atomic_pred_expr(expr): result = set([]) app = exprs.find_application(expr, 'ite') if app is not None: result.add(expr.children[0]) for child in expr.children: result.update(get_all_atomic_pred_expr(child)) return result else: return result
def get_all_atomic_term_expr(expr): result = set([]) # macro functions involving ite have been resolved. app = exprs.find_application(expr, 'ite') if app is not None: for child in expr.children: result.update(get_all_atomic_term_expr(child)) return result else: if not is_bool_expr(expr): result.add(expr) return result
def instantiate_all(self, expr): instantiated_one = False while not instantiated_one: instantiated_one = True for fname, fint in self.function_interpretations.items(): while True: app = exprs.find_application(expr, fname) if app is None: break instantiated_one = False actual_params = app.children formal_params = fint.formal_parameters new_app = exprs.substitute_all( fint.interpretation_expression, list(zip(formal_params, actual_params))) expr = exprs.substitute(expr, app, new_app) return expr
def apply(constraints, syn_ctx): new_constraints = [] found_one = False for constraint in constraints: ite = exprs.find_application(constraint, 'ite') if ite is None: new_constraints.append(constraint) continue else: found_one = True cond, tt, ff = ite.children tc = syn_ctx.make_function_expr( 'or', exprs.substitute(constraint, ite, tt), syn_ctx.make_function_expr('not', cond)) fc = syn_ctx.make_function_expr( 'or', exprs.substitute(constraint, ite, ff), cond) new_constraints.append(tc) new_constraints.append(fc) if found_one: return RewriteITE.apply(new_constraints, syn_ctx) else: return new_constraints
def verify(expr, boolean_combs, comparators, consts, negatives, constant_multiplication, div, mod): if not constant_multiplication and exprs.find_application(expr, '*') is not None: return False if not negatives and exprs.find_application(expr, '-') is not None: return False used_consts = set( [e.value_object.value_object for e in exprs.get_all_constants(expr)]) if not used_consts.issubset(consts): return False if not boolean_combs and (exprs.find_application(expr, 'and') is not None or exprs.find_application(expr, 'or') is not None or exprs.find_application(expr, 'not') is not None): return False used_comparators = set() for c in ['<', '<=', '=', 'ne', '>', '>=']: if exprs.find_application(expr, c) is not None: used_comparators.add(c) if not used_comparators.issubset(comparators): return False return True
def get_func_exprs_grammars(benchmark_files): global eu # Grammars results = [] # for eusolver ite_related_macros = [] for benchmark_file in benchmark_files: fun_exprs = [] print('Loading : ', benchmark_file) file_sexp = parser.sexpFromFile(benchmark_file) if file_sexp is None: continue core_instantiator = semantics_core.CoreInstantiator() theory_instantiators = [ parser.get_theory_instantiator(theory) for theory in parser._known_theories ] macro_instantiator = semantics_core.MacroInstantiator() uf_instantiator = semantics_core.UninterpretedFunctionInstantiator() synth_instantiator = semantics_core.SynthFunctionInstantiator() syn_ctx = synthesis_context.SynthesisContext(core_instantiator, *theory_instantiators, macro_instantiator, uf_instantiator, synth_instantiator) syn_ctx.set_macro_instantiator(macro_instantiator) defs, _ = parser.filter_sexp_for('define-fun', file_sexp) if defs is None: defs = [] for [name, args_data, ret_type_data, interpretation] in defs: for eusolver in ([True, False] if eu else [False]): ((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) macro_func = semantics_types.MacroFunction( name, len(arg_vars), tuple(arg_types), return_type, expr, arg_vars) # for eusolver (recording macro functions of which definition include ite) if eusolver: app = exprs.find_application(expr, 'ite') if app is not None: ite_related_macros.append(name) macro_instantiator.add_function(name, macro_func) 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) # resolve macro functions involving ite (for enumeration of pred exprs (eusolver)) if eusolver: for fname in ite_related_macros: app = exprs.find_application(expr, fname) if app is None: continue expr = macro_instantiator.instantiate_macro( expr, fname) fun_exprs.append(expr) @static_var("cnt", 0) def rename(synth_funs_data): for synth_fun_data in synth_funs_data: # to avoid duplicated names synth_fun_data[0] = "__aux_name__" + benchmark_file + str( rename.cnt) rename.cnt += 1 # collect grammars synth_funs_data, _ = parser.filter_sexp_for('synth-fun', file_sexp) if len(synth_funs_data) == 0: synth_funs_data, _ = parser.filter_sexp_for('synth-inv', file_sexp) rename(synth_funs_data) synth_funs_grammar_data = parser.process_synth_invs( synth_funs_data, synth_instantiator, syn_ctx) else: rename(synth_funs_data) synth_funs_grammar_data = parser.process_synth_funcs( synth_funs_data, synth_instantiator, syn_ctx) grammar = None for synth_fun, arg_vars, grammar_data in synth_funs_grammar_data: if grammar_data != 'Default grammar': # we only consider a single function synthesis for now grammar = parser.sexp_to_grammar(arg_vars, grammar_data, synth_fun, syn_ctx) break results.append((fun_exprs, grammar)) return results
def get_func_exprs_grammars(benchmark_files): # expected format: # sygus format problem # (check-synth) # a single solution global eu @static_var("cnt", 0) def rename(synth_funs_data): for synth_fun_data in synth_funs_data: # to avoid duplicated names synth_fun_data[0] = "__aux_name__" + benchmark_file + str( rename.cnt) rename.cnt += 1 exprs_per_category = {} # decision tree : label -> exprs ## label : (ret_type, eu, STD spec / PBE spec, spec information ... ) # for eusolver ite_related_macros = [] # all vocabs all_vocabs = set([]) for benchmark_file in benchmark_files: print('Loading : ', benchmark_file) file_sexp = parser.sexpFromFile(benchmark_file) if file_sexp is None: continue ## specification specification = get_specification(file_sexp) all_vocabs.update(basic_vocabs_for_spec(specification)) core_instantiator = semantics_core.CoreInstantiator() theory_instantiators = [ parser.get_theory_instantiator(theory) for theory in parser._known_theories ] macro_instantiator = semantics_core.MacroInstantiator() uf_instantiator = semantics_core.UninterpretedFunctionInstantiator() synth_instantiator = semantics_core.SynthFunctionInstantiator() syn_ctx = synthesis_context.SynthesisContext(core_instantiator, *theory_instantiators, macro_instantiator, uf_instantiator, synth_instantiator) syn_ctx.set_macro_instantiator(macro_instantiator) # collect grammars synth_funs_data, _ = parser.filter_sexp_for('synth-fun', file_sexp) if len(synth_funs_data) == 0: synth_funs_data, _ = parser.filter_sexp_for('synth-inv', file_sexp) # rename(synth_funs_data) synth_funs_grammar_data = parser.process_synth_invs( synth_funs_data, synth_instantiator, syn_ctx) else: # rename(synth_funs_data) synth_funs_grammar_data = parser.process_synth_funcs( synth_funs_data, synth_instantiator, syn_ctx) # handling only single function problems for now fetchop_func = fetchop spec_flag = () synth_fun_name = '' for synth_fun, arg_vars, grammar_data in synth_funs_grammar_data: if grammar_data != 'Default grammar': synth_fun_name = synth_fun.function_name grammar = parser.sexp_to_grammar(arg_vars, grammar_data, synth_fun, syn_ctx) # spec flag spec_flag = get_spec_flag(specification, grammar) # fetchop func fetchop_func = get_fetchop_func(specification, grammar) all_vocabs.update( get_vocabs_from_grammar(grammar, fetchop_func)) defs, _ = parser.filter_sexp_for('define-fun', file_sexp) if defs is None: defs = [] if len(defs) > 0: for [name, args_data, ret_type_data, interpretation] in defs: print(name, ' ', synth_fun_name) if synth_fun_name in name: for eusolver in ([True] if eu else [False]): ((arg_vars, arg_types, arg_var_map), return_type) = parser._process_function_defintion( args_data, ret_type_data) # category flag flag = (return_type, eusolver, spec_flag) expr = parser.sexp_to_expr(interpretation, syn_ctx, arg_var_map) macro_func = semantics_types.MacroFunction( name, len(arg_vars), tuple(arg_types), return_type, expr, arg_vars) # for eusolver (recording macro functions of which definition include ite) if eusolver: app = exprs.find_application(expr, 'ite') if app is not None: ite_related_macros.append(name) macro_instantiator.add_function(name, macro_func) 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) # resolve macro functions involving ite (for enumeration of pred exprs (eusolver)) if eusolver: for fname in ite_related_macros: app = exprs.find_application(expr, fname) if app is None: continue expr = macro_instantiator.instantiate_macro( expr, fname) if flag not in exprs_per_category: exprs_per_category[flag] = set([]) exprs_per_category[flag].add((expr, fetchop_func)) return exprs_per_category, all_vocabs