def process_definitions(defs, syn_ctx, macro_instantiator): for [name, args_data, ret_type_data, interpretation] in defs: ((arg_vars, arg_types, arg_var_map), return_type) = _process_function_defintion(args_data, ret_type_data) expr = 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) macro_instantiator.add_function(name, macro_func)
def add_dummy_pred(expr): arg_var = exprs.VariableExpression( exprs.VariableInfo(exprtypes.BoolType(), 'd', 0)) dummy_macro_func = semantics_types.MacroFunction( dummy_pred_name, 1, (exprtypes.BoolType(), ), exprtypes.BoolType(), arg_var, [arg_var]) expr = exprs.FunctionExpression(dummy_macro_func, (expr, )) return expr
def decompose(self, macro_instantiator): start_nt = self.start reverse_mapping = [] term_productions = [] pred_productions = [] for rewrite in self.rules[start_nt]: ph_vars, nts, orig_expr_template = rewrite.to_template_expr() ph_var_nt_map = dict(zip(ph_vars, nts)) expr_template = macro_instantiator.instantiate_all( orig_expr_template) ifs = exprs.find_all_applications(expr_template, 'ite') # Either there are no ifs or it is an concrete expression if len(ifs) == 0 or len(nts) == 0: term_productions.append(rewrite) continue elif len(ifs) > 1 and ifs[0] != expr_template: return None [cond, thent, elset] = ifs[0].children cond_ph_vars = exprs.get_all_variables(cond) & set(ph_vars) then_ph_vars = exprs.get_all_variables(thent) & set(ph_vars) else_ph_vars = exprs.get_all_variables(elset) & set(ph_vars) if (len(cond_ph_vars & then_ph_vars) > 0 or len(cond_ph_vars & else_ph_vars) > 0 or len(else_ph_vars & then_ph_vars) > 0): return None if ( thent not in ph_vars or \ elset not in ph_vars or \ ph_var_nt_map[thent] != start_nt or \ ph_var_nt_map[elset] != start_nt): return None cond_rewrite = expr_template_to_rewrite(cond, ph_var_nt_map, self) # Make dummy function to recognize predicate arg_var = exprs.VariableExpression( exprs.VariableInfo(exprtypes.BoolType(), 'd', 0)) dummy_macro_func = semantics_types.MacroFunction( 'dummy_pred_id_' + str(random.randint(1, 1000000)), 1, (exprtypes.BoolType(), ), exprtypes.BoolType(), arg_var, [arg_var]) pred_production = FunctionRewrite(dummy_macro_func, cond_rewrite) pred_productions.append(pred_production) reverse_mapping.append( (dummy_macro_func, cond, orig_expr_template, expr_template)) if len(pred_productions) == 0: return None # Non-terminals [term_start, pred_start] = [x + start_nt for x in ['Term', 'Pred']] [term_nts, pred_nts ] = [self.non_terminals + [x] for x in [term_start, pred_start]] term_nts.remove(start_nt) pred_nts.remove(start_nt) # Non-terminal types term_nt_type, pred_nt_type = self.nt_type.copy(), self.nt_type.copy() term_nt_type.pop(start_nt) term_nt_type[term_start] = self.nt_type[start_nt] pred_nt_type.pop(start_nt) pred_nt_type[pred_start] = exprtypes.BoolType() # Rules term_rules = {} term_rules[term_start] = [ rew.rename_nt(start_nt, term_start) for rew in term_productions ] for nt in self.non_terminals: if nt != start_nt: term_rules[nt] = [ rew.rename_nt(start_nt, term_start) for rew in self.rules[nt] ] pred_rules = {} pred_rules[pred_start] = [ rew.rename_nt(start_nt, term_start) for rew in pred_productions ] for nt in self.non_terminals: if nt != start_nt: pred_rules[nt] = [ rew.rename_nt(start_nt, term_start) for rew in self.rules[nt] ] # pred_rules[term_start] = term_rules[term_start] # pred_nt_type[term_start] = term_nt_type[term_start] pred_rules = {**term_rules, **pred_rules} pred_nt_type = {**term_nt_type, **pred_nt_type} term_grammar = Grammar(term_nts, term_nt_type, term_rules, term_start) pred_grammar = Grammar(pred_nts + [term_start], pred_nt_type, pred_rules, pred_start) # print(pred_grammar) return term_grammar, pred_grammar, reverse_mapping
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