def test_incremental(self): a = Symbol('a', BOOL) b = Symbol('b', BOOL) c = Symbol('c', BOOL) for name in get_env().factory.all_solvers(logic=QF_BOOL): with Solver(name) as solver: solver.add_assertion(Or(a, b)) solver.add_assertion(Or(Not(b), c)) self.assertTrue(solver.solve()) try: solver.push(1) except NotImplementedError: # if push not implemented, pop shouldn't be either self.assertRaises(NotImplementedError, solver.pop) continue solver.add_assertion(And(Not(a), Not(c))) self.assertFalse(solver.solve()) solver.pop(1) self.assertTrue(solver.solve()) solver.add_assertion(FALSE()) self.assertFalse(solver.solve()) solver.reset_assertions() solver.add_assertion(a) self.assertTrue(solver.solve())
def construct_spread_formula_from_graph(spread_graph, limit, target): initial_infection_ints = [ Symbol('init_int_' + str(i), INT) for i in spread_graph.nodes ] final_infection_ints = [ Symbol('final_int_' + str(i), INT) for i in spread_graph.nodes ] spreading_clauses = [] origin_clauses = [] all_bounds = [] # Here, we ensure that, if node i is selected as an initial infector, all of its neighbors are also infected: for starting_node in spread_graph.nodes: initial_infection_bounds = And( LE(initial_infection_ints[int(starting_node)], Int(1)), GE(initial_infection_ints[int(starting_node)], Int(0))) infected_neighbors = And([ Equals(final_infection_ints[int(i)], Int(1)) for i in spread_graph.successors(starting_node) ]) infected_nodes = And( infected_neighbors, Equals(final_infection_ints[int(starting_node)], Int(1))) spreading_forumla = Implies( Equals(initial_infection_ints[int(starting_node)], Int(1)), infected_nodes) spreading_clauses.append(spreading_forumla) all_bounds.append(initial_infection_bounds) # Here, we ensure that, if node i becomes infected, either it was infected by an initial infectors with an edge to node i # of node i itself was an initial infector. for infected_node in spread_graph.nodes: final_infection_bounds = And( LE(final_infection_ints[int(infected_node)], Int(1)), GE(final_infection_ints[int(infected_node)], Int(0))) origin_neighbors = Or([ Equals(initial_infection_ints[int(i)], Int(1)) for i in spread_graph.predecessors(infected_node) ]) origin_nodes = Or( origin_neighbors, Equals(initial_infection_ints[int(infected_node)], Int(1))) origin_formula = Implies( Equals(final_infection_ints[int(infected_node)], Int(1)), origin_nodes) origin_clauses.append(origin_formula) all_bounds.append(final_infection_bounds) initial_infection_limit = LE(Plus(initial_infection_ints), Int(limit)) final_infection_target = GE(Plus(final_infection_ints), Int(target)) return And( And(spreading_clauses), And(origin_clauses), And(all_bounds), initial_infection_limit, final_infection_target), initial_infection_ints, final_infection_ints
def encode_node(self, node): """ Encode a node of a tree. """ if '_' not in node.name: # continuous features => expecting an upper bound # feature and its upper bound (value) f, v = node.name, node.threshold existing = True if tuple([f, v]) in self.idmgr.obj2id else False vid = self.idmgr.id(tuple([f, v])) bv = Symbol('bvar{0}'.format(vid), typename=BOOL) if not existing: if self.intvs: d = self.imaps[f][v] + 1 pos, neg = self.ivars[f][:d], self.ivars[f][d:] self.enc.append(Iff(bv, Or(pos))) self.enc.append(Iff(Not(bv), Or(neg))) else: fvar, fval = Symbol(f, typename=REAL), Real(v) self.enc.append(Iff(bv, LT(fvar, fval))) return bv, Not(bv) else: # all features are expected to be categorical and # encoded with one-hot encoding into Booleans # each node is expected to be of the form: f_i < 0.5 bv = Symbol(node.name, typename=BOOL) # left branch is positive, i.e. bv is true # right branch is negative, i.e. bv is false return Not(bv), bv
def all_loopbacks(self, vars, k, heqvar=None): lvars = list(vars) vars_k = [TS.get_timed(v, k) for v in lvars] loopback = FALSE() eqvar = None heqvars = None if heqvar is not None: eqvar = Symbol(EQVAR, BOOL) heqvars = [] peqvars = FALSE() for i in range(k): vars_i = [TS.get_timed(v, i) for v in lvars] eq_k_i = And( [EqualsOrIff(vars_k[j], vars_i[j]) for j in range(len(lvars))]) if heqvar is not None: eqvar_i = TS.get_timed(eqvar, i) peqvars = Or(peqvars, eqvar_i) eq_k_i = And(eqvar_i, Iff(eqvar_i, eq_k_i)) heqvars.append(Iff(TS.get_timed(heqvar, i), peqvars)) loopback = Or(loopback, eq_k_i) if heqvar is not None: loopback = And(loopback, And(heqvars)) return loopback
def break_dfa_symmetry_bfs(x, y, sigma, prefixes_r, h): epsilon_i = prefixes_r[()] assert epsilon_i == 0 constraints = [] constraints.append(Equals(x[epsilon_i], Int(1))) t = [[Symbol(f"t_{i}_{j}", BOOL) for j in range(h)] for i in range(h)] p = [[Symbol(f"p_{i}_{j}", BOOL) for j in range(h)] for i in range(h)] for i, j in it.combinations(range(h), 2): constraints.append(Iff( t[i][j], Or(*(Equals(Select(y[l], Int(i+1)), Int(j+1)) for l in range(len(sigma)))) )) constraints.append(Iff( p[j][i], And( t[i][j], *(Not(t[k][j]) for k in range(i)) ) )) for j in range(1, h): constraints.append(Or(*(p[j][k] for k in range(j)))) for k, i, j in it.combinations(range(h-1), 3): constraints.append(Implies(p[j][i], Not(p[j+1][k]))) assert len(sigma) == 2 for i, j in it.combinations(range(h-1), 2): constraints.append(Implies(And(p[j][i], p[j+1][i]), Equals(Select(y[0], Int(i+1)), Int(j+1)))) return constraints
def get_wire_formulas(w, lst): r = None if w.type == Wire.INPUT: r = Symbol(w.name) elif w.type == 'not': r = Not(lst[0]) elif w.type == 'buf': r = lst[0] elif w.type == 'buff': r = lst[0] elif w.type == 'and': r = And(lst) elif w.type == 'nand': r = And(lst) r = Not(r) elif w.type == 'or': r = Or(lst) elif w.type == 'nor': r = Or(lst) r = Not(r) elif w.type == 'xor': assert (len(lst) == 2) r = Xor(lst[0], lst[1]) elif w.type == 'xnor': assert (len(lst) == 2) r = Xor(lst[0], lst[1]) r = Not(r) elif w.type == 'mux': assert (len(lst) == 3) r = Or(And(Not(lst[0]), lst[1]), And(lst[0], lst[2])) else: logging.critical('unspecified gate type') exit() return r
def __init__(self, oracle_cir, obf_cir): self.oracle_cir = oracle_cir self.obf_cir = obf_cir # generate solver formulas for w in self.oracle_cir.wire_objs: lst = [] for op in w.operands: lst.append(Symbol(op.name)) r = self.get_wire_formulas(w, lst) w.formula = Iff(Symbol(w.name), r) # generate formulas for two copies of obfuscated circuit ckt1 = self.gen_dip_chk('dc1', '_0', None) ckt2 = self.gen_dip_chk('dc2', '_1', None) output_xors = [] for w in self.obf_cir.output_wires: output_xors.append( Xor(Symbol(w.name + '@dc1'), Symbol(w.name + '@dc2'))) self.dip_gen_ckt = And(Or(output_xors), ckt1, ckt2) # key inequality circuit key_symbols1 = [] key_symbols2 = [] for w in self.obf_cir.wire_objs: if 'keyinput' in w.name: key_symbols1.append(Symbol(w.name + '_0')) key_symbols2.append(Symbol(w.name + '_1')) output_xors = [] for i in range(self.obf_cir.k_inputs): output_xors.append(Xor(key_symbols1[i], key_symbols2[i])) self.key_inequality_ckt = Or(output_xors)
def k_sequence_WH(m, K, K_seq_len=100, count=100): k_seq = [Symbol('x_%i' % i, INT) for i in range(K_seq_len)] domain = And([Or(Equals(x, Int(0)), Equals(x, Int(1))) for x in k_seq]) K_window = And([ LE(Plus(k_seq[t:min(K_seq_len, t + K)]), Int(m)) for t in range(max(1, K_seq_len - K + 1)) ]) formula = And(domain, K_window) solver = Solver(name='yices', incremental=True, random_seed=randint(2 << 30)) solver.add_assertion(formula) for _ in range(count): result = solver.solve() if not result: solver = Solver(name='z3', incremental=True, random_seed=randint(2 << 30)) solver.add_assertion(formula) solver.solve() model = solver.get_model() model = array(list(map(lambda x: model.get_py_value(x), k_seq)), dtype=bool) yield model solver.add_assertion( Or([NotEquals(k_seq[i], Int(model[i])) for i in range(K_seq_len)]))
def solve_inc(self, hts, prop, k, all_vars=True): if all_vars: relevant_vars = hts.vars else: relevant_vars = hts.state_vars | hts.input_vars | hts.output_vars init = hts.single_init() trans = hts.single_trans() invar = hts.single_invar() init = And(init, invar) init_0 = self.at_time(init, 0) nprop = self.enc.to_nnf(Not(prop)) self._reset_assertions(self.solver) self._add_assertion(self.solver, init_0) for t in range(1, k + 1, 1): trans_t = self.unroll(trans, invar, t) self._add_assertion(self.solver, trans_t) lb = self.all_simple_loopbacks(relevant_vars, t) self._push(self.solver) self._push(self.solver) nprop_k = self.enc.encode(nprop, 0, t) self._add_assertion(self.solver, And(nprop_k, Not(Or(lb)))) if self._solve(self.solver): Logger.log("Counterexample (no-loop) found with k=%s" % (t), 1) model = self._get_model(self.solver) return (t, model) nltlprop = [] self._pop(self.solver) for l in range(t + 1): nprop_l = self.enc.encode_l(nprop, 0, t, l) nltlprop.append(And(lb[l], nprop_l)) self._add_assertion(self.solver, Or(nltlprop)) if self._solve(self.solver): Logger.log("Counterexample (with-loop) found with k=%s" % (t), 1) model = self._get_model(self.solver) return (t, model) else: Logger.log("No counterexample found with k=%s" % (t), 1) Logger.msg(".", 0, not (Logger.level(1))) self._pop(self.solver) return (k - 1, None)
def test_boolean(self): x, y, z = Symbol("x"), Symbol("y"), Symbol("z") f = Or(And(Not(x), Iff(x, y)), Implies(x, z)) self.assertEqual(f.to_smtlib(daggify=False), "(or (and (not x) (= x y)) (=> x z))") self.assertEqual(f.to_smtlib(daggify=True), "(let ((.def_0 (=> x z))) (let ((.def_1 (= x y))) (let ((.def_2 (not x))) (let ((.def_3 (and .def_2 .def_1))) (let ((.def_4 (or .def_3 .def_0))) .def_4)))))")
def two_comparator(input1, input2): if SortingNetwork.simplify: return [ simplify(Or(input1, input2)), simplify(And(input1, input2)) ] else: return [Or(input1, input2), And(input1, input2)]
def test_int(self): p, q = Symbol("p", INT), Symbol("q", INT) f = Or(Equals(Times(p, Int(5)), Minus(p,q)), LT(p,q), LE(Int(6), Int(1))) self.assertEqual(f.to_smtlib(daggify=False), "(or (= (* p 5) (- p q)) (< p q) (<= 6 1))") self.assertEqual(f.to_smtlib(daggify=True), "(let ((.def_0 (<= 6 1))) (let ((.def_1 (< p q))) (let ((.def_2 (- p q))) (let ((.def_3 (* p 5))) (let ((.def_4 (= .def_3 .def_2))) (let ((.def_5 (or .def_4 .def_1 .def_0))) .def_5))))))")
def test_boolean(self): x, y, z = Symbol("x"), Symbol("y"), Symbol("z") f = Or(And(Not(x), Iff(x, y)), Implies(x, z)) self.assertEqual(f.to_smtlib(daggify=False), "(or (and (not x) (= x y)) (=> x z))") self.assertEqual( f.to_smtlib(daggify=True), "(let ((.def_0 (=> x z))) (let ((.def_1 (= x y))) (let ((.def_2 (not x))) (let ((.def_3 (and .def_2 .def_1))) (let ((.def_4 (or .def_3 .def_0))) .def_4)))))" )
def test_prenex_basic(self): a, b, c = (Symbol(x) for x in "abc") f = Not(And(a, Exists([b], And(a, b)), ForAll([c], Or(a, c)))) prenex = prenex_normal_form(f) # Two prenex normal forms are possible my_prenex_1 = Exists([c], ForAll([b], Not(And(a, And(a, b), Or(a, c))))) my_prenex_2 = ForAll([b], Exists([c], Not(And(a, And(a, b), Or(a, c))))) self.assertTrue(prenex == my_prenex_1 or prenex == my_prenex_2)
def triangle(nvars, rand_gen): # alpha = rand_gen.uniform(0.05, 0.25) alpha = rand_gen.uniform(0.2, 0.25) remain = nvars % 3 n_tris = int(nvars / 3) variables = [Symbol(f"x{i}", REAL) for i in range(1, nvars + 1)] lbounds = [LE(Real(0), x) for x in variables] ubounds = [LE(x, Real(1)) for x in variables] clauses = [] potentials = [] for i in range(n_tris): x, y, z = variables[3 * i], variables[3 * i + 1], variables[3 * i + 2] xc = None if 3 * i + 3 >= nvars else variables[3 * i + 3] # x_i clauses.append(Or(LE(x, Real(alpha)), LE(Real(1 - alpha), x))) # x_i -- y_i clauses.append( Or(LE(y, Plus(x, Real(-alpha))), LE(Plus(x, Real(alpha)), y))) # x_i -- z_i clauses.append(Or(LE(Real(1 - alpha), x), LE(Real(1 - alpha), z))) clauses.append(Or(LE(x, Real(alpha)), LE(z, Real(alpha)))) # z_i -- y_i clauses.append(LE(z, y)) # x_i -- x_i+1 if xc: clauses.append(Or(LE(x, Real(alpha)), LE(Real(1 - alpha), xc))) clauses.append(Or(LE(Real(1 - alpha), x), LE(xc, Real(alpha)))) pot_yz = Ite(LE(z, y), Times([z, y, Real(100)]), Real(1)) pot_xy = Ite(LE(y, Plus(x, Real(-alpha))), Times(Real(100), Plus(x, y)), Real(1)) potentials.append(pot_xy) potentials.append(pot_yz) if remain == 1: x = variables[3 * n_tris] clauses.append(Or(LE(x, Real(alpha)), LE(Real(1 - alpha), x))) if remain == 2: x, y = variables[3 * n_tris], variables[nvars - 1] # x_n clauses.append(Or(LE(x, Real(alpha)), LE(Real(1 - alpha), x))) # x -- y clauses.append( Or(LE(y, Plus(x, Real(-alpha))), LE(Plus(x, Real(alpha)), y))) potentials.append( Ite(LE(y, Plus(x, Real(-alpha))), Times(Real(100), Plus(x, y)), Real(1))) domain = Domain.make( [], # no booleans [x.symbol_name() for x in variables], [(0, 1) for _ in range(len(variables))]) support = And(lbounds + ubounds + clauses) weight = Times(potentials) if len(potentials) > 1 else potentials[0] return Density(domain, support, weight, []), alpha
def test_int(self): p, q = Symbol("p", INT), Symbol("q", INT) f = Or(Equals(Times(p, Int(5)), Minus(p, q)), LT(p, q), LE(Int(6), Int(1))) self.assertEqual(f.to_smtlib(daggify=False), "(or (= (* p 5) (- p q)) (< p q) (<= 6 1))") self.assertEqual( f.to_smtlib(daggify=True), "(let ((.def_0 (<= 6 1))) (let ((.def_1 (< p q))) (let ((.def_2 (- p q))) (let ((.def_3 (* p 5))) (let ((.def_4 (= .def_3 .def_2))) (let ((.def_5 (or .def_4 .def_1 .def_0))) .def_5))))))" )
def k_sequence_WH_worst_case(m, K, K_seq_len=100, count=100): k_seq = [Symbol('x_%i' % i, INT) for i in range(K_seq_len)] domain = And([Or(Equals(x, Int(0)), Equals(x, Int(1))) for x in k_seq]) K_window = And([ LE(Plus(k_seq[t:min(K_seq_len, t + K)]), Int(m)) for t in range(max(1, K_seq_len - K + 1)) ]) violate_up = And([ GT(Plus(k_seq[t:min(K_seq_len, t + K)]), Int(m - 1)) for t in range(max(1, K_seq_len - K + 1)) ]) def violate_right_generator(n): return And([ GT(Plus(k_seq[t:min(K_seq_len, t + K + n)]), Int(m)) for t in range(max(1, K_seq_len - (K + n) + 1)) ]) right_shift = 1 formula = And(domain, K_window, violate_up, violate_right_generator(right_shift)) solver = Solver(name='z3', incremental=True, random_seed=randint(2 << 30)) solver.add_assertion(formula) solver.z3.set('timeout', 5 * 60 * 1000) solutions = And() for _ in range(count): while right_shift + K < K_seq_len: try: result = solver.solve() except BaseException: result = None if not result: solver = Solver(name='z3', incremental=True, random_seed=randint(2 << 30)) right_shift += 1 solver.z3.set('timeout', 5 * 60 * 1000) solver.add_assertion( And(solutions, domain, K_window, violate_up, violate_right_generator(right_shift))) else: break try: model = solver.get_model() except BaseException: break model = array(list(map(lambda x: model.get_py_value(x), k_seq)), dtype=bool) yield model solution = Or( [NotEquals(k_seq[i], Int(model[i])) for i in range(K_seq_len)]) solutions = And(solutions, solution) solver.add_assertion(solution)
def generate_false_constraint(path_constraint): false_constraint = None if path_constraint.is_and() or path_constraint.is_or(): prefix = None while path_constraint.is_and() or path_constraint.is_or(): constraint = path_constraint.arg(1) constraint_str = str(constraint.serialize()) if "angelic!bool" in constraint_str: model = generate_model(constraint) for var_name, byte_list in model: if "angelic!bool" in var_name: value = utilities.get_signed_value(byte_list) if value != 0: constraint = Not(constraint) if false_constraint: if path_constraint.is_and(): false_constraint = And(false_constraint, constraint) elif path_constraint.is_or(): false_constraint = Or(false_constraint, constraint) else: false_constraint = constraint prefix = path_constraint.arg(0) if prefix.is_and() or prefix.is_or(): path_constraint = prefix else: prefix_str = str(prefix.serialize()) if "angelic!bool" in prefix_str: model = generate_model(prefix) for var_name, byte_list in model: if "angelic!bool" in var_name: value = utilities.get_signed_value(byte_list) if value != 0: prefix = Not(prefix) if path_constraint.is_and(): false_constraint = And(false_constraint, prefix) elif path_constraint.is_or(): false_constraint = Or(false_constraint, prefix) else: model = generate_model(path_constraint) for var_name in model: byte_list = model[var_name] if "angelic!bool" in var_name: value = utilities.get_signed_value(byte_list) if value != 0: false_constraint = Not(path_constraint) else: false_constraint = path_constraint return false_constraint
def IsAttack(attack, plan, gridsize, obstacles, safes): obstacles = IntifyCoords(obstacles) safes = IntifyCoords(safes) # (1) All attack moves are in Z_gridsize x Z_gridsize. bounds = And([IsOnGrid(step, gridsize) for step in attack]) # (2) The attacker never moves more than 1 grid-square at a time. adjacency = IsConnected(attack) # (3) The attack begins in the same place as some path in the plan. init = Or([SamePosition(path[0], attack[0]) for path in plan]) # (4) The attack enters a "safe" zone at some point. reach = Or( [SamePosition(coord, safe) for coord in attack for safe in safes]) # (5) The attack does not cross paths with any plans other than the one it # replaces. avoid = And([ Implies(SamePosition(path[i], attack[i]), SamePosition(path[0], attack[0])) for i in range(len(attack)) for path in plan ]) # (6) The attack never runs into any obstacle. obstacles = And([ Not(SamePosition(coord, obstacle)) for coord in attack for obstacle in obstacles ]) # (7) Any time the attack is adjacent to some plan p, it is in the same # place as another plan p' and therefore could be mistaken for the # innocent plan p'. # i is the attacker, j the observer, k the time-step. undetected = And([ Implies( SamePosition(plan[i][0], attack[0]), And([ And( Implies(Adj(plan[j][k], plan[i][k]), SamePosition(coord, plan[i][k])), Implies(Adj(coord, plan[j][k]), SamePosition(coord, plan[i][k]))) for k, coord in enumerate(attack) for j in range(len(plan)) if j != i ])) for i in range(len(plan)) ]) return And(bounds, adjacency, init, reach, avoid, obstacles, undetected)
def test_named_unsat_core_with_assumptions(self): i0 = Int(0) a = GT(Symbol("a", INT), i0) b = GT(Symbol("b", INT), i0) c = GT(Symbol("c", INT), i0) n_a = Not(a) n_b = Not(b) n_c = Not(c) formulae = [Or(b, n_a), Or(c, n_a), Or(n_a, n_b, n_c)] with UnsatCoreSolver(logic=QF_LIA, unsat_cores_mode="named") as solver: for i, f in enumerate(formulae): solver.add_assertion(f, named=f"f{i}") sat = solver.solve([a]) self.assertFalse(sat)
def belongs_and_unique(idx): disequal = [Or(Not(Equals(v, output_amt[idx])), Equals(output_party[k], Int(party)))\ for (k, v) in filter(lambda x: x[0] != idx, output_amt.items())] return And(Equals(output_party[idx], Int(party)), And(disequal))
def _do_cld_check(cld): self.cldid += 1 sel = Symbol('{0}_{1}'.format(self.selv.symbol_name(), self.cldid)) cld.append(Not(sel)) # adding clause D self.oracle.add_assertion(Or(cld)) self.ss_assumps.append(sel) self.setd = [] st = self.oracle.solve([self.selv] + self.ss_assumps + self.bb_assumps) self.ss_assumps.pop() # removing clause D assumption if st == True: model = self.oracle.get_model() for l in cld[:-1]: # filtering all satisfied literals if int(model.get_py_value(l)) > 0: self.ss_assumps.append(l) else: self.setd.append(l) else: # clause D is unsatisfiable => all literals are backbones self.bb_assumps.extend([Not(l) for l in cld[:-1]]) # deactivating clause D self.oracle.add_assertion(Not(sel))
def simple_checker_problem(): theory = Or( And(LE(Symbol("x", REAL), Real(0.5)), LE(Symbol("y", REAL), Real(0.5))), And(GT(Symbol("x", REAL), Real(0.5)), GT(Symbol("y", REAL), Real(0.5))) ) return xy_domain(), theory, "simple_checker"
def generate_program_specification(binary_path): dir_list = [f for f in os.listdir(binary_path) if not os.path.isfile(os.path.join(binary_path, f))] expected_output_list = values.LIST_TEST_OUTPUT test_count = len(expected_output_list) max_skip_index = (test_count * 2) - 1 program_specification = None for dir_name in dir_list: if "klee-out-" not in dir_name: continue dir_path = os.path.join(binary_path, dir_name) klee_index = int(dir_name.split("-")[-1]) # if klee_index <= max_skip_index: # continue file_list = [f for f in os.listdir(dir_path) if os.path.isfile(os.path.join(dir_path, f))] for file_name in file_list: if ".smt2" in file_name: file_path = os.path.join(dir_path, file_name) path_condition = extractor.extract_formula_from_file(file_path) model_path = generate_model(path_condition) var_list = list(model_path.keys()) count = 0 for var in var_list: if "obs!" in var: count = count + 1 if count == 0: continue if program_specification is None: program_specification = path_condition else: program_specification = Or(program_specification, path_condition) return program_specification
def graph_to_tree(graph: Graph, constant: float = 1.0, return_map=False, n_bbox=1): edges, nodes = list(graph.edges), list(graph.nodes) n = len(nodes) node_map = {} for label in range(n): symbol = Symbol("x_{}".format(label), REAL) if n_bbox: node_map[label] = TNode(label=label, symbol=symbol, n_bbox=n_bbox) else: node_map[label] = TNode(label=label, symbol=symbol) for u, v in edges: u, v = min(u, v), max(u, v) # u -> v parent = node_map[u] child = node_map[v] formula = Or(parent.symbol + Real(constant) <= child.symbol, parent.symbol + Real(-constant) >= child.symbol) edge = TEdge(parent=parent, child=child, formula=formula) parent.add_edge(edge) if return_map: return node_map[0], node_map return node_map[0]
def get_mask(self, var_name): """ Returns the bitmask needed to ignore the additional unused bits used to encode the counter var_name. """ # minimum number of bits to represent max_value assert var_name in self.vars2bound max_value = self.vars2bound[var_name] bitsize = CounterEnc._get_bitsize(max_value) # construct the bitmask: we do NOT want all the models i = max_value + 1 mask = FALSE() max_value_with_bit = int(math.pow(2, bitsize)) - 1 # print "Maximum value %d" % max_value # print "Number of bits %d" % bitsize # print "max_repr_value %d" % max_value_with_bit while i <= max_value_with_bit: single_val = self.eq_val(var_name, i, True) mask = Or(mask, single_val) i = i + 1 assert (mask != None) mask = Not(mask) # TODO: get a compact representation using BDDs if (self.use_bdds): bdd_mask = self.bdd_converter.convert(mask) mask = self.bdd_converter.back(bdd_mask) return mask
def smart_walk_not(self, formula): if formula in self.subs: # Smarties contains a string. # In the future, we could allow for arbitrary function calls self.write(self.subs[formula]) else: arg = formula.arg(0) if arg.is_iff(): arg = self.get_iff(arg) if arg.is_exists(): argn = ForAll(arg.quantifier_vars(), Not(arg.arg(0))) return self.walk(argn) elif arg.is_forall(): argn = Exists(arg.quantifier_vars(), Not(arg.arg(0))) return self.walk(argn) elif arg.is_and(): args = [Not(a) for a in arg.args()] argn = Or(args) return self.walk(argn) elif arg.is_or(): args = [Not(a) for a in arg.args()] argn = And(args) return self.walk(argn) elif arg.is_not(): return self.walk(arg.arg(0)) else: if (arg.is_not()): assert (0) return HRPrinter.super(self, formula)
def get_prepared_solver(self, logic, solver_name=None): """Returns a solver initialized with the sudoku constraints and a matrix of SMT variables, each representing a cell of the game. """ sq_size = self.size**2 ty = self.get_type() var_table = [[FreshSymbol(ty) for _ in range(sq_size)] for _ in range(sq_size)] solver = Solver(logic=logic, name=solver_name) # Sudoku constraints # all variables are positive and lower or equal to than sq_size for row in var_table: for var in row: solver.add_assertion(Or([Equals(var, self.const(i)) for i in range(1, sq_size + 1)])) # each row and each column contains all different numbers for i in range(sq_size): solver.add_assertion(AllDifferent(var_table[i])) solver.add_assertion(AllDifferent([x[i] for x in var_table])) # each square contains all different numbers for sx in range(self.size): for sy in range(self.size): square = [var_table[i + sx * self.size][j + sy * self.size] for i in range(self.size) for j in range(self.size)] solver.add_assertion(AllDifferent(square)) return solver, var_table
def flip_negated_literals_cnf(f): """ Removes the negated LRA/NRA literals in 'f' by pushing the negation into the relation, while leaving the negated boolean atoms unaltered. Returns a pysmt.FNode instance that is equivalent to 'f'. Raises ValueError if the 'f' is not in CNF. Parameters ---------- f : pysmt.FNode instance """ if is_literal(f): if is_ra_literal(f) and f.is_not(): return flip_ra_atom(f.args()[0]) else: return f elif f.is_or(): return Or([flip_negated_literals_cnf(l) for l in f.args()]) elif f.is_and(): return And([flip_negated_literals_cnf(c) for c in f.args()]) else: raise ValueError("Formula not in CNF {}".format(f))
def test_int(self): p, q = Symbol("p", INT), Symbol("q", INT) f = Or(Equals(Times(p, Int(5)), Minus(p, q)), LT(p, q), LE(Int(6), Int(1))) f_string = self.print_to_string(f) self.assertEqual(f_string, "(or (= (* p 5) (- p q)) (< p q) (<= 6 1))")
def test_from_formula(self): x, y = Symbol("x"), Symbol("y") f = And(x, Or(y, x)) script = smtlibscript_from_formula(f) self.assertIsNotNone(script) outstream = cStringIO() script.serialize(outstream) output = outstream.getvalue() self.assertIn("(set-logic ", output) self.assertIn("(declare-fun x () Bool)", output) self.assertIn("(declare-fun y () Bool)", output) self.assertIn("(check-sat)", output) # Use custom logic (as str) script2 = smtlibscript_from_formula(f, logic="BOOL") outstream = cStringIO() script2.serialize(outstream) output = outstream.getvalue() self.assertIn("(set-logic BOOL)", output) # Use custom logic (as Logic obj) script3 = smtlibscript_from_formula(f, logic=QF_UFLIRA) outstream = cStringIO() script3.serialize(outstream) output = outstream.getvalue() self.assertIn("(set-logic QF_UFLIRA)", output) # Custom logic must be a Logic or Str with self.assertRaises(UndefinedLogicError): smtlibscript_from_formula(f, logic=4)
def test_solving_under_assumption_theory(self): x = Symbol("x", REAL) y = Symbol("y", REAL) v1 = GT(x, Real(10)) v2 = LE(y, Real(2)) xor = Or(And(v1, Not(v2)), And(Not(v1), v2)) for name in get_env().factory.all_solvers(logic=QF_LRA): with Solver(name=name) as solver: solver.add_assertion(xor) res1 = solver.solve(assumptions=[v1, Not(v2)]) model1 = solver.get_model() res2 = solver.solve(assumptions=[Not(v1), v2]) model2 = solver.get_model() res3 = solver.solve(assumptions=[v1, v2]) self.assertTrue(res1) self.assertTrue(res2) self.assertFalse(res3) self.assertEqual(model1.get_value(v1), TRUE()) self.assertEqual(model1.get_value(v2), FALSE()) self.assertEqual(model2.get_value(v1), FALSE()) self.assertEqual(model2.get_value(v2), TRUE())
def test_or_flattening(self): x,y,z = (Symbol(name) for name in "xyz") f1 = Or(x, y, z) f2 = Or(x, Or(y, z)) self.assertEqual(f2.simplify(), f1)
def test_trivial_true_or(self): x,y,z = (Symbol(name) for name in "xyz") f = Or(x, y, z, Not(x)) self.assertEqual(f.simplify(), TRUE())
def test_bool_dag(self): p = Symbol("p", INT) x = Symbol("x") f = Or(x, GT(p, Int(0)), And(x, x)) bool_dag = f.size(SizeOracle.MEASURE_BOOL_DAG) self.assertEqual(bool_dag, 4)