示例#1
0
 def apply(self, *args):
     if (len(args) != 2):
         raise basetypes.ArgumentError(
             'NNFConverter.apply() must be called with an ' +
             'expression object and a synthesis context object')
     simple_expr = self._eliminate_complex(args[0], args[1])
     return self._do_transform(simple_expr, args[1], True)
示例#2
0
 def make_placeholder(self, identifier):
     if (identifier in self.generator_map):
         raise basetypes.ArgumentError(
             'Identifier already used as placeholder!')
     retval = _RecursiveGeneratorPlaceholder(self, identifier)
     self.generator_map[identifier] = retval
     return retval
示例#3
0
 def apply(self, *args):
     if (len(args) != 2):
         raise basetypes.ArgumentError(
             'CNFConverter.apply() must be called with ' +
             'an expression and a synthesis context object')
     nnf_converter = NNFConverter()
     nnf_expr = nnf_converter.apply(args[0], args[1])
     flatted_nnf_expr = self._flatten_and_or(nnf_expr, args[1])
     clauses = self._do_transform(flatted_nnf_expr, args[1])
     return (clauses, args[1].make_ac_function_expr('and', *clauses))
    def make_function_expr(self, function_name_or_info, *child_exps):
        """Makes a typed function expression applied to the given child expressions."""

        if (isinstance(function_name_or_info, str)):
            function_info = self.make_function(function_name_or_info,
                                               *child_exps)
            function_name = function_name_or_info
        else:
            assert (isinstance(function_name_or_info,
                               semantics_types.FunctionBase))
            function_info = function_name_or_info
            function_name = function_info.function_name

        if (function_info == None):
            raise basetypes.ArgumentError(
                'Could not instantiate function named "' + function_name +
                '" with argument types: (' + ', '.join(
                    [str(exprs.get_expression_type(x))
                     for x in child_exps]) + ')')

        return exprs.FunctionExpression(function_info, tuple(child_exps))
示例#5
0
def canonicalize_specification(expr, syn_ctx, theory):
    """Performs a bunch of operations:
    1. Checks that the expr is "well-bound" to the syn_ctx object.
    2. Checks that the specification has the single-invocation property.
    3. Gathers the set of synth functions (should be only one).
    4. Gathers the variables used in the specification.
    5. Converts the specification to CNF (as part of the single-invocation test)
    6. Given that the spec is single invocation, rewrites the CNF spec (preserving and sat)
       by introducing new variables that correspond to a uniform way of invoking the
       (single) synth function

    Returns a tuple containing:
    1. A list of 'variable_info' objects corresponding to the variables used in the spec
    2. A list of synth functions (should be a singleton list)
    3. A list of clauses corresponding to the CNF specification
    4. A list of NEGATED clauses
    5. A list containing the set of formal parameters that all appearances of the synth
       functions are invoked with.
    """
    check_expr_binding_to_context(expr, syn_ctx)
    clauses, cnf_expr = to_cnf(expr, theory, syn_ctx)

    synth_function_set = gather_synth_functions(expr)
    synth_function_list = list(synth_function_set)
    num_funs = len(synth_function_list)

    orig_variable_set = gather_variables(expr)
    orig_variable_list = [x.variable_info for x in orig_variable_set]
    orig_variable_list.sort(key=lambda x: x.variable_name)

    # check single invocation/separability properties
    if (not check_single_invocation_property(clauses, syn_ctx)):
        raise basetypes.ArgumentError('Spec:\n%s\nis not single-invocation!' %
                                      exprs.expression_to_string(expr))

    (intro_clauses,
     intro_vars) = _intro_new_universal_vars(clauses, syn_ctx,
                                             synth_function_list[0])

    # ensure that the intro_vars at the head of the list
    # Arjun: Why? Most likely not necessary
    variable_list = [x.variable_info for x in intro_vars] + orig_variable_list
    num_vars = len(variable_list)
    for i in range(num_vars):
        variable_list[i].variable_eval_offset = i
    num_funs = len(synth_function_list)
    for i in range(num_funs):
        synth_function_list[i].synth_function_id = i

    if len(intro_clauses) == 1:
        canon_spec = intro_clauses[0]
    else:
        canon_spec = syn_ctx.make_function_expr('and', *intro_clauses)

    canon_clauses = []
    for ic in intro_clauses:
        if exprs.is_application_of(ic, 'or'):
            disjuncts = ic.children
        else:
            disjuncts = [ic]
        canon_clauses.append(disjuncts)

    return (variable_list, synth_function_list, canon_spec, canon_clauses,
            intro_vars)
示例#6
0
 def apply(self, *args):
     if (len(args) != 2):
         raise basetypes.ArgumentError(
             'LIAFlattener.apply() must be called with an ' +
             'expression object and a synthesis context object')
     return self._do_transform(args[0], args[1])