def make_linear_term(syn_ctx, v, c, consts, neg, constant_multiplication): if c == 1: return v if c in consts and constant_multiplication: return syn_ctx.make_function_expr( '*', v, exprs.ConstantExpression(exprs.Value(c, exprtypes.IntType()))) if neg and 0 in consts and (-c) in consts and constant_multiplication: return syn_ctx.make_function_expr( '-', exprs.ConstantExpression(exprs.Value(0, exprtypes.IntType())), syn_ctx.make_function_expr( '*', v, exprs.ConstantExpression(exprs.Value(-c, exprtypes.IntType())))) if neg and c < 0: return syn_ctx.make_function_expr( '-', exprs.ConstantExpression(exprs.Value(0, exprtypes.IntType())), make_linear_term(syn_ctx, v, -c, consts, neg, constant_multiplication)) if c > 0: ret = v for x in range(1, c): ret = syn_ctx.make_function_expr('+', v, ret) return ret return None
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 term_to_expr(var, coeff): if var == 1: term = exprs.ConstantExpression( exprs.Value(coeff, exprtypes.IntType())) else: if coeff == 1: term = var else: coeff_expr = exprs.ConstantExpression( exprs.Value(coeff, exprtypes.IntType())) term = syn_ctx.make_function_expr('mul', var, coeff_expr) return term
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 make_constant_rules(constraints): constants = set() for constraint in constraints: constants |= exprs.get_all_constants(constraint) constants.add(exprs.ConstantExpression(exprs.Value(1, exprtypes.IntType(), -1))) constants.add(exprs.ConstantExpression(exprs.Value(0, exprtypes.IntType(), -1))) const_templates = [] for const in constants: const_template = grammars.ExpressionRewrite(const) const_templates.append(const_template) return const_templates
def to_expr(self, syn_ctx): def term_to_expr(var, coeff): if var == 1: term = exprs.ConstantExpression( exprs.Value(coeff, exprtypes.IntType())) else: if coeff == 1: term = var else: coeff_expr = exprs.ConstantExpression( exprs.Value(coeff, exprtypes.IntType())) term = syn_ctx.make_function_expr('mul', var, coeff_expr) return term terms = [ term_to_expr(var, coeff) for var, coeff in self.coeffs.items() if coeff != 0 ] if len(terms) == 0: return exprs.ConstantExpression(exprs.Value( 0, exprtypes.IntType())) else: return reduce(lambda a, b: syn_ctx.make_function_expr('+', a, b), terms)
def _trivial_solve(self): ret = exprs.ConstantExpression(exprs.Value(0, exprtypes.IntType())) if len(self.synth_funs) > 1: domain_types = tuple([exprtypes.IntType()] * len(self.synth_funs)) ret = exprs.FunctionExpression(semantics_core.CommaFunction(domain_types), tuple([ret] * len(self.synth_funs))) self.signature_to_term = {None:ret} return True
def _process_rule(non_terminals, nt_type, syn_ctx, arg_vars, var_map, synth_fun, rule_data): ph_let_bound_vars, let_bound_vars = [], [] if type(rule_data) == tuple: value = sexp_to_value(rule_data) ret = grammars.ExpressionRewrite(exprs.ConstantExpression(value)) elif rule_data[0] == 'Constant': typ = sexp_to_type(rule_data[1]) ret = grammars.NTRewrite('Constant' + str(typ), typ) elif rule_data[0] in [ 'Variable', 'InputVariable', 'LocalVariable' ]: raise NotImplementedError('Variable rules in grammars') elif type(rule_data) == str: if rule_data in [ a.variable_info.variable_name for a in arg_vars ]: (parameter_position, variable) = next((i, x) for (i, x) in enumerate(arg_vars) if x.variable_info.variable_name == rule_data) expr = exprs.FormalParameterExpression(synth_fun, variable.variable_info.variable_type, parameter_position) ret = grammars.ExpressionRewrite(expr) elif rule_data in non_terminals: ret = grammars.NTRewrite(rule_data, nt_type[rule_data]) elif rule_data in var_map: ret = grammars.ExpressionRewrite(var_map[rule_data]) else: # Could be a 0 arity function func = syn_ctx.make_function(rule_data) if func != None: ret = grammars.ExpressionRewrite(syn_ctx.make_function_expr(rule_data)) else: # Could be a let bound variable bound_var_ph = exprs.VariableExpression(exprs.VariableInfo(exprtypes.BoolType(), 'ph_' + rule_data)) ph_let_bound_vars.append(bound_var_ph) ret = grammars.ExpressionRewrite(bound_var_ph) elif type(rule_data) == list: function_name = rule_data[0] if function_name != 'let': function_args = [] for child in rule_data[1:]: ph_lbv, lbv, arg = _process_rule(non_terminals, nt_type, syn_ctx, arg_vars, var_map, synth_fun, child) ph_let_bound_vars.extend(ph_lbv) let_bound_vars.extend(lbv) function_args.append(arg) function_arg_types = tuple([ x.type for x in function_args ]) function = syn_ctx.make_function(function_name, *function_arg_types) else: def child_processing_func(rd, syn_ctx, new_var_map): ph_lbv, lbv, a = _process_rule(non_terminals, nt_type, syn_ctx, arg_vars, new_var_map, synth_fun, rd) ph_let_bound_vars.extend(ph_lbv) let_bound_vars.extend(lbv) return a def get_return_type(r): return r.type function, function_args = sexp_to_let(rule_data, syn_ctx, child_processing_func, get_return_type, var_map) let_bound_vars.extend(function.binding_vars) assert function is not None ret = grammars.FunctionRewrite(function, *function_args) else: raise Exception('Unknown right hand side: %s' % rule_data) return ph_let_bound_vars, let_bound_vars, ret
def string_to_constant_rewrite(topsymb): if topsymb.isdigit() or (topsymb.startswith('-') and len(topsymb) >= 2 and topsymb[1:].isdigit): num = -1 * int(topsymb[1:]) if topsymb.startswith('-') else int( topsymb) return grammars.ExpressionRewrite( exprs.ConstantExpression(exprs.Value(num, exprtypes.IntType()))) elif topsymb.startswith('#x'): # bitvector num = int('0' + topsymb[1:], 16) bitsize = (len(topsymb) - 2) * 4 return grammars.ExpressionRewrite( exprs.ConstantExpression( exprs.Value(num, exprtypes.BitVectorType(bitsize)))) else: # boolean return grammars.ExpressionRewrite( exprs.ConstantExpression( exprs.Value(bool(topsymb), exprtypes.BoolType())))
def solve_inequalities_one_outvar(model, outvar, inequalities, syn_ctx): if len(inequalities) == 0: return [exprs.ConstantExpression(exprs.Value(0, exprtypes.IntType()))] bounds = [ineq.get_bounds(outvar) for ineq in inequalities] eqs = [(c, eq_exp) for (c, (_, eq_exp, _)) in bounds if eq_exp is not None] lbs = [(c, lb_exp) for (c, (lb_exp, _, _)) in bounds if lb_exp is not None] ubs = [(c, ub_exp) for (c, (_, _, ub_exp)) in bounds if ub_exp is not None] # Equalities if len(eqs) > 0: rhs = eqs[0][1].to_expr(syn_ctx) if eqs[0][0] == 1: return [rhs] else: return [ syn_ctx.make_function_expr( 'div', rhs, exprs.ConstantExpression( exprs.Value(eqs[0][0], exprtypes.IntType()))) ] # Upper bounds if len(ubs) > 0: tightest_ub = min(ubs, key=lambda a: a[1].eval(model) / a[0]) if tightest_ub is not None: coeff = tighest_ub[0] rhs = tightest_ub[1].to_expr(syn_ctx) if coeff == 1: return [rhs] else: return [ syn_ctx.make_function_expr( 'div', rhs, exprs.ConstantExpression( exprs.Value(coeff, exprtypes.IntType()))) ] # Lower bounds if len(lbs) > 0: tightest_lb = max(lbs, key=lambda a: a[1].eval(model) / a[0]) if tightest_lb is not None: coeff = tightest_lb[0] rhs = tightest_lb[1].to_expr(syn_ctx) if coeff == 1: return [rhs] return [ syn_ctx.make_function_expr( 'div', syn_ctx.make_function_expr( 'add', rhs, exprs.ConstantExpression( exprs.Value(1, exprtypes.IntType()))), exprs.ConstantExpression( exprs.Value(coeff, exprtypes.IntType()))) ] return exprs.ConstantExpression(exprs.Value(0, exprtypes.IntType()))
def rewrite_pred(syn_ctx, pred, boolean_combs, comparators, neg, consts, constant_multiplication): liaineq = LIAInequality.from_expr(pred).to_positive_form() if liaineq.is_valid(): if len(consts) > 0: return exprs.ConstantExpression( exprs.Value(True, exprtypes.BoolType())) else: return None (left, op, right) = (liaineq.left, liaineq.op, liaineq.right) negate = {'<': '>=', '>': '<=', '>=': '<', '<=': '>'} flip = {'<': '>', '>': '<', '>=': '<=', '<=': '>='} addNot = False if op not in comparators: if op in negate and negate[op] in comparators: (left, op, right) = (left, negate[op], right) addNot = True elif op in flip and flip[op] in comparators: (left, op, right) = (right, flip[op], left) elif op == '=' and ('<=' in comparators or '>=' in comparators): new_op = '<=' if '<=' in comparators else '>=' p1 = syn_ctx.make_function_expr(new_op, pred.children[0], pred.children[1]) p2 = syn_ctx.make_function_expr(new_op, pred.children[1], pred.children[0]) return syn_ctx.make_function_expr( 'and', rewrite_pred(syn_ctx, p1, boolean_combs, comparators, neg, consts, constant_multiplication), rewrite_pred(syn_ctx, p2, boolean_combs, comparators, neg, consts, constant_multiplication)) else: return None liaineq = LIAInequality(left, op, right).to_positive_form() left_term = rewrite_lia_term(syn_ctx, liaineq.left, neg, consts, constant_multiplication) right_term = rewrite_lia_term(syn_ctx, liaineq.right, neg, consts, constant_multiplication) if left_term is None or right_term is None: return None ret = syn_ctx.make_function_expr(liaineq.op, left_term, right_term) if addNot: ret = syn_ctx.make_function_expr('not', ret) return ret
def _single_solve_single_point(self, ivs, point): syn_ctx = self.syn_ctx smt_ctx = self.smt_ctx eval_ctx = self.eval_ctx spec = self.rewritten_spec # Find one value of output eq_constrs = [] for var, value in zip(self.point_var_exprs, point): c = self.syn_ctx.make_function_expr( 'eq', exprs.ConstantExpression(value), var) eq_constrs.append(c) full_constr = self.syn_ctx.make_function_expr('and', spec, *eq_constrs) raw_z3_model = exprs.sample(full_constr, smt_ctx, self.all_vars_z3) # print("B1:", raw_z3_model) model = dict( zip(self.all_vars, [z3_value.as_long() for z3_value in raw_z3_model])) # print("B2:") # for var, val in model.items(): # print("\t", exprs.expression_to_string(var), "--->", val) # Find the first disjunct that # (a) Is true in this model # (b) Contains some outvar # print("B3:") # for clause in self.lia_clauses: # for disj in clause: # print(str(disj), end=" , ") # print() ineqs = [] outvar_set = set(self.outvars) for clause in self.lia_clauses: for disjunct in clause: # print(str(disjunct) + " --> " + str(disjunct.eval(model))) # print(str(disjunct) + " --> " + str(len(outvar_set & disjunct.get_variables()))) if disjunct.eval(model) and len( outvar_set & disjunct.get_variables()) > 0: ineqs.append(disjunct) break # print("B3:") # for ineq in ineqs: # print("\t", str(ineq)) return lia_utils.solve_inequalities(model, self.outvars, ineqs, syn_ctx)
def sexp_to_expr(sexp, syn_ctx, arg_var_map): # Must be a value if type(sexp) == tuple: value = sexp_to_value(sexp) return exprs.ConstantExpression(value) elif type(sexp) == str: if sexp in arg_var_map: return arg_var_map[sexp] else: # Could be a zero-argument function return syn_ctx.make_function_expr(sexp) elif type(sexp) == list: if sexp[0] != 'let': func = sexp[0] children = [ sexp_to_expr(child, syn_ctx, arg_var_map) for child in sexp[1:] ] else: func, children = sexp_to_let(sexp, syn_ctx, sexp_to_expr, exprs.get_expression_type, arg_var_map) return syn_ctx.make_function_expr(func, *children) else: raise Exception('Unknown sexp type: %s', str(sexp))
def rewrite_lia_term(syn_ctx, lia_term, neg, consts, constant_multiplication): c = lia_term.get_const() linear_terms = [ make_linear_term(syn_ctx, v, coeff, consts, neg, constant_multiplication) for (v, coeff) in lia_term.get_var_coeff_pairs() ] if c != 0: new_term = make_constant(syn_ctx, c, consts, neg) if new_term is None: return None elif len(linear_terms) > 0: new_term = linear_terms[0] linear_terms = linear_terms[1:] else: if 0 in consts: return exprs.ConstantExpression(exprs.Value( 0, exprtypes.IntType())) else: return None for nt in linear_terms: new_term = syn_ctx.make_function_expr('+', nt, new_term) return new_term
def make_constant(syn_ctx, c, consts, neg): if c in consts: return exprs.ConstantExpression(exprs.Value(c, exprtypes.IntType())) if -c in consts and neg and 0 in consts: return syn_ctx.make_function_expr( '-', exprs.ConstantExpression(exprs.Value(0, exprtypes.IntType())), exprs.ConstantExpression(exprs.Value(-c, exprtypes.IntType()))) if c > 0: ret = exprs.ConstantExpression(exprs.Value(1, exprtypes.IntType())) for x in range(1, c): ret = syn_ctx.make_function_expr( '+', ret, exprs.ConstantExpression(exprs.Value(1, exprtypes.IntType()))) return ret elif c < 0 and neg and 0 in consts: return syn_ctx.make_function_expr( '-', exprs.ConstantExpression(exprs.Value(0, exprtypes.IntType())), make_constant(syn_ctx, -c, consts, neg)) return None
from parsers import parser from core import synthesis_context from semantics import semantics_core from semantics import semantics_types from core import synthesis_context import random import pickle import itertools # import numpy as np # import matplotlib.pyplot as plt # import networkx as nx from sphogs.sphog_utils import * from utils import z3smt max_score = 9999999.0 original_expr_to_compare = exprs.ConstantExpression(exprs.Value(True, exprtypes.BoolType())) class PriorityQueue: def __init__(self): self.heap = [] self.elements = set([]) self.nelem = 0 def empty(self): return (self.nelem == 0) def get(self): pri, d = heapq.heappop(self.heap) self.nelem -= 1 self.elements.remove(d) return pri, d
# # # Code: from eusolver import BitSet from semantics import semantics_core from unifiers.unifiers import UnifierInterface from exprs import evaluation from exprs import exprs from exprs import exprtypes from utils.lia_utils import LIAInequality _expr_to_str = exprs.expression_to_string _true_expr = exprs.ConstantExpression(exprs.Value(True, exprtypes.BoolType())) _false_expr = exprs.ConstantExpression(exprs.Value(False, exprtypes.BoolType())) def simplify_inequality(inequality): if LIAInequality.from_expr(inequality).is_valid(): return _true_expr return inequality def _filter_to_intro_vars(clauses, intro_vars): only_intro_var_clauses = [] for clause in clauses: new_clause = [] for disjunct in clause:
def make_constant_expr(self, const_type, const_value): """Makes a typed constant expression with the given value.""" assert (isinstance(const_type, exprtypes.TypeBase)) return exprs.ConstantExpression(exprs.Value(const_type, const_value))
def _generate_test_generators(): from core import synthesis_context from semantics import semantics_core from semantics import semantics_lia syn_ctx = synthesis_context.SynthesisContext( semantics_core.CoreInstantiator(), semantics_lia.LIAInstantiator()) var_a_info = syn_ctx.make_variable(exprtypes.IntType(), 'varA', 0) var_b_info = syn_ctx.make_variable(exprtypes.IntType(), 'varB', 1) var_c_info = syn_ctx.make_variable(exprtypes.IntType(), 'varC', 2) var_a = exprs.VariableExpression(var_a_info) var_b = exprs.VariableExpression(var_b_info) var_c = exprs.VariableExpression(var_c_info) zero_value = exprs.Value(0, exprtypes.IntType()) one_value = exprs.Value(1, exprtypes.IntType()) zero_exp = exprs.ConstantExpression(zero_value) one_exp = exprs.ConstantExpression(one_value) var_generator = LeafGenerator([var_a, var_b, var_c], 'Variable Generator') const_generator = LeafGenerator([zero_exp, one_exp], 'Constant Generator') leaf_generator = AlternativesGenerator([var_generator, const_generator], 'Leaf Term Generator') generator_factory = RecursiveGeneratorFactory() start_generator_ph = generator_factory.make_placeholder('Start') start_bool_generator_ph = generator_factory.make_placeholder('StartBool') add_fun = syn_ctx.make_function('add', exprtypes.IntType(), exprtypes.IntType()) sub_fun = syn_ctx.make_function('sub', exprtypes.IntType(), exprtypes.IntType()) ite_fun = syn_ctx.make_function('ite', exprtypes.BoolType(), exprtypes.IntType(), exprtypes.IntType()) and_fun = syn_ctx.make_function('and', exprtypes.BoolType(), exprtypes.BoolType()) or_fun = syn_ctx.make_function('or', exprtypes.BoolType(), exprtypes.BoolType()) not_fun = syn_ctx.make_function('not', exprtypes.BoolType()) le_fun = syn_ctx.make_function('le', exprtypes.IntType(), exprtypes.IntType()) ge_fun = syn_ctx.make_function('ge', exprtypes.IntType(), exprtypes.IntType()) eq_fun = syn_ctx.make_function('eq', exprtypes.IntType(), exprtypes.IntType()) start_generator = \ generator_factory.make_generator('Start', AlternativesGenerator, ([leaf_generator] + [FunctionalGenerator(add_fun, [start_generator_ph, start_generator_ph]), FunctionalGenerator(sub_fun, [start_generator_ph, start_generator_ph]), FunctionalGenerator(ite_fun, [start_bool_generator_ph, start_generator_ph, start_generator_ph])],)) generator_factory.make_generator('StartBool', AlternativesGenerator, ([ FunctionalGenerator( and_fun, [start_bool_generator_ph, start_bool_generator_ph]), FunctionalGenerator( or_fun, [start_bool_generator_ph, start_bool_generator_ph]), FunctionalGenerator(not_fun, [start_bool_generator_ph]), FunctionalGenerator(le_fun, [start_generator_ph, start_generator_ph]), FunctionalGenerator(eq_fun, [start_generator_ph, start_generator_ph]), FunctionalGenerator(ge_fun, [start_generator_ph, start_generator_ph]) ], )) return start_generator
def make_true_expr(self): """Makes an expression representing the Boolean constant TRUE.""" return exprs.ConstantExpression(exprs.Value(True, exprtypes.BoolType()))
def make_default_grammar(syn_ctx, theory, return_type, args): int_type = exprtypes.IntType() bool_type = exprtypes.BoolType() if theory == 'LIA': [start, start_bool, const] = ['Start', 'StartBool', 'ConstantIntegerType'] nts = [start, start_bool, const] nt_type = {start: int_type, start_bool: bool_type, const: int_type} rules = {start: [], start_bool: [], const: []} ntr_start = NTRewrite(start, int_type) ntr_startbool = NTRewrite(start_bool, bool_type) ntr_const = NTRewrite(const, int_type) [ add_func, sub_func, mul_func, div_func, mod_func ] = \ [ syn_ctx.make_function(name, int_type, int_type) for name in [ 'add', 'sub', 'mul', 'div', 'mod' ] ] ite_func = syn_ctx.make_function('ite', bool_type, int_type, int_type) [ and_func, or_func ] = \ [ syn_ctx.make_function(name, bool_type, bool_type) for name in [ 'and', 'or' ] ] not_func = syn_ctx.make_function('not', bool_type) [ eq_func, ne_func, le_func, lt_func, ge_func, gt_func ] = \ [ syn_ctx.make_function(name, int_type, int_type) for name in [ '=', 'ne', '<=', '<', '>=', '>' ] ] # Start rules: # Args for arg in args: if exprs.get_expression_type(arg) == int_type: rules[start].append(ExpressionRewrite(arg)) elif exprs.get_expression_type(arg) == bool_type: rules[start_bool].append(ExpressionRewrite(arg)) # Constants rules[start].append( ExpressionRewrite( exprs.ConstantExpression(exprs.Value(1, int_type)))) rules[start].append( ExpressionRewrite( exprs.ConstantExpression(exprs.Value(0, int_type)))) rules[start].append(ntr_const) # Start + Start, Start - Start, rules[start].append(FunctionRewrite(add_func, ntr_start, ntr_start)) rules[start].append(FunctionRewrite(sub_func, ntr_start, ntr_start)) # Start * Constant, Start / Constant, Start mod Constant rules[start].append(FunctionRewrite(mul_func, ntr_start, ntr_start)) rules[start].append(FunctionRewrite(div_func, ntr_start, ntr_start)) rules[start].append(FunctionRewrite(mod_func, ntr_start, ntr_start)) # ITE rules[start].append( FunctionRewrite(ite_func, ntr_startbool, ntr_start, ntr_start)) # Start bool rules # And, or, not rules[start_bool].append( ExpressionRewrite( exprs.ConstantExpression(exprs.Value(False, bool_type)))) rules[start_bool].append( ExpressionRewrite( exprs.ConstantExpression(exprs.Value(True, bool_type)))) rules[start_bool].append( FunctionRewrite(and_func, ntr_startbool, ntr_startbool)) rules[start_bool].append( FunctionRewrite(or_func, ntr_startbool, ntr_startbool)) rules[start_bool].append(FunctionRewrite(not_func, ntr_startbool)) # comparison ops rules[start_bool].append(FunctionRewrite(eq_func, ntr_start, ntr_start)) rules[start_bool].append(FunctionRewrite(ne_func, ntr_start, ntr_start)) rules[start_bool].append(FunctionRewrite(le_func, ntr_start, ntr_start)) rules[start_bool].append(FunctionRewrite(lt_func, ntr_start, ntr_start)) rules[start_bool].append(FunctionRewrite(ge_func, ntr_start, ntr_start)) rules[start_bool].append(FunctionRewrite(gt_func, ntr_start, ntr_start)) # Constant rules rules[const].append( ExpressionRewrite( exprs.ConstantExpression(exprs.Value(1, int_type)))) rules[const].append( ExpressionRewrite( exprs.ConstantExpression(exprs.Value(0, int_type)))) rules[const].append(FunctionRewrite(add_func, ntr_const, ntr_const)) rules[const].append(FunctionRewrite(add_func, ntr_const, ntr_const)) rules[const].append(FunctionRewrite(sub_func, ntr_const, ntr_const)) if return_type == int_type: ret = Grammar(nts, nt_type, rules, start) elif return_type == bool_type: ret = Grammar(nts, nt_type, rules, start_bool) else: raise NotImplementedError ret.from_default = True return ret elif theory == 'BV': from semantics import semantics_bv from semantics import semantics_core print("ARSAYS: Default bit-vec grammar shouldn't be used!") (start, start_bool) = ('Start', 'StartBool') bv_size = 64 nts = [start, start_bool] (bv_type, bool_type) = (exprtypes.BitVectorType(bv_size), exprtypes.BoolType()) nt_type = {start: bv_type, start_bool: bool_type} rules = {start: [], start_bool: []} ntr_start = NTRewrite(start, bv_type) ntr_start_bool = NTRewrite(start_bool, bool_type) rules[start].extend( map( lambda x: ExpressionRewrite( exprs.ConstantExpression(exprs.Value(x, bv_type))), [0, 1])) for func in [ semantics_bv.BVNot(bv_size), semantics_bv.BVAdd(bv_size), semantics_bv.BVAnd(bv_size), semantics_bv.BVOr(bv_size), semantics_bv.BVNeg(bv_size), semantics_bv.BVAdd(bv_size), semantics_bv.BVMul(bv_size), semantics_bv.BVSub(bv_size), semantics_bv.BVUDiv(bv_size), semantics_bv.BVSDiv(bv_size), semantics_bv.BVSRem(bv_size), semantics_bv.BVURem(bv_size), semantics_bv.BVShl(bv_size), semantics_bv.BVLShR(bv_size), semantics_bv.BVAShR(bv_size), semantics_bv.BVUlt(bv_size), semantics_bv.BVUle(bv_size), semantics_bv.BVUge(bv_size), semantics_bv.BVUgt(bv_size), semantics_bv.BVSle(bv_size), semantics_bv.BVSlt(bv_size), semantics_bv.BVSge(bv_size), semantics_bv.BVSgt(bv_size), semantics_bv.BVXor(bv_size), semantics_bv.BVXNor(bv_size), semantics_bv.BVNand(bv_size), semantics_bv.BVNor(bv_size), # semantics_bv.BVComp(bv_size) semantics_core.EqFunction(bv_type) ]: assert all([t == bv_type for t in func.domain_types]) args = [ntr_start] * len(func.domain_types) if func.range_type == bv_type: rules[start].append(FunctionRewrite(func, *args)) elif func.range_type == bool_type: rules[start_bool].append(FunctionRewrite(func, *args)) else: assert False ite_func = semantics_core.IteFunction(bv_type) rules[start].append( FunctionRewrite(ite_func, ntr_start_bool, ntr_start, ntr_start)) if return_type == bv_type: ret = Grammar(nts, nt_type, rules, start) elif return_type == bool_type: ret = Grammar(nts, nt_type, rules, start_bool) else: raise NotImplementedError ret.from_default = True return ret elif theory == 'SLIA': raise NotImplementedError else: raise NotImplementedError
def make_false_expr(self): """Makes an expression representing the boolean constant FALSE.""" return exprs.ConstantExpression( exprs.Value(False, exprtypes.BoolType()))