def test_conversion_of_fractions_in_z3(self): self.assertValid(Equals(Real(Fraction(1,9)), Div(Real(1), Real(9))), solver_name="msat") self.assertValid(Equals(Real(Fraction(1,9)), Div(Real(1), Real(9))), solver_name="z3")
def __post_init__(self): w, h = self.w, self.h spacing = self.spacing factory = self.factory constraints = self.constraints grid = [[factory() for _ in range(w)] for _ in range(h)] # align rows and columns for row in grid: constraints.append(top_align(row)) for col in range(w): constraints.append(left_align(row[col] for row in grid)) # establish spacing between grid elements first_row = grid[0] first_col = [row[0] for row in grid] for a, b in zip(first_row, first_row[1:]): constraints.append(Equals(b.bounds.left_edge, a.bounds.right_edge + spacing)) for a, b in zip(first_col, first_col[1:]): constraints.append(Equals(b.bounds.top_edge, a.bounds.bottom_edge + spacing)) # flatten the grid and store it self.shapes.extend(shape for row in grid for shape in row)
def resize_bvs(self, formula): """ Resize the bitvector variables wrt to the maximum domain size """ subs_map = {} for (fvar, max_value) in self.fvars_maxval.iteritems(): old_enc_var = self.fvars2encvars.lookup_a(fvar) bv_size = self.get_size(max_value+1) new_enc_var = FreshSymbol(BVType(bv_size)) self.fvars2encvars.add(fvar, new_enc_var) val2val = self.fvars2values[fvar] for i in range(max_value + 1): old_value = BV(i, SymbolicGrounding.MAX_BV) new_value = BV(i, bv_size) fval = val2val.lookup_b(old_value) val2val.add(fval, new_value) old_f = Equals(old_enc_var, old_value) new_f = Equals(new_enc_var, new_value) subs_map[old_f] = new_f formula = substitute(formula, subs_map) return formula
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 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 test_btor_get_non_bool_value(self): with Solver(name="btor") as s: x = Symbol("x", BVType(16)) s.add_assertion(Equals(x, BV(1, 16))) self.assertTrue(s.solve()) self.assertEqual(s.get_value(Equals(x, BV(1, 16))), TRUE()) self.assertEqual(s.get_value(BVAdd(x, BV(1, 16))), BV(2, 16))
def add_relu_eager_constraint(self): # Eager lemma encoding for relus zero = Real(0) for r, relu_in in self.relus: self.formulae.append(Implies(GT(relu_in, zero), Equals(r, relu_in))) self.formulae.append(Implies(LE(relu_in, zero), Equals(r, zero)))
def test_str_to_int(self): f = Equals(StrToInt(String("1")), Int(1)) self.assertValid(f) f = Equals(StrToInt(String("-55")), Int(-1)) self.assertValid(f) f = Equals(StrToInt(String("pippo")), Int(-1)) self.assertValid(f)
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 process(): varA = Symbol("A") varB = Symbol("B") f = And(varA, Not(varB)) print(f) print(is_sat(f)) hello = [Symbol(s, INT) for s in "hello"] world = [Symbol(s, INT) for s in "world"] letters = set(hello + world) domains = And(And(LE(Int(1), l), GE(Int(10), l)) for l in letters) print(domains,'domain') sum_hello = Plus(hello) sum_world = Plus(world) problem = And(Equals(sum_hello, sum_world), Equals(sum_hello, Int(36))) formula = And(domains, problem) print("Serialization of the formula:") print(formula) print(formula.serialize()) print(is_sat(formula)) print(get_model(formula))
def main(): # Example Transition System (SMV-like syntax) # # VAR x: integer; # y: integer; # # INIT: x = 1 & y = 2; # # TRANS: next(x) = x + 1; # TRANS: next(y) = y + 2; x, y = [Symbol(s, INT) for s in "xy"] nx, ny = [next_var(Symbol(s, INT)) for s in "xy"] example = TransitionSystem(variables=[x, y], init=And(Equals(x, Int(1)), Equals(y, Int(2))), trans=And(Equals(nx, Plus(x, Int(1))), Equals(ny, Plus(y, Int(2))))) # A true invariant property: y = x * 2 true_prop = Equals(y, Times(x, Int(2))) # A false invariant property: x <= 10 false_prop = LE(x, Int(10)) for prop in [true_prop, false_prop]: check_property(example, prop) print("")
def test_div_by_0(self): varA = Symbol('A', REAL) varB = Symbol('B', REAL) f = And(Equals(varA, varB), Not(Equals(Div(varA, Real(0)), Div(varB, Real(0))))) self.assertUnsat(f)
def test_btor_get_array_element(self): with Solver(name="btor") as s: x = Symbol("a", ArrayType(BVType(16), BVType(16))) s.add_assertion(Equals(Select(x, BV(1, 16)), BV(1, 16))) s.add_assertion(Equals(Select(x, BV(2, 16)), BV(3, 16))) self.assertTrue(s.solve()) self.assertEqual(s.get_value(Select(x, BV(1, 16))), BV(1, 16)) self.assertIsNotNone(s.get_value(x))
def sym_exec_rsicv_add(rs1, rs2, rd, regs): rs1_val = Ite(Equals(rs1, BitVecVal(0, 5)), BitVecVal(0, 32), Select(regs, rs1)) rs2_val = Ite(Equals(rs2, BitVecVal(0, 5)), BitVecVal(0, 32), Select(regs, rs2)) res = BVAdd(rs1_val, rs2_val) regs_n = Store(regs, rd, res) return Ite(Equals(rd, BitVecVal(0, 5)), regs, regs_n)
def test_div_pow(self): x = FreshSymbol(REAL) f = Equals(Times(Real(4), Pow(x, Real(-1))), Real(2)) self.assertTrue(is_sat(f)) f = Equals(Div(Real(4), x), Real(2)) self.assertTrue(is_sat(f, solver_name="z3")) f = Equals(Times(x, x), Real(16)) self.assertTrue(is_sat(f))
def test_ackermannization_unary(self): self.env.enable_infix_notation = True a, b = (Symbol(x, INT) for x in "ab") f, g, h = (Symbol(x, FunctionType(INT, [INT])) for x in "fgh") formula1 = Not(Equals(f(g(h(a))), f(g(h(b))))) formula2 = Equals(a, b) formula = And(formula1, formula2) self._verify_ackermannization(formula)
def test_ackermannization_pairwise(self): self.env.enable_infix_notation = True a, b, c, d = (Symbol(x, INT) for x in "abcd") f = Symbol("f", FunctionType(INT, [INT])) formula = And(Not(Equals(f(b), f(c))), Equals(f(a), f(b)), Equals(f(c), f(d)), Equals(a, d)) self.assertUnsat(formula) formula_ack = Ackermannizer().do_ackermannization(formula) self.assertUnsat(formula_ack)
def check_table_energies_exact(self, graph, decision_variables, h, J): """For a given ising problem, check that the table gives the correct energies when linear and quadratic energies are specified exactly. """ # determine the aux variables aux_variables = tuple(v for v in graph if v not in decision_variables) # now generate a theta that sets linear and quadratic equal to h, J linear_ranges = {v: (bias, bias) for v, bias in h.items()} quadratic_ranges = {edge: (bias, bias) for edge, bias in J.items()} # and now the table table = Table(graph, decision_variables, linear_ranges, quadratic_ranges) # ok, time to do some energy calculations for config in itertools.product((-1, 1), repeat=len(decision_variables)): spins = dict(zip(decision_variables, config)) # first we want to know the minimum classical energy energy = float('inf') for aux_config in itertools.product((-1, 1), repeat=len(aux_variables)): aux_spins = dict(zip(aux_variables, aux_config)) aux_spins.update(spins) aux_energy = ising_energy(h, J, aux_spins) if aux_energy < energy: energy = aux_energy # collect assertions assertions = table.assertions theta = table.theta # so we can set the offset directly # table assertions by themselves should be SAT self.assertSat(And(assertions)) # ok, does the exact energy calculated by the table match? table_energy = table.energy(spins, break_aux_symmetry=False) for offset in [0, -.5, -.3, -.1, .23, 1, 106]: self.assertSat(And([Equals(table_energy, limitReal(energy + offset)), And(assertions), Equals(theta.offset, limitReal(offset))]), msg='exact energy equality is not SAT') self.assertUnsat(And([Not(Equals(table_energy, limitReal(energy + offset))), And(assertions), Equals(theta.offset, limitReal(offset))]), msg='exact energy inequality is not UNSAT') # how about the upper bound? table_energy_upperbound = table.energy_upperbound(spins) for offset in [-.5, -.3, -.1, 0, .23, 1, 106]: self.assertSat(And([GE(table_energy_upperbound, limitReal(energy + offset)), And(assertions), Equals(theta.offset, limitReal(offset))]), msg='energy upperbound is not SAT')
def add_relu_simplex_friendly_eager(self): # Eager lemma encoding for relus zero = Real(0) for relu_out, relu_in in self.relus: #Introduce f = relu_out - relu_in f = FreshSymbol(REAL) self.formulae.append(Equals(f, Minus(relu_out, relu_in))) self.formulae.append(Implies(GT(relu_in, zero), Equals(f, zero))) self.formulae.append( Implies(LE(relu_in, zero), Equals(relu_out, zero)))
def find_all_moves(p): logger.debug("finding all possible moves for %s" % p.name) options = [] for r, row in enumerate(board): for c, cell in enumerate(row): if not Equals( board[r][c], p.value) in solver.assertions: # if not already played options.append(Equals(cell, p.value)) return options
def score_output( idx ): #how many other outputs in the same amount that do not belong to us? outputs_equal_not_ours = [And(Equals(v, output_amt[idx]), Not(Equals(output_party[k], output_party[idx])))\ for (k, v) in filter(lambda x: x[0] != idx, output_amt.items())] score = Plus([bool_to_int(x) for x in outputs_equal_not_ours]) anonymityset_constraints.add(Equals(output_score[idx], score)) return score
def translate(self): """Create SMT expressions for bounding the parameters of an output port to be within the constraints defined by the user :param str name: Name of the port to be constrained :returns: None -- no issues with translating the port parameters to SMT """ incoming_channels = self.get_incoming_channels() if len(incoming_channels) <= 0: raise ValueError("Port %s must have 1 or more connections" % self.get_name()) # Currently don't support this, and I don't think it would be the case # in real circuits, an output port is considered the end of a branch outgoing_channels = self.get_outgoing_channels() if len(outgoing_channels) != 0: raise ValueError("Cannot have channels out of output port %s" % self.get_name()) # Since input is just a specialized node, call translate node self.exprs.append(Node.Node().translate(self)) #TODO: test this # Calculate flow rate for this port based on pressure and channels out # if not specified by user if not self.get_min_flow_rate(name): # The flow rate at this node is the sum of the flow rates of the # the channel coming in (I think, should be verified) total_flow_in = [] for incoming_channel in incoming_channels: # TODO: This is where the flow rate calls to the input nodes get triggered self.exprs.append(incoming_channel) total_flow_in.append(incoming_channel.get_flow_rate()) if len(total_flow_in) == 1: # only one incoming channel self.exprs.append( Equals(self.get_flow_rate(), total_flow_in[0])) else: self.exprs.append( Equals(self.get_flow_rate(), Plus(total_flow_in))) self.expers.append(incomming_channel.translate()) # Once it gets back from translating we can get the flow rate total_flow_in.append(channel_in.get_channel_flow_rate()) ''' Here iterate over the incoming channels and call translate over them for incomming_channel in self.incoming_channels: self.expers.append(incomming_channel.translate()) # Once it gets back from translating we can get the flow rate total_flow_in.append(channel_in.get_channel_flow_rate()) ''' return self.exprs
def exec_Branch(self, instr: Branch, st): taken = { BranchCond.CC: lambda: Equals(st.C, BitVecVal(0, 1)), BranchCond.CS: lambda: Equals(st.C, BitVecVal(1, 1)), BranchCond.EQ: lambda: Equals(st.Z, BitVecVal(1, 1)), BranchCond.NE: lambda: Equals(st.Z, BitVecVal(0, 1)), }[instr.cond]() if instr.offset >= 0: taken_pc = BVAdd(st.PC, BitVecVal(instr.offset + 1, 16)) else: taken_pc = BVSub(st.PC, BitVecVal((-instr.offset) + 1, 16)) return st, (taken, taken_pc)
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 test_complex_types(self): with self.assertRaises(PysmtTypeError): # Not(Store(Array<Real,BV8>(8d_0), 1.0, 8d_5) = # Store(Array<Int,BV8>(8d_0), 1, 8d_5)) Not( Equals(Store(Array(REAL, BV(0, 8)), Real(1), BV(5, 8)), Store(Array(INT, BV(0, 8)), Int(1), BV(5, 8)))) nested_a = Symbol("a_arb_aii", ArrayType(ArrayType(REAL, BV8), ARRAY_INT_INT)) with self.assertRaises(PysmtTypeError): # This is wrong, because the first elemnt of Array must be a Type Equals(nested_a, Array(Array(REAL, BV(0, 8)), Array(INT, Int(7))))
def test_get_atoms_array_select(self): a = Symbol("a", ArrayType(INT, BOOL)) x = Symbol("x", INT) p = Symbol("p", BOOL) phi = And(Iff(Select(a, x), p), Equals(x, Int(1))) atoms = phi.get_atoms() self.assertEqual(len(atoms), 3) self.assertIn(Select(a, x), atoms) self.assertIn(p, atoms) self.assertIn(Equals(x, Int(1)), atoms)
def evenly_spaced(start_point, end_point, shapes): n = len(shapes) assert n > 1 constraints = [] for i in range(n): if shapes[i] is None: continue j = n - i - 1 x = (start_point.x * j + end_point.x * i) / (n - 1) y = (start_point.y * j + end_point.y * i) / (n - 1) constraints.append(Equals(shapes[i].x, x)) constraints.append(Equals(shapes[i].y, y)) return And(constraints)
def test_integer(self): x = FreshSymbol(INT) f = Equals(Times(x, x), Int(2)) with Solver(name="z3") as s: self.assertFalse(s.is_sat(f)) # f = Equals(Times(Int(4), Pow(x, Int(-1))), Int(2)) # self.assertTrue(is_sat(f, solver_name="z3")) f = Equals(Div(Int(4), x), Int(2)) self.assertTrue(is_sat(f, solver_name="z3")) f = Equals(Times(x, x), Int(16)) self.assertTrue(is_sat(f))
def test_copy(self): linear_ranges = defaultdict(lambda: (-2., 2.)) quadratic_ranges = defaultdict(lambda: (-1., 1.)) graph = nx.complete_graph(5) theta = Theta.from_graph(graph, linear_ranges, quadratic_ranges) cp_theta = theta.copy() # should all point to the same for v, bias in theta.linear.items(): self.assertSat(Equals(bias, cp_theta.linear[v])) self.assertUnsat(Not(Equals(bias, cp_theta.linear[v])))
def convert(self, abstract=False): for i in range(self.nnet.inputSize): x = Symbol("x%d" % i, REAL) self.input_vars.append(x) for i in range(self.nnet.outputSize): y = Symbol("y%d" % i, REAL) self.output_vars.append(y) # for i,v in enumerate(self.input_vars): # # normalized # m = self.nnet.mins[i] # l = GE(self.input_vars[i], # Real((m - self.nnet.means[i])/self.nnet.ranges[i])) # self.formulae.append(l) # # normalized # m = self.nnet.maxes[i] # l = LE(self.input_vars[i], # Real((m - self.nnet.means[i])/self.nnet.ranges[i])) # self.formulae.append(l) prev_layer_result = self.input_vars.copy() layer_result = [] zero = Real(0) self.relus_level.append(set()) for l in range(self.nnet.numLayers - 1): self.relus_level.append(set()) for ls in range(self.nnet.layerSizes[l + 1]): r = self.dot(self.nnet.weights[l][ls], prev_layer_result) r = Plus(r, Real(float(self.nnet.biases[l][ls]))) relu_in = FreshSymbol(REAL) self.formulae.append(Equals(relu_in, r)) if abstract: relu_out = FreshSymbol(REAL) r = relu_out self.relus.append((relu_out, relu_in)) self.relus_level[l + 1].add((relu_out, relu_in)) else: r = Max(relu_in, zero) layer_result.append(r) prev_layer_result = layer_result.copy() layer_result.clear() for i, y in enumerate(self.output_vars): o = self.dot(self.nnet.weights[-1][i], prev_layer_result) o = Plus(o, Real(float(self.nnet.biases[-1][i]))) # # undo normalization # o = Times(o, Real(self.nnet.ranges[-1])) # o = Plus(o, Real(self.nnet.means[-1])) self.formulae.append(Equals(y, o)) self.parse_violation(self.violation_path)