Beispiel #1
0
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
Beispiel #2
0
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
Beispiel #3
0
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
Beispiel #4
0
    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
Beispiel #5
0
 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
Beispiel #6
0
 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
Beispiel #8
0
 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
Beispiel #9
0
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
Beispiel #10
0
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
Beispiel #11
0
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