def test_substitute_memoization(self): a = Symbol("A", BOOL) b = Symbol("B", BOOL) f = And(a, b) g = f.substitute({a:Bool(True)}) h = f.substitute({a:Bool(False)}) self.assertNotEqual(h, g)
def test_threshold_printing(self): x = Symbol("x") f = And(x,x) for _ in xrange(10): f = And(f,f) short_f_str = str(f) long_f_str = f.serialize() self.assertTrue(len(short_f_str) < len(long_f_str))
def test_get_implicant_unsat(self): varA = Symbol("A", BOOL) varB = Symbol("B", BOOL) f = And(varA, Not(varB)) g = f.substitute({varB:varA}) for solver in get_env().factory.all_solvers(logic=QF_BOOL): res = get_implicant(g, solver_name=solver) self.assertIsNone(res, "Formula was expected to be UNSAT")
def test_is_sat(self): varA = Symbol("A", BOOL) varB = Symbol("B", BOOL) f = And(varA, Not(varB)) g = f.substitute({varB:varA}) self.assertUnsat(g, logic=QF_BOOL, msg="Formula was expected to be UNSAT") for solver in get_env().factory.all_solvers(): self.assertUnsat(g, solver_name=solver, msg="Formula was expected to be UNSAT")
def test_create_and_solve(self): solver = Solver(logic=QF_BOOL) varA = Symbol("A", BOOL) varB = Symbol("B", BOOL) f = And(varA, Not(varB)) g = f.substitute({varB:varA}) solver.add_assertion(g) res = solver.solve() self.assertFalse(res, "Formula was expected to be UNSAT") h = And(g, Bool(False)) simp_h = h.simplify() self.assertEqual(simp_h, Bool(False))
def get_unrolling(self, k): """Unrolling of the transition relation from 0 to k: E.g. T(0,1) & T(1,2) & ... & T(k-1,k) """ res = [] for i in range(k + 1): subs_i = self.get_subs(i) res.append(self.system.trans.substitute(subs_i)) return And(res)
def test_substitution_complex(self): x, y = Symbol("x", REAL), Symbol("y", REAL) # y = 0 /\ (Forall x. x > 3 /\ y < 2) f = And(Equals(y, Real(0)), ForAll([x], And(GT(x, Real(3)), LT(y, Real(2))))) subs = { y: Real(0), ForAll([x], And(GT(x, Real(3)), LT(y, Real(2)))): TRUE() } f_subs = substitute(f, subs).simplify() if self.env.SubstituterClass == MGSubstituter: self.assertEqual(f_subs, TRUE()) else: # In the MSS the y=0 substitution is performed first, # therefore, the overall quantified expression does not # match the one defined in the substitution map. # See test_substitution_complex_mss for a positive example. self.assertEqual(f_subs, ForAll([x], GT(x, Real(3))))
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_stack_recursion(self): import sys limit = sys.getrecursionlimit() f = FreshSymbol() p = FreshSymbol() for _ in range(limit): f = Or(p, And(f, p)) self.assertTrue(f.size() >= limit) s = f.serialize() self.assertIsNotNone(s)
def test_warp_solvermodel(self): x, y, z = [FreshSymbol() for _ in range(3)] with Solver(name='z3') as solver: solver.add_assertion(And(x, y, z)) solver.solve() z3_model = solver.get_model() eager_model = EagerModel(z3_model) for var, value in eager_model: self.assertIn(var, [x, y, z]) self.assertEqual(value, TRUE())
def test_default_logic_in_is_sat(self): factory = get_env().factory factory.default_logic = QF_BOOL self.assertEqual(factory.default_logic, QF_BOOL) varA = Symbol("A", BOOL) varB = Symbol("B", BOOL) f = And(varA, Not(varB)) self.assertSat(f)
def test_get_implicant_sat(self): varA = Symbol("A", BOOL) varX = Symbol("X", REAL) f = And(varA, Equals(varX, Real(8))) for solver in get_env().factory.all_solvers(logic=QF_LRA): res = get_implicant(f, solver_name=solver) self.assertIsNotNone(res, "Formula was expected to be SAT") self.assertValid(Implies(res, f), logic=QF_LRA)
def solveDecisionProblem(filename): global robots_info global task_info global task_utilities global k robots_info = {} task_info = {} task_utilities = {} k=0 file = open(filename, "r") mode = 0 for line in file: if line=='\n': mode+=1 elif mode==0: k = int(line.strip()) elif mode==1: task_line = line.split() task_info[task_line[0]] = [int(resource) for resource in task_line[2:]] task_utilities[task_line[0]] = int(task_line[1]) elif mode == 2: robot_line = line.split() robots_info[robot_line[0]] = [int(resource) for resource in robot_line[1:]] file.close() # Each robot may be assigned to at most one task # runs in time |Robots||Tasks||Tasks| oneTask = And([Symbol(robot+taskAssigned).Implies(Not(Symbol(robot+task))) for robot in robots_info.keys() for taskAssigned in task_info.keys() for task in task_info.keys() if (taskAssigned != task)]) # A task is satisfied if and only if all of its resource requirements are met # runs in time |Robots||Tasks||ResourceTypes| tasksSatisfied = And([Iff(Symbol(task +"Sat"), And([GE(Plus([Times(Ite(Symbol(robot+task),Int(1), Int(0)), Int(robots_info[robot][i])) for robot in robots_info.keys()]), Int(task_info[task][i])) for i in range(len(task_info[task]))])) for task in task_info.keys()]) # Is the decision problem satisfied # runs in time |Tasks| decisionProb = GE(Plus([Times(Ite(Symbol(task+"Sat"), Int(1), Int(0)), Int(task_utilities[task])) for task in task_info.keys()]), Int(k)) prob = And(oneTask, tasksSatisfied, decisionProb) model = get_model(prob) return model
def add_lemmas(self, hts, prop, lemmas): if len(lemmas) == 0: return (hts, False) self._reset_assertions(self.solver) h_init = hts.single_init() h_trans = hts.single_trans() holding_lemmas = [] lindex = 1 nlemmas = len(lemmas) tlemmas = 0 flemmas = 0 for lemma in lemmas: Logger.log("\nChecking Lemma %s/%s" % (lindex, nlemmas), 1) invar = hts.single_invar() init = And(h_init, invar) trans = And(invar, h_trans, TS.to_next(invar)) if self._check_lemma(hts, lemma, init, trans): holding_lemmas.append(lemma) hts.add_assumption(lemma) hts.reset_formulae() Logger.log("Lemma %s holds" % (lindex), 1) tlemmas += 1 if self._suff_lemmas(prop, holding_lemmas): return (hts, True) else: Logger.log("Lemma %s does not hold" % (lindex), 1) flemmas += 1 msg = "%s T:%s F:%s U:%s" % (status_bar( (float(lindex) / float(nlemmas)), False), tlemmas, flemmas, (nlemmas - lindex)) Logger.inline(msg, 0, not (Logger.level(1))) lindex += 1 Logger.clear_inline(0, not (Logger.level(1))) hts.assumptions = And(holding_lemmas) return (hts, False)
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 test_basic_expr(self): convert = self.bdd_converter.convert bdd_x = convert(self.x) bdd_y = convert(self.y) bdd_x_and_y = self.bdd_converter.ddmanager.And(bdd_x, bdd_y) x_and_y = And(self.x, self.y) converted_expr = convert(x_and_y) self.assertEqual(bdd_x_and_y, converted_expr)
def generate_constraint_for_input_partition(input_partition): formula = None for var_name in input_partition: sym_array = Symbol(var_name, ArrayType(BV32, BV8)) sym_var = BVConcat( Select(sym_array, BV(3, 32)), BVConcat( Select(sym_array, BV(2, 32)), BVConcat(Select(sym_array, BV(1, 32)), Select(sym_array, BV(0, 32))))) constant_info = input_partition[var_name] upper_bound = int(constant_info['upper-bound']) lower_bound = int(constant_info['lower-bound']) sub_formula = And(BVSGE(SBV(upper_bound, 32), sym_var), BVSLE(SBV(lower_bound, 32), sym_var)) if formula is None: formula = sub_formula else: formula = And(formula, sub_formula) return formula
def test_solving_under_assumption(self): v1, v2 = [FreshSymbol() for _ in xrange(2)] xor = Or(And(v1, Not(v2)), And(Not(v1), v2)) for name in get_env().factory.all_solvers(): 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 generate_flipped_path(ppc): """ This function will check if a selected path is feasible ppc : partial path conditoin at chosen control loc chosen_control_loc: branch location selected for flip returns satisfiability of the negated path """ parser = SmtLibParser() new_path = None try: script = parser.get_script(cStringIO(ppc)) formula = script.get_last_formula() prefix = formula.arg(0) constraint = formula.arg(1) new_path = And(prefix, Not(constraint)) assert str(new_path.serialize()) != str(formula.serialize()) except Exception as ex: emitter.debug("Pysmt parser error, skipping path flip") finally: return new_path
def test_pe_edge(self): sym_x = Symbol("x", REAL) # child sym_y = Symbol("y", REAL) # parent x_domain = And(sym_x > Real(-1), sym_x < Real(6)) y_domain = And(sym_y > Real(-2), sym_y < Real(4)) x = TNode(symbol=sym_x, label=1, domains=x_domain) y = TNode(symbol=sym_y, label=0, domains=y_domain) formula = LE(sym_x, sym_y + Real(1)) edge = TEdge(parent=y, child=x, formula=formula) y.add_edge(edge) x_constraints = [[0, 1, 2], [2.5, 3.5, 4]] interval_and_degree = SMI.pe_edge(edge, x_constraints) self.assertListEqual(interval_and_degree[0], [-1.0, 0.0, 3]) self.assertListEqual(interval_and_degree[1], [0, 1.5, 0]) self.assertListEqual(interval_and_degree[2], [1.5, 2.5, 5]) self.assertListEqual(interval_and_degree[3], [2.5, 4, 0])
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 setUp(self): self.x, self.y = Symbol("x"), Symbol("y") self.bdd_solver = Solver(logic=pysmt.logics.BOOL, name='bdd') self.bdd_converter = self.bdd_solver.converter trail = [And, Or, And, Or] f = And(self.x, self.y) for op in trail: f = op(f, f) self.big_tree = f
def check_in_language(tree_str, conf_file): cfg_f, cfg_r = read_features(conf_file) sent_t = Tree.parse(tree_str.strip(), trunc=False) symbols, all_constraints = get_sat_constraints(sent_t, cfg_f, cfg_r, {}, []) problem = And(all_constraints) model = get_model(problem) if model: return tree_to_str(sent_t) else: return None
def non_zero(self): w_reg_list = [] for (weights, bias) in self.net_formula.values(): for w_r, b in zip(weights, bias): for w in w_r: coin = np.random.uniform(0, 1, 1) if coin > 0.5: w_reg_list.append(NotEquals(w, Real(0))) # w_reg_list.append(NotEquals(b, Real(0))) regularize = And(w_reg_list) return regularize
def test_substitution_complex(self): x, y = FreshSymbol(REAL), FreshSymbol(REAL) # y = 0 /\ (Forall x. x > 3 /\ y < 2) f = And(Equals(y, Real(0)), ForAll([x], And(GT(x, Real(3)), LT(y, Real(2))))) if "MSS" in str(self.env.SubstituterClass): subs = { y: Real(0), ForAll([x], And(GT(x, Real(3)), LT(Real(0), Real(2)))): TRUE() } else: assert "MGS" in str(self.env.SubstituterClass) subs = { y: Real(0), ForAll([x], And(GT(x, Real(3)), LT(y, Real(2)))): TRUE() } f_subs = substitute(f, subs).simplify() self.assertEqual(f_subs, TRUE())
def test_generic_wrapper_enable_debug(self): a = Symbol("A", BOOL) f = And(a, Not(a)) for n in self.all_solvers: with Solver(name=n, logic=QF_BOOL, solver_options={'debug_interaction': True}) as s: s.add_assertion(f) res = s.solve() self.assertFalse(res)
def test_substitution_term(self): x, y = FreshSymbol(REAL), FreshSymbol(REAL) # y = 0 /\ Forall x. x > 3 f = And(Equals(y, Real(0)), ForAll([x], GT(x, Real(3)))) subs = {GT(x, Real(3)): TRUE()} f_subs = substitute(f, subs) # Since 'x' is quantified, we cannot replace the term # therefore the substitution does not yield any result. self.assertEqual(f_subs, f)
def test_ackermannization_binary(self): self.env.enable_infix_notation = True a, b = (Symbol(x, INT) for x in "ab") f, g = (Symbol(x, FunctionType(INT, [INT, INT])) for x in "fg") h = Symbol("h", FunctionType(INT, [INT])) formula1 = Not(Equals(f(a, g(a, h(a))), f(b, g(b, h(b))))) formula2 = Equals(a, b) formula = And(formula1, formula2) self._verify_ackermannization(formula)
def test_boolean(self): varA = Symbol("At", INT) varB = Symbol("Bt", INT) f = And(LT(varA, Plus(varB, Int(1))), GT(varA, Minus(varB, Int(1)))) g = Equals(varA, varB) h = Iff(f, g) tc = get_env().stc res = tc.walk(h) self.assertEqual(res, BOOL)
def test_add_assertions(self): varA = Symbol("A", BOOL) varB = Symbol("B", BOOL) varC = Symbol("C", BOOL) assertions = [varA, Implies(varA, varB), Implies(varB, varC)] for name in get_env().factory.all_solvers(logic=QF_BOOL): with Solver(name) as solver: solver.add_assertions(assertions) solver.solve() self.assertTrue(solver.get_py_value(And(assertions)))
def check_step(): self._reset_assertions(self.solver) self._add_assertion(self.solver, self.at_time(And(trans, lemma), 0)) self._add_assertion(self.solver, self.at_time(Not(lemma), 1)) if self._solve(self.solver): Logger.log("Lemma \"%s\" failed for L & T -> L'"%lemma, 2) return False Logger.log("Lemma \"%s\" holds for L & T -> L'"%lemma, 2) return True
def check_init(): self._reset_assertions(self.solver) self._add_assertion(self.solver, self.at_time(And(init, Not(lemma)), 0), comment="Init check") res = self._solve(self.solver) if res: Logger.log("Lemma \"%s\" failed for I -> L"%lemma, 2) return False Logger.log("Lemma \"%s\" holds for I -> L"%lemma, 2) return True
def test_construction(self): """Build an eager model out of a dictionary""" x, y = FreshSymbol(), FreshSymbol() d = {x: TRUE(), y: FALSE()} model = EagerModel(assignment=d) self.assertEqual(model.get_value(x), TRUE()) self.assertEqual(model.get_value(y), FALSE()) self.assertEqual(model.get_value(And(x, y)), FALSE())
def solve(formula, n, max_models=None, solver="msat"): s = Solver(name=solver) st = s.is_sat(formula) if st: vs = [x for xs in variables(n) for x in xs] k = 0 s.add_assertion(formula) while s.solve() and ((not max_models) or k < max_models): k = k + 1 model = s.get_model() s.add_assertion(Not(And([EqualsOrIff(v, model[v]) for v in vs]))) yield to_bn(model, n)
def is_global_circuit(f, c, sign=None): edges = list(zip(c, c[1:] + [c[0]])) k = len(c) + 1 if sign == -1: # an odd number of edges are negative return Or([ And([Or(edge(f, x, j, i, -1) for x in f) for j, i in ls] + [ Or(edge(f, x, j, i, +1) for x in f) for j, i in edges if (j, i) not in ls ]) for m in range(1, k + 1, 2) for ls in combinations(edges, m) ]) if sign == +1: # an even number of edges are negative return Or([ And([Or(edge(f, x, j, i, -1) for x in f) for j, i in ls] + [ Or(edge(f, x, j, i, +1) for x in f) for j, i in edges if (j, i) not in ls ]) for m in range(0, k + 1, 2) for ls in combinations(edges, m) ]) # all edges exist return And([Not(And(edge(f, x, j, i, 0) for x in f)) for j, i in edges])
def test_ackermannization_dictionaries(self): self.env.enable_infix_notation = True a,b = (Symbol(x, INT) for x in "ab") f,g = (Symbol(x, FunctionType(INT, [INT, INT])) for x in "fg") h = Symbol("h", FunctionType(INT, [INT])) formula1 = Not(Equals(f(a, g(a, h(a))), f(b, g(b, h(b))))) formula2 = Equals(a, b) formula = And(formula1, formula2) ackermannization = Ackermannizer() _ = ackermannization.do_ackermannization(formula) terms_to_consts = ackermannization.get_term_to_const_dict() consts_to_terms = ackermannization.get_const_to_term_dict() # The maps have the same length self.assertEqual(len(terms_to_consts), len(consts_to_terms)) # The maps are the inverse of each other for t in terms_to_consts: self.assertEqual(t, consts_to_terms[terms_to_consts[t]]) # Check that the the functions are there for atom in formula.get_atoms(): if atom.is_function_application(): self.assertIsNotNone(terms_to_consts[atom])
def test_basic(self): varA = Symbol("A") f = And(varA, Not(varA)) self.assertEqual(f.size(), 4) self.assertEqual(f.size(SizeOracle.MEASURE_TREE_NODES), 4) self.assertEqual(f.size(SizeOracle.MEASURE_DAG_NODES), 3) self.assertEqual(varA.size(SizeOracle.MEASURE_LEAVES), 1) self.assertEqual(f.size(SizeOracle.MEASURE_DEPTH), 3) self.assertEqual(f.size(SizeOracle.MEASURE_SYMBOLS), 1)
def test_trivial_false_and(self): x,y,z = (Symbol(name) for name in "xyz") f = And(x, y, z, Not(x)) self.assertEqual(f.simplify(), FALSE())
def test_and_flattening(self): x,y,z = (Symbol(name) for name in "xyz") f1 = And(x, y, z) f2 = And(x, And(y, z)) self.assertEqual(f2.simplify(), f1)
# Checking satisfiability of a formula. # # This example shows: # 1. How to build a formula # 2. How to perform substitution # 3. Printing # 4. Satisfiability checking from pysmt.shortcuts import Symbol, And, Not, is_sat varA = Symbol("A") # Default type is Boolean varB = Symbol("B") f = And([varA, Not(varB)]) g = f.substitute({varB:varA}) res = is_sat(f) assert res # SAT print("f := %s is SAT? %s" % (f, res)) res = is_sat(g) print("g := %s is SAT? %s" % (g, res)) assert not res # UNSAT