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 selects_in_expression(expression): expressions = [expression] selects = [] while len(expressions) > 0: expression = expressions.pop(0) if z3p.is_const(expression): continue elif z3p.is_app(expression): if expression.decl().kind() == z3p.Z3_OP_SELECT: selects.append(expression) else: for i in range(expression.num_args()): expressions.append(expression.arg(i)) return selects