def split_sum_s_expr(expr, solv, extra_defs, typ): """divides up a linear expression 'a - b - 1 + a' into ({'a':2, 'b': -1}, -1) i.e. 'a' times 2 etc and constant value of -1.""" def rec(expr): return split_sum_s_expr(expr, solv, extra_defs, typ) if expr[0] == 'bvadd': var = {} const = 0 for x in expr[1:]: (var2, const2) = rec(x) for (v, count) in var2.iteritems(): var.setdefault(v, 0) var[v] += count const += const2 return (var, const) elif expr[0] == 'bvsub': (_, lhs, rhs) = expr (lvar, lconst) = rec(lhs) (rvar, rconst) = rec(rhs) const = lconst - rconst var = dict([(v, lvar.get(v, 0) - rvar.get(v, 0)) for v in set.union(set(lvar), set(rvar))]) return (var, const) elif expr in solv.defs: return rec(solv.defs[expr]) elif expr in extra_defs: return rec(extra_defs[expr]) elif expr[:2] in ['#x', '#b']: val = solver.smt_to_val(expr) assert val.kind == 'Num' return ({}, val.val) else: return ({expr: 1}, 0)
def split_sum_s_expr (expr, solv, extra_defs): """divides up a linear expression 'a - b - 1 + a' into ({'a':2, 'b': -1}, -1)""" if expr[0] == 'bvadd': var = {} const = 0 for x in expr[1:]: (var2, const2) = split_sum_s_expr (x, solv, extra_defs) for (v, count) in var2.iteritems (): var.setdefault (v, 0) var[v] += count const += const2 return (var, const) elif expr[0] == 'bvsub': (_, lhs, rhs) = expr (lvar, lconst) = split_sum_s_expr (lhs, solv, extra_defs) (rvar, rconst) = split_sum_s_expr (rhs, solv, extra_defs) const = lconst - rconst var = dict ([(v, lvar.get (v, 0) - rvar.get (v, 0)) for v in set.union (set (lvar), set (rvar))]) return (var, const) elif expr in solv.defs: return split_sum_s_expr (solv.defs[expr], solv, extra_defs) elif expr in extra_defs: return split_sum_s_expr (extra_defs[expr], solv, extra_defs) elif expr[:2] in ['#x', '#b']: val = solver.smt_to_val (expr) assert val.kind == 'Num' return ({}, val.val) else: return ({expr: 1}, 0)
def eval_model (m, s, toplevel = None): if s in m: return m[s] if toplevel == None: toplevel = s if type (s) == str: try: result = solver.smt_to_val (s) except Exception, e: trace ('Error with eval_model') trace (toplevel) raise e return result
def str_to_num(smt_str): v = solver.smt_to_val(smt_str) return expr_num(v)