Beispiel #1
0
 def substitute_hole_in_expression(self, expression, pairs):
     """
     Expression is a z3 expression, and pairs is a list of pairs
     of the form (function declaration representing hole, substitute)
     For now substitute can only be a value.
     TODO: change this so substitute can be a conditional expression as well.
     The latter will require to introduce a 'table variable'.
     """
     assert z3p.is_expr(expression)
     holes = [pair[0] for pair in pairs]
     if z3p.is_bool_or_int_value(expression):
         return expression
     if z3p.is_app(expression):
         declaration = expression.decl()
         for hole, substitute in pairs:
             if declaration == hole:
                 input_variables = [expression.arg(i)
                                    for i in range(expression.num_args())]
                 conditional = constraint_model.lookup_table_to_conditional_expression(substitute, input_variables)
                 # introduce table variable and add table declaration in tables
                 table_id = len(self.tables.keys())
                 table_var_name = 'table_{}'.format(table_id)
                 self.tables[table_var_name] = conditional
                 return z3p.Const(table_var_name, hole.range())
         if expression.num_args() == 2:
             expression1 = self.substitute_hole_in_expression(expression.arg(0), pairs)
             expression2 = self.substitute_hole_in_expression(expression.arg(1), pairs)
             operator = expression.decl()
             return operator(expression1, expression2)
     return expression
 def lookup_table_for_function(self, function_name):
     """Returns a model for the function as a dictionary.
     The dictionary has tuples of argument values as keys. In particular,
     if the function has a single argument, the key will still be a single element tuple.
     """
     assert (function_name in self.function_names and
             function_name in self.z3_functions_by_name)
     z3_function = self.z3_functions_by_name[function_name]
     model = self.solver.model()
     table = {}
     for i in self.function_name_to_domain_values[function_name]:
         table[i] = model.evaluate(z3_function(i))
         # If a value is unconstrained the z3 model might just return
         # a variable back, therefore for the boolean case
         if not z3p.is_bool_or_int_value(table[i]) and table[i].sort() == z3p.BoolSort():
             # a constant value is returned here.
             table[i] = z3p.BoolVal(False)
     return table
Beispiel #3
0
def evaluate_expression(expression,
                        symbolic_memory,
                        concrete_memory,
                        tables=None):
    if isinstance(expression, int):
        return expression
    if isinstance(expression, tuple):
        return expression
    if z3p.is_const(expression):
        if z3p.is_bool_or_int_value(expression):
            return expression
        if expression in symbolic_memory:
            return symbolic_memory[expression]
        elif expression.decl().name().startswith('table_'):
            assert expression.decl().name() in tables
            table_expression = tables[expression.decl().name()]
            first_value = table_expression[0][1]
            if first_value.sort() == z3p.IntSort():
                last_else = z3p.IntVal(0)
            else:
                last_else = z3p.BoolVal(False)
            if_expression = None
            for conditional, value in table_expression:
                guard = evaluate_expression(conditional, symbolic_memory,
                                            concrete_memory)
                last_else = z3p.If(guard, value, last_else)
            return z3p.simplify(last_else)
        else:
            return concrete_memory[expression]
    elif expression.decl().kind() == z3p.Z3_OP_SELECT:
        if expression in symbolic_memory:
            return symbolic_memory[expression]
        else:
            return concrete_memory[expression]
    else:
        new_args = [
            evaluate_expression(expression.arg(i), symbolic_memory,
                                concrete_memory, tables)
            for i in range(expression.num_args())
        ]
        if expression.decl().kind() == z3p.Z3_OP_AND:
            return z3p.And(*new_args)
        else:
            return expression.decl()(*new_args)
 def lookup_table_for_function(self, function_name):
     """Returns a model for the function as a dictionary.
     The dictionary has tuples of argument values as keys. In particular,
     if the function has a single argument, the key will still be a single element tuple.
     """
     assert (function_name in self.function_names
             and function_name in self.z3_functions_by_name)
     z3_function = self.z3_functions_by_name[function_name]
     model = self.solver.model()
     table = {}
     for i in self.function_name_to_domain_values[function_name]:
         table[i] = model.evaluate(z3_function(i))
         # If a value is unconstrained the z3 model might just return
         # a variable back, therefore for the boolean case
         if not z3p.is_bool_or_int_value(
                 table[i]) and table[i].sort() == z3p.BoolSort():
             # a constant value is returned here.
             table[i] = z3p.BoolVal(False)
     return table
Beispiel #5
0
def evaluate_expression(expression, symbolic_memory, concrete_memory, tables=None):
    if isinstance(expression, int):
        return expression
    if isinstance(expression, tuple):
        return expression
    if z3p.is_const(expression):
        if z3p.is_bool_or_int_value(expression):
            return expression
        if expression in symbolic_memory:
            return symbolic_memory[expression]
        elif expression.decl().name().startswith('table_'):
            assert expression.decl().name() in tables
            table_expression = tables[expression.decl().name()]
            first_value = table_expression[0][1]
            if first_value.sort() == z3p.IntSort():
                last_else = z3p.IntVal(0)
            else:
                last_else = z3p.BoolVal(False)
            if_expression = None
            for conditional, value in table_expression:
                guard = evaluate_expression(conditional, symbolic_memory, concrete_memory)
                last_else = z3p.If(guard, value, last_else)
            return z3p.simplify(last_else)
        else:
            return concrete_memory[expression]
    elif expression.decl().kind() == z3p.Z3_OP_SELECT:
        if expression in symbolic_memory:
            return symbolic_memory[expression]
        else:
            return concrete_memory[expression]
    else:
        new_args = [evaluate_expression(expression.arg(i), symbolic_memory, concrete_memory, tables)
                    for i in range(expression.num_args())]
        if expression.decl().kind() == z3p.Z3_OP_AND:
            return z3p.And(*new_args)
        else:
            return expression.decl()(*new_args)