def get_simple_path(system, k): """Simple path constraint for k-induction: each time encodes a different state """ res = [] for i in xrange(k): subs_i = get_subs(system, i) for j in xrange(i+1, k): subs_j = get_subs(system, j) for v in system.variables: v_i = v.substitute(subs_i) v_j = v.substitute(subs_j) res.append(Not(Equals(v_i, v_j))) return And(res)
def test_identity_walker_simple(self): def walk_and_to_or(formula, args, **kwargs): return Or(args) def walk_or_to_and(formula, args, **kwargs): return And(args) walker = IdentityDagWalker(env=get_env()) walker.set_function(walk_and_to_or, op.AND) walker.set_function(walk_or_to_and, op.OR) x, y, z = Symbol('x'), Symbol('y'), Symbol('z') cnf = And(Or(x, y, z), Or(z, Not(y))) fake_dnf = Or(And(x, y, z), And(z, Not(y))) result = walker.walk(cnf) self.assertEqual(result, fake_dnf) alternation = Or(cnf, Not(cnf)) expected = And(fake_dnf, Not(fake_dnf)) result = walker.walk(alternation) self.assertEqual(result, expected)
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_solving_under_assumption_mixed(self): x = Symbol("x", REAL) v1 = GT(x, Real(10)) v2 = Symbol("v2", BOOL) xor = Or(And(v1, Not(v2)), And(Not(v1), v2)) for name in get_env().factory.all_solvers(logic=QF_UFLIRA): 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 Eq(in0, in1, out): # INVAR: (((in0 = in1) -> (out = #b1)) & ((in0 != in1) -> (out = #b0))) vars_ = [in0, in1, out] comment = "Eq (in0, in1, out) = (%s, %s, %s)" % (tuple( [x.symbol_name() for x in vars_])) Logger.log(comment, 3) if Modules.functional: if out.symbol_type() == BOOL: invar = EqualsOrIff(out, EqualsOrIff(in0, in1)) else: invar = EqualsOrIff(out, BVComp(in0, in1)) else: eq = EqualsOrIff(in0, in1) if out.symbol_type() == BOOL: out0 = Not(out) out1 = out else: out0 = EqualsOrIff(out, BV(0, 1)) out1 = EqualsOrIff(out, BV(1, 1)) invar = And(Implies(eq, out1), Implies(Not(eq), out0)) ts = TS(comment) ts.vars, ts.invar = set(vars_), invar return ts
def test_generic_wrapper_eager_model(self): a = Symbol("A", BOOL) b = Symbol("B", BOOL) f = And(a, Not(b)) for n in self.all_solvers: model = None with Solver(name=n, logic=QF_BOOL) as s: s.add_assertion(f) res = s.solve() self.assertTrue(res) model = s.get_model() self.assertFalse(model.get_value(b).is_true()) self.assertTrue(model.get_value(a).is_true())
def to_smv(self, smv_file_name): ts_enc = TSEncoder(self.trace, self.spec_list, self.opts.simplify_trace, self.stats) ts = ts_enc.get_ts_encoding() ts2smv = SmvTranslator(ts_enc.pysmt_env, ts.state_vars, ts.input_vars, ts.init, ts.trans, Not(ts_enc.error_prop)) with open(smv_file_name, "wt") as f: ts2smv.to_smv(f) f.close()
def test_misc(self): bool_list = [ And(self.x, self.y), Or(self.x, self.y), Not(self.x), self.x, Equals(self.p, self.q), GE(self.p, self.q), LE(self.p, self.q), GT(self.p, self.q), LT(self.p, self.q), Bool(True), Ite(self.x, self.y, self.x) ] # TODO: FORALL EXISTS real_list = [ self.r, Real(4), Plus(self.r, self.s), Plus(self.r, Real(2)), Minus(self.s, self.r), Times(self.r, Real(1)), Div(self.r, Real(1)), Ite(self.x, self.r, self.s), ] int_list = [ self.p, Int(4), Plus(self.p, self.q), Plus(self.p, Int(2)), Minus(self.p, self.q), Times(self.p, Int(1)), Ite(self.x, self.p, self.q), ] for f in bool_list: t = self.tc.walk(f) self.assertEqual(t, BOOL, f) for f in real_list: t = self.tc.walk(f) self.assertEqual(t, REAL, f) for f in int_list: t = self.tc.walk(f) self.assertEqual(t, INT, f)
def run_ic3(self, nuxmv_path, ic3_frames): ts_enc = TSEncoder(self.trace, self.spec_list, self.opts.simplify_trace, self.stats) ts = ts_enc.get_ts_encoding() self.stats.start_timer(Stats.VERIFICATION_TIME,True) nuxmv_driver = NuXmvDriver(ts_enc.pysmt_env, ts, nuxmv_path) (result, trace) = nuxmv_driver.ic3(Not(ts_enc.error_prop), ic3_frames) self.stats.stop_timer(Stats.VERIFICATION_TIME,True) self.stats.write_times(sys.stdout, Stats.VERIFICATION_TIME) return (result, trace, ts_enc.mapback)
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() 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()) return new_path
def test_model(self): s = Symbol("s", STRING) f = [ Equals(StrLength(s), Int(5)), Equals(StrCharAt(s, Int(0)), String("A")), Not(Equals(StrCharAt(s, Int(2)), String("B"))) ] with Solver(logic=QF_SLIA) as solver: solver.add_assertion(And(f)) res = solver.solve() self.assertTrue(res) s_value = solver.get_value(s) py_value = s_value.constant_value() self.assertEqual(py_value[0], "A") self.assertNotEqual(py_value[1], "B") self.assertEqual(len(py_value), 5)
def get_simple_path(self, k): """Simple path constraint for k-induction: each time encodes a different state """ res = [] for i in range(k + 1): subs_i = self.get_subs(i) for j in range(i + 1, k + 1): state = [] subs_j = self.get_subs(j) for v in self.system.variables: v_i = v.substitute(subs_i) v_j = v.substitute(subs_j) state.append(Not(EqualsOrIff(v_i, v_j))) res.append(Or(state)) return And(res)
def test_1(self): var_name = "counter_1" self.enc.add_var(var_name, 1) b0 = self.enc._get_bitvar(var_name,0) e = self.enc.eq_val(var_name, 0) self._is_eq(e, Not(b0)) e = self.enc.eq_val(var_name, 1) self._is_eq(e, b0) with self.assertRaises(AssertionError): e = self.enc.eq_val(var_name, 2) mask = self.enc.get_mask(var_name) self._is_eq(mask, TRUE())
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 stepwise(f, ms): adms = admissible_states(ms) mltb = multi_level_to_bool(ms) # if xij=0, fi(j+1) must be 0 c0 = [ Not(f[x][mltb[(i, j + 1)] - 1]) for i in range(1, len(ms) + 1) for j in range(1, ms[i - 1]) for x in adms if x[mltb[(i, j)] - 1] == 0 ] # if xij=1, fi(j-1) must be 1 c1 = [ f[x][mltb[(i, j - 1)] - 1] for i in range(1, len(ms) + 1) for j in range(2, ms[i - 1] + 1) for x in adms if x[mltb[(i, j)] - 1] == 1 ] return And(c0 + c1)
def compile_ftrans(self): if self.ftrans is None: return None ret_trans = TRUE() ret_invar = TRUE() use_ites = False if use_ites: for var, cond_assign_list in self.ftrans.items(): if TS.has_next(var): ite_list = TS.to_prev(var) else: ite_list = var for (condition, value) in reversed(cond_assign_list): if condition == TRUE(): ite_list = value else: ite_list = Ite(condition, value, ite_list) if TS.has_next(ite_list): ret_trans = And(ret_trans, EqualsOrIff(var, ite_list)) else: ret_invar = And(ret_invar, EqualsOrIff(var, ite_list)) else: for var, cond_assign_list in self.ftrans.items(): effects = [] all_neg_cond = [] for (condition, value) in cond_assign_list: effects.append( simplify(Implies(condition, EqualsOrIff(var, value)))) all_neg_cond.append(Not(condition)) if not TS.has_next(var) and not TS.has_next(condition): ret_invar = And(ret_invar, And(effects)) else: ret_trans = And(ret_trans, And(effects)) if TS.has_next(var): no_change = EqualsOrIff(var, TS.to_prev(var)) ret_trans = And( ret_trans, simplify(Implies(And(all_neg_cond), no_change))) return (ret_invar, ret_trans)
def get_sts(self, params): if len(params) != len(self.interface.split()): Logger.error("Invalid parameters for clock behavior \"%s\"" % (self.name)) clk = params[0] valuepar = params[1] if (not type(clk) == FNode) or (not clk.is_symbol()): Logger.error("Clock symbol \"%s\" not found" % (str(clk))) if (type(valuepar) == FNode) and (valuepar.is_bv_constant()): value = valuepar.constant_value() else: try: value = int(valuepar) except: Logger.error( "Clock value should be an integer number instead of \"%s\"" % valuepar) init = [] invar = [] trans = [] vars = set([]) if clk.symbol_type().is_bv_type(): pos_clk = EqualsOrIff(clk, BV(1, 1)) neg_clk = EqualsOrIff(clk, BV(0, 1)) else: pos_clk = clk neg_clk = Not(clk) if value == 1: invar.append(pos_clk) else: invar.append(neg_clk) ts = TS("Clock Behavior") ts.vars, ts.init, ts.invar, ts.trans = vars, And(init), And( invar), And(trans) Logger.log( "Adding clock behavior \"%s(%s)\"" % (self.name, ", ".join([str(p) for p in params])), 1) return ts
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) prefix = None if self.config.prefix is not None: prefix = self.config.prefix + "-ind" 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 solve_safety_inc_bwd(self, hts, prop, k, assert_property=False): self._reset_assertions(self.solver) if TS.has_next(prop): Logger.error( "Invariant checking with next variables only supports FWD strategy" ) init = hts.single_init() trans = hts.single_trans() invar = hts.single_invar() formula = self.at_ptime(And(Not(prop), invar), -1) Logger.log("Add not property at time %d" % 0, 2) self._add_assertion(self.solver, formula) t = 0 while (t < k + 1): self._push(self.solver) pinit = self.at_ptime(init, t - 1) Logger.log("Add init at time %d" % t, 2) self._add_assertion(self.solver, pinit) if self._solve(self.solver): Logger.log("Counterexample 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) trans_t = self.unroll(trans, invar, t, t + 1) self._add_assertion(self.solver, trans_t) if assert_property and t > 0: prop_t = self.unroll(TRUE(), prop, t - 1, t) self._add_assertion(self.solver, prop_t) Logger.log("Add property at time %d" % t, 2) t += 1 return (t - 1, None)
def partition_input_space(path_condition, assertion): global pool, result_list result_list = [] is_exist = And(path_condition, Not(assertion)) is_always = And(path_condition, assertion) input_space = generator.generate_input_space(path_condition) if oracle.is_loc_in_trace(values.CONF_LOC_BUG): if is_sat(is_exist): emitter.normal("\tpartitioning input space") partition_model = generator.generate_model(is_exist) partition_model, is_multi_dimension = extractor.extract_input_list( partition_model) partition_list = generator.generate_partition_for_input_space( partition_model, input_space, is_multi_dimension) if values.DEFAULT_OPERATION_MODE in ["sequential"]: for partition in partition_list: # emitter.emit_patch(patch, message="\tabstract patch: ") result_list.append( refine.refine_input_partition(path_condition, assertion, partition, is_multi_dimension)) else: emitter.normal("\t\tstarting parallel computing") pool = mp.Pool(mp.cpu_count(), initializer=mute) for partition in partition_list: pool.apply_async(refine.refine_input_partition, args=(path_condition, assertion, partition, is_multi_dimension), callback=collect_result) pool.close() emitter.normal("\t\twaiting for thread completion") pool.join() filtered_list = list() for partition in result_list: if not partition: continue if isinstance(partition, list): for sub_partition in partition: filtered_list.append(sub_partition) else: filtered_list.append(partition) result_list = filtered_list return result_list
def find_bug_inc(self, k, trace_enc=None): solver = self._get_solver() res = None for i in range(k + 1): logging.info("Finding bugs at step %d..." % i) f_at_i = self.get_ts_enc_at_i(i) solver.add_assertion(f_at_i) if (trace_enc is not None): tenc_at_i = self.get_trace_enc_at_i(i, trace_enc) solver.add_assertion(tenc_at_i) if not USE_ASSUMPTIONS: solver.push() error_at_i = self.helper.get_formula_at_i(self.all_vars, self.error, i) solver.add_assertion(error_at_i) res = self.solve(solver, i) if res is not None: return res solver.pop() else: # ENCODE # b_var <-> bug #add assumption b_var # check, then assert negation of prop na = Symbol("__va__%d" % i, BOOL) error_at_i = self.helper.get_formula_at_i(self.all_vars, self.error, i) solver.add_assertion(Iff(na, error_at_i)) app = solver.solve([na]) if (app): logging.debug("The encoding is satisfiable...") model = solver.get_model() trace = self._build_trace(model, k) return trace else: logging.debug("No bugs found up to %d steps" % k) solver.add_assertion(Not(na)) return res
def _compute(): i = 0 while i < len(self.setd): if self.optns.usecld: _do_cld_check(self.setd[i:]) i = 0 if self.setd: # it may be empty after the clause D check self.calls += 1 self.ss_assumps.append(self.setd[i]) if not self.oracle.solve([self.selv] + self.ss_assumps + self.bb_assumps): self.ss_assumps.pop() self.bb_assumps.append(Not(self.setd[i])) i += 1
def getCandidates(): varA = Symbol("A") varB = Symbol("B") f = And([varA, Not(varB)]) scholar = SuperScholar() scholar.trainModel('./trainingset/book.txt') scholar.writeModel('./model.txt') scholar.gao(u'南山南') scholar.gao(u'冰比冰水冰') scholar.gao(u'明天去操场操到天明') scholar.gao(u'大波美人鱼人美波大') scholar.gao(u'人') scholar.gao(u'人间') scholar.gao(u'人间美') scholar.gao(u'人间佳草') scholar.gao(u'人间一杯酒') scholar.gao(u'我爸是李刚')
def get_models(self, fml, blocking, count): t_logic = get_logic(fml) models = [] m_index = 0 with Solver(logic=t_logic) as solver: solver.add_assertion(fml) while (solver.solve()): partial_model = [ EqualsOrIff(b, solver.get_value(b)) for b in blocking ] m = solver.get_model() models.append(m) solver.add_assertion(Not(And(partial_model))) m_index += 1 if m_index > count: break return models
def test_theory_oracle(self): from pysmt.oracles import get_logic s1 = Symbol("s1", STRING) s2 = Symbol("s2", STRING) f = Equals(StrConcat(s1, s1), s2) theory = get_logic(f).theory self.assertTrue(theory.strings, theory) f = Not( And(GE(StrLength(StrConcat(s1, s2)), StrLength(s1)), GE(StrLength(StrConcat(s1, s2)), StrLength(s2)))) theory = get_logic(f).theory self.assertTrue(theory.strings, theory) f = And(GT(StrLength(s1), Int(2)), GT(StrLength(s2), StrLength(s1)), And(StrSuffixOf(s2, s1), StrContains(s2, s1))) theory = get_logic(f).theory self.assertTrue(theory.strings, theory)
def is_circuit(f, x, 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([edge(f, x, j, i, -1) for j, i in ls] + [edge(f, x, j, i, +1) 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([edge(f, x, j, i, -1) for j, i in ls] + [edge(f, x, j, i, +1) 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(edge(f, x, j, i, 0)) for j, i in edges])
def IsPlan(plan, gridsize, starts, goals, obstacles): # Begin by snapping all coordinates to N x N space. This is correct # according to the problem formulation given in Definition 1 starts = IntifyCoords(starts) goals = IntifyCoords(goals) obstacles = IntifyCoords(obstacles) # (1) A i in N_R : x_i^1 = S_i init = And( [SamePosition(path[0], starts[i]) for i, path in enumerate(plan)]) # (2) A i in N_r : A t in N_T : x_i^t in W = Z_n x Z_n bounds = And( [And([IsOnGrid(step, gridsize) for step in path]) for path in plan]) # (3) A i in N_R : A t in N_{T-1} : E u in U : delta(x_i^t, u) = x_i^{t+1} # Note this isn't exactly the same, but it's morally equivalent, just # modulo the knowledge of the function delta. adjacency = And([IsConnected(path) for path in plan]) # (4) A i in N_R : E t in N_T : G_i in x_i^T reach = And([ Or([SamePosition(coord, goals[i]) for coord in path]) for i, path in enumerate(plan) ]) # (5) A (i, j) in N_R x N_R : A t in N_T : # x_i^t \cap x_j^t \neq \emptyset => i = j avoid = And([ Implies(SamePosition(plan[i][k], plan[j][k]), Equals(Int(i), Int(j))) for k in range(len(plan[0])) for i in range(len(plan)) for j in range(len(plan)) ]) # (6) A i in N_R : A t in N_T : x_i^t \cap \Omega = \emptyset obstacles = And([ Not(SamePosition(coord, obstacle)) for path in plan for coord in path for obstacle in obstacles ]) # valid(x) = (1) ^ (2) ^ (3) ^ (4) ^ (5) ^ (6) return And(init, bounds, adjacency, reach, avoid, obstacles)
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 _enum_trans_one_side(solver, labels, index, results, trail, label, negate=False): literal = label.get_formula() if negate: literal = Not(literal) solver.push() solver.add_assertion(literal) if (solver.solve()): trail.append(literal) _enum_trans_rec(solver, labels, index, results, trail) # side effect on trail, backtrack the trail of assignments trail.pop() solver.pop()
def stratify_invariant(self, inv_set_l): print("\nstratifying inductive invariant:") for label, v in inv_set_l: f = self.replaceDefinitions(v) # print("%s" % pretty_serialize(f)) print(" %s:" % label) print(" pos:") self.strat.update_stratify(f) print(" neg:") self.strat.update_stratify(Not(f)) if not self.strat.has_exists: print("\t(with inv: no exists detected)") eprint("\t(with inv: no exists detected)") print("\t(with inv: epr: %s)" % self.is_epr()) eprint("\t(with inv: epr: %s)" % self.is_epr()) self.strat.print_all_arcs() print( "-----------------------------------------------------------------" )