def get_history(expr, pick=None): return get_history_new(expr, pick) def add_child(expr, parent_addr, child_expr): if not (exprs.is_function_expression(expr)): return expr if len(parent_addr) == 0: children = expr.children + (child_expr, ) else: hd, *tl = parent_addr children = list(expr.children) children[hd] = add_child(expr.children[hd], tl, child_expr) children = tuple(children) return exprs.FunctionExpression(expr.function_info, children) def remove_children(expr): if exprs.is_function_expression(expr): expr_wo_children = exprs.FunctionExpression(expr.function_info, ()) else: expr_wo_children = expr return expr_wo_children if not exprs.is_function_expression(expr): return [(expr, ())] stack = [] for i, child in enumerate(expr.children): stack.append((child, [i])) history = [(remove_children(expr), ())] # print(exprs.expression_to_string(expr)) while len(stack) > 0: e, addr = stack.pop(0) # print(addr) # print(exprs.expression_to_string(history[-1])) # add next step if exprs.is_function_expression(e): next_step = add_child( history[-1][0], addr[:-1], exprs.FunctionExpression(e.function_info, ())) history.append((next_step, tuple(addr))) else: next_step = add_child(history[-1][0], addr[:-1], e) history.append((next_step, tuple(addr))) # for online search if pick is not None and pick == tuple(addr): return [history[-1]] # DFS visit if exprs.is_function_expression(e): added = [] for i, child in enumerate(e.children): new_addr = list(addr) new_addr.append(i) added.append((child, new_addr)) stack[0:0] = added # print(exprs.expression_to_string(history[-1][0]), ' ', history[-1][1]) return history
def preprocess_operators(term_exprs, pred_exprs): eval_context = evaluation.EvaluationContext() bitsize = 64 bvlshr = semantics_bv.BVLShR(bitsize) new_term_exprs = set([]) new_pred_exprs = set([]) for term_expr, f in term_exprs: subst_pairs = set([]) all_exprs = exprs.get_all_exprs(term_expr) for e in all_exprs: if exprs.is_function_expression(e): if e.function_info.function_name == 'bvudiv': if exprs.is_constant_expression(e.children[1]): value = evaluation.evaluate_expression_raw( e.children[1], eval_context) new_right_child = exprs.ConstantExpression( exprs.Value( BitVector(int(math.log2(value.value)), bitsize), exprtypes.BitVectorType(bitsize))) subst_pairs.add( (e, exprs.FunctionExpression( bvlshr, (e.children[0], new_right_child)))) new_term_expr = term_expr for (old_term, new_term) in subst_pairs: new_term_expr = exprs.substitute(new_term_expr, old_term, new_term) new_term_exprs.add((new_term_expr, f)) for pred_expr, f in pred_exprs: subst_pairs = set([]) all_exprs = exprs.get_all_exprs(pred_expr) for e in all_exprs: if exprs.is_function_expression(e): if e.function_info.function_name == 'bvudiv': if exprs.is_constant_expression(e.children[1]): value = evaluation.evaluate_expression_raw( e.children[1], eval_context) new_right_child = exprs.ConstantExpression( exprs.Value( BitVector(int(math.log2(value.value)), bitsize), exprtypes.BitVectorType(bitsize))) subst_pairs.add( (e, exprs.FunctionExpression( bvlshr, (e.children[0], new_right_child)))) new_pred_expr = pred_expr for (old_term, new_term) in subst_pairs: new_pred_expr = exprs.substitute(new_pred_expr, old_term, new_term) new_pred_exprs.add((new_pred_expr, f)) return (new_term_exprs, new_pred_exprs)
def _do_transform(self, expr_object, syn_ctx): neg = { '<=': '>', '<': '>=', '>=': '<', '>': '<=', '=': 'ne', 'ne': '=', } if not exprs.is_function_expression(expr_object): return expr_object function_info = expr_object.function_info function_name = function_info.function_name if function_name in ['and', 'or']: children = [ self._do_transform(child, syn_ctx) for child in expr_object.children ] return exprs.FunctionExpression(function_info, tuple(children)) elif function_name in ['<=', '>=', '<', '>', '=', 'eq', 'ne']: children = [ self._do_transform(child, syn_ctx) for child in expr_object.children ] return syn_ctx.make_function_expr(function_name, *children) elif (function_name in ['not'] and exprs.is_function_expression(expr_object.children[0]) and expr_object.children[0].function_info.function_name in ['<=', '>=', '<', '>', '=', 'eq', 'ne']): child = expr_object.children[0] child_func_name = child.function_info.function_name ret_func_name = neg[child_func_name] return syn_ctx.make_function_expr(ret_func_name, *child.children) elif function_name in ['add']: children = [ self._do_transform(child, syn_ctx) for child in expr_object.children ] new_children = [] for child in children: if exprs.is_function_expression( child) and child.function_info.function_name == 'add': new_children.extend(child.children) else: new_children.append(child) return syn_ctx.make_function_expr('add', *new_children) elif function_name in ['sub', 'mul', '-']: children = [ self._do_transform(child, syn_ctx) for child in expr_object.children ] return syn_ctx.make_function_expr(function_name, *children) else: return expr_object
def get_history_new(expr, pick=None): def get_partial_ast(expr, addr): # print('get_partial_ast: ', exprs.expression_to_string(expr), ' ', addr) if len(addr) == 0: if not (exprs.is_function_expression(expr)): return expr else: return exprs.FunctionExpression(expr.function_info, ()) else: hd, *tl = addr rest = get_partial_ast(expr.children[hd], tl) children = expr.children[0:hd] + (rest, ) return exprs.FunctionExpression(expr.function_info, children) def remove_children(expr): if exprs.is_function_expression(expr): expr_wo_children = exprs.FunctionExpression(expr.function_info, ()) else: expr_wo_children = expr return expr_wo_children # for online search if pick is not None: return [(get_partial_ast(expr, pick), ())] if not exprs.is_function_expression(expr): return [(expr, ())] stack = [] for i, child in enumerate(expr.children): stack.append((child, [i])) history = [(remove_children(expr), ())] # print(exprs.expression_to_string(expr)) while len(stack) > 0: e, addr = stack.pop(0) # add next step history.append((get_partial_ast(expr, addr), tuple(addr))) # DFS visit if exprs.is_function_expression(e): added = [] for i, child in enumerate(e.children): new_addr = list(addr) new_addr.append(i) added.append((child, new_addr)) stack[0:0] = added # print(exprs.expression_to_string(history[-1][0]), ' ', history[-1][1]) return history
def get_partial_ast(expr, addr): if not (exprs.is_function_expression(expr)) or len(addr) == 0: return expr else: hd, *tl = addr rest = get_partial_ast(expr.children[hd], tl) children = expr.children[0:hd] + (rest, ) return exprs.FunctionExpression(expr.function_info, children)
def from_expr(expr): if not exprs.is_function_expression(expr): raise NotImplementedError op = expr.function_info.function_name if op not in _op_funcs: raise NotImplementedError left = LIAExpression.from_expr(expr.children[0]) right = LIAExpression.from_expr(expr.children[1]) return LIAInequality(left, op, right)
def expr_template_to_rewrite(expr_template, ph_var_nt_map, grammar): if expr_template in ph_var_nt_map: nt = ph_var_nt_map[expr_template] nt_type = grammar.nt_type[nt] return NTRewrite(nt, nt_type) elif exprs.is_function_expression(expr_template): children = [ expr_template_to_rewrite(child, ph_var_nt_map, grammar) for child in expr_template.children ] return FunctionRewrite(expr_template.function_info, *children) else: return ExpressionRewrite(expr_template)
def fetchop_func_formula(specification, grammar, expr): if (exprs.is_function_expression(expr)): # assert (exprs.is_function_expression(specification.spec_expr)) # origexpr = specification.spec_expr.children[0] result = fetchop(expr) elif (exprs.is_formal_parameter_expression(expr)): # only a single parameter result = aparam_to_string(0) else: result = fetchop(expr) return result
def add_child(expr, parent_addr, child_expr): if not (exprs.is_function_expression(expr)): return expr if len(parent_addr) == 0: children = expr.children + (child_expr, ) else: hd, *tl = parent_addr children = list(expr.children) children[hd] = add_child(expr.children[hd], tl, child_expr) children = tuple(children) return exprs.FunctionExpression(expr.function_info, children)
def fetchop(expr): if (exprs.is_function_expression(expr)): fkind = expr.function_info.function_name if dummy_pred_name in fkind: return dummy_pred_name else: return fkind elif (exprs.is_constant_expression(expr)): # return str(exprs.get_expression_type(expr)) return exprs.expression_to_string(expr) elif (exprs.is_formal_parameter_expression(expr)): return exprs.expression_to_string(expr) else: return 'Var'
def get_partial_ast(expr, addr): # print('get_partial_ast: ', exprs.expression_to_string(expr), ' ', addr) if len(addr) == 0: if not (exprs.is_function_expression(expr)): return expr else: return exprs.FunctionExpression(expr.function_info, ()) else: hd, *tl = addr rest = get_partial_ast(expr.children[hd], tl) children = expr.children[0:hd] + (rest, ) return exprs.FunctionExpression(expr.function_info, children)
def get_addr(partial_ast, target): addr = [] curr_node = partial_ast while curr_node != target: assert (exprs.is_function_expression(curr_node)) children = curr_node.children for (i, child) in enumerate(children): if target in get_all_exprs(child): addr.append(i) curr_node = child break return addr
def simplify_basic(syn_ctx, expr): if not exprs.is_function_expression(expr): return expr func_name = expr.function_info.function_name if func_name not in ['and', 'or', 'not', 'ite']: return expr true = exprs.ConstantExpression(exprs.Value(True, exprtypes.BoolType())) false = exprs.ConstantExpression(exprs.Value(False, exprtypes.BoolType())) if func_name == 'and': cond_children = [simplify_basic(syn_ctx, c) for c in expr.children] cond_true_children = [c for c in cond_children if c != true] cond_false_children = [c for c in cond_children if c == false] if len(cond_false_children) > 0: return false elif len(cond_true_children) == 0: return true elif len(cond_true_children) == 1: return cond_true_children[0] else: return syn_ctx.make_function_expr('and', *cond_true_children) elif func_name == 'or': cond_children = [simplify_basic(syn_ctx, c) for c in expr.children] cond_true_children = [c for c in cond_children if c == true] cond_false_children = [c for c in cond_children if c != false] if len(cond_true_children) > 0: return true elif len(cond_false_children) == 0: return false elif len(cond_false_children) == 1: return cond_false_children[0] else: return syn_ctx.make_function_expr('or', *cond_false_children) elif func_name == 'not': child = simplify_basic(syn_ctx, expr.children[0]) if child == true: return false elif child == false: return true else: return expr else: #ITE cond = simplify_basic(syn_ctx, expr.children[0]) if cond == true: return simplify_basic(syn_ctx, expr.children[1]) elif cond == false: return simplify_basic(syn_ctx, expr.children[2]) else: return syn_ctx.make_function_expr( 'ite', cond, simplify_basic(syn_ctx, expr.children[1]), simplify_basic(syn_ctx, expr.children[2]))
def fetch_prod(partial_ast, curr_addr): curr_node = partial_ast for idx in curr_addr: if exprs.is_function_expression(curr_node) and len( curr_node.children) > 0: if (len(curr_node.children) > idx): curr_node = curr_node.children[idx] else: print(exprs.expression_to_string(curr_node), ' ', idx, ' ', len(curr_node.children)) assert False return curr_node
def get_all_addrs(expr): addrs = set() addrs.add(()) stack = [(expr, [])] while len(stack) > 0: v, addr = stack.pop(0) if exprs.is_function_expression(v): for i, child in enumerate(v.children): new_addr = list(addr) new_addr.append(i) addrs.add(tuple(new_addr)) stack.append((child, new_addr)) return addrs
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
def _do_transform(expr, syn_ctx): if not exprs.is_function_expression(expr): return expr new_children = [ LetFlattener._do_transform(child, syn_ctx) for child in expr.children ] if exprs.is_application_of(expr, 'let'): in_expr = new_children[-1] sub_pairs = list( zip(expr.function_info.binding_vars, new_children[:-1])) return exprs.substitute_all(in_expr, sub_pairs) else: return exprs.FunctionExpression(expr.function_info, tuple(new_children))
def get_all_exprs(expr): result = set([expr]) if exprs.is_function_expression(expr): for child in expr.children: result.update(get_all_exprs(child)) return result
def get_children(node): if exprs.is_function_expression(node): return node.children # return [child for child in node.children if child is not None] else: return []
def remove_children(expr): if exprs.is_function_expression(expr): expr_wo_children = exprs.FunctionExpression(expr.function_info, ()) else: expr_wo_children = expr return expr_wo_children