示例#1
0
def rewrite_arbitrary_arity_and_or(syn_ctx, sol):
    import functools
    apps = exprs.find_all_applications(sol, 'and')
    for app in apps:
        if len(app.children) == 2:
            continue
        elif len(app.children) == 1:
            new_app = syn_ctx.make_function_expr('and', app.children[0],
                                                 app.children[0])
        else:
            new_app = functools.reduce(
                lambda a, b: syn_ctx.make_function_expr('and', a, b),
                app.children)
        sol = exprs.substitute(sol, app, new_app)

    new_apps = exprs.find_all_applications(sol, 'and')
    assert all([len(new_app.children) == 2 for new_app in new_apps])

    apps = exprs.find_all_applications(sol, 'or')
    for app in apps:
        if len(app.children) == 2:
            continue
        elif len(app.children) == 1:
            new_app = syn_ctx.make_function_expr('or', app.children[0],
                                                 app.children[0])
        else:
            new_app = functools.reduce(
                lambda a, b: syn_ctx.make_function_expr('or', a, b),
                app.children)
        sol = exprs.substitute(sol, app, new_app)

    new_apps = exprs.find_all_applications(sol, 'or')
    assert all([len(new_app.children) == 2 for new_app in new_apps])

    return sol
示例#2
0
 def get_applications(self):
     applications = {}
     for sf in self.synth_funs:
         sf_name = sf.function_name
         apps = exprs.find_all_applications(self.spec_expr, sf_name)
         applications[sf] = apps
     return applications
示例#3
0
    def apply(constraints, uf_instantiator, syn_ctx):
        import random
        conds = []
        all_apps = set()
        for uf_name, uf_info in uf_instantiator.get_functions().items():
            uf_apps = set()
            for c in constraints:
                uf_apps |= set(exprs.find_all_applications(c, uf_name))
            all_apps |= uf_apps

            while len(uf_apps) > 0:
                uf_app1 = uf_apps.pop()
                for uf_app2 in uf_apps:
                    app1_args, app2_args = uf_app1.children, uf_app2.children
                    args_eq_expr = [
                        syn_ctx.make_function_expr('=', a1, a2)
                        for (a1, a2) in zip(app1_args, app2_args)
                    ]
                    output_neq_expr = syn_ctx.make_function_expr(
                        'ne', uf_app1, uf_app2)
                    cond = syn_ctx.make_function_expr('and', output_neq_expr,
                                                      *args_eq_expr)
                    conds.append(cond)

        if len(conds) > 0:
            constraints = [
                syn_ctx.make_function_expr('or', *conds, constraint)
                for constraint in constraints
            ]
        for app in sorted(all_apps, key=exprs.get_expression_size):
            var = syn_ctx.make_variable_expr(
                app.function_info.range_type,
                'ufcall_' + app.function_info.function_name + '_' +
                str(random.randint(1, 1000000)))
            constraints = [
                exprs.substitute(constraint, app, var)
                for constraint in constraints
            ]
        return constraints
示例#4
0
文件: grammars.py 项目: wslee/euphony
    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