def test_sets_the_global_values(self): glob.flatten_hierarchy() glob.encode_variables() with self.assertRaises(NuSMVNeedBooleanModelError): glob.master_bool_sexp_fsm() glob.build_boolean_model() self.assertIsNotNone(glob.master_bool_sexp_fsm())
def generate_counter_example(fsm, problem, solver, k, descr="BMC counter example"): """ Generates a counter example for `problem` evaluated against `fsm` as identified by `solver` (problem has a length `k`) but prints nothing. .. note:: If you are looking for something more advanced, you might want to look at :func:`pynusmv.be.encoder.BeEnc.decode_sat_model` which does the same thing but is more complete. :param fsm: the FSM against which problem was evaluated :param problem: the SAT problem used to identify a counter example :param solver: the SAT solver that identified a counter example :param k: the length of the generated problem (length in terms of state) :param descr: a description of what the generated counter example is about :raises ValueError: whenever the problem or the solver is None or when the problem bound `k` is negative. """ if problem is None: raise ValueError("a problem must be given") if solver is None: raise ValueError("a solver must be given") if k < 0: raise ValueError("the problem bound `k` must be non negative") ptr = _bmc.Bmc_Utils_generate_cntexample( fsm.encoding._ptr, solver._as_SatSolver_ptr(), problem._ptr, k, descr, glob.master_bool_sexp_fsm().symbols_list._ptr) return Trace(ptr)
def test_iter(self): """tests the behavior of assign and value""" with BmcSupport(): sexp_fsm = master_bool_sexp_fsm() be_fsm = master_be_fsm() # empty trace trace = Trace.create( "Dummy example", TraceType.COUNTER_EXAMPLE, sexp_fsm.symbol_table, sexp_fsm.symbols_list, is_volatile=True, ) step1 = trace.steps[1] yes = Node.from_ptr(parse_simple_expression("TRUE")) no = Node.from_ptr(parse_simple_expression("FALSE")) v = be_fsm.encoding.by_name["v"].name self.assertEqual([], list(step1)) step1 += v, yes self.assertEqual([(v, yes)], list(step1)) # += really ASSIGNS a value, not append step1 += v, no self.assertEqual([(v, no)], list(step1))
def test_assign_value__magicmethod__(self): """tests the behavior of assign and value""" with BmcSupport(): sexp_fsm = master_bool_sexp_fsm() be_fsm = master_be_fsm() # empty trace trace = Trace.create( "Dummy example", TraceType.COUNTER_EXAMPLE, sexp_fsm.symbol_table, sexp_fsm.symbols_list, is_volatile=True, ) step1 = trace.steps[1] yes = Node.from_ptr(parse_simple_expression("TRUE")) no = Node.from_ptr(parse_simple_expression("FALSE")) v = be_fsm.encoding.by_name["v"].name self.assertIsNone(step1.value[v]) step1 += (v, yes) self.assertEqual(yes, step1.value[v]) step1 += (v, no) self.assertEqual(no, step1.value[v])
def test_force_loopback(self): with BmcSupport(): sexp_fsm = master_bool_sexp_fsm() # empty trace trace = Trace.create( "Dummy example", TraceType.COUNTER_EXAMPLE, sexp_fsm.symbol_table, sexp_fsm.symbols_list, is_volatile=True, ) step1 = trace.steps[1] # because last step is never a loopback trace.append_step() # must fail when trace is thawed with self.assertRaises(NuSmvIllegalTraceStateError): step1.force_loopback() trace.freeze() self.assertFalse(step1.is_loopback) step1.force_loopback() self.assertTrue(step1.is_loopback)
def build_master_be_fsm(): """ Creates the BE fsm from the Sexpr FSM. Currently the be_enc is a singleton global private variable which is shared between all the BE FSMs. If not previoulsy committed (because a boolean encoder was not available at the time due to the use of coi) the determinization layer will be committed to the be_encoder :raises NuSMVBeEncNotInitializedError: if the global BeEnc singleton is not initialized """ global __be_fsm # raises the exception if necessary be_enc = BeEnc.global_singleton_instance() sym_table = be_enc.symbol_table if _symb_table.SymbTable_get_layer(sym_table._ptr, "inlining") is not None: # commits the determ layer if not previously committed if not _baseenc.BaseEnc_layer_occurs(be_enc._ptr, "determ"): _baseenc.BaseEnc_commit_layer(be_enc._ptr, "determ") # commits the inlining layer if not previously committed # note: I find this a little bit weird, but that's the way NuSMV proceeds if not _baseenc.BaseEnc_layer_occurs(be_enc._ptr, "inlining"): _baseenc.BaseEnc_commit_layer(be_enc._ptr, "inlining") # actual fsm creation __be_fsm = BeFsm.create_from_sexp(be_enc, glob.master_bool_sexp_fsm()) propdb = _prop.PropPkg_get_prop_database() _prop.PropDb_master_set_be_fsm(propdb, __be_fsm._ptr);
def test_fill_counter_example(self): load_from_string(""" MODULE main VAR v : boolean; w : boolean; ASSIGN init(v) := TRUE; next(v) := !v; init(w) := FALSE; next(w) := !w; """) with BmcSupport(): bound = 2 fsm = master_be_fsm() sexpfsm = master_bool_sexp_fsm() expr = Node.from_ptr(parse_ltl_spec("F ( w <-> v )")) pb = generate_ltl_problem(fsm, expr, bound=bound) cnf = pb.inline(True).to_cnf() solver = SatSolverFactory.create() solver += cnf solver.polarity(cnf, Polarity.POSITIVE) self.assertEqual(SatSolverResult.SATISFIABLE, solver.solve()) trace = Trace.create("FILLED", TraceType.COUNTER_EXAMPLE, sexpfsm.symbol_table, sexpfsm.symbols_list, True) bmcutils.fill_counter_example(fsm, solver, bound, trace) self.assertIsNotNone(trace) self.assertEqual(2, len(trace)) print(trace)
def test_language_contains(self): with BmcSupport(): sexp_fsm = master_bool_sexp_fsm() be_fsm = master_be_fsm() trace = Trace.create( "Dummy example", TraceType.COUNTER_EXAMPLE, sexp_fsm.symbol_table, sexp_fsm.symbols_list, is_volatile=True, ) v = be_fsm.encoding.by_name["v"] w = be_fsm.encoding.by_name["w"] f = be_fsm.encoding.by_name["f"] i = be_fsm.encoding.by_name["i"] self.assertTrue(v.name in trace) self.assertTrue(w.name in trace) self.assertTrue(f.name in trace) self.assertTrue(i.name in trace) x = parse_simple_expression("x") self.assertFalse(Node.from_ptr(x) in trace)
def test_is_loopback_when_frozen(self): with BmcSupport(): sexp_fsm = master_bool_sexp_fsm() be_fsm = master_be_fsm() # empty trace trace = Trace.create("Dummy example", TraceType.COUNTER_EXAMPLE, sexp_fsm.symbol_table, sexp_fsm.symbols_list, is_volatile=True) step1 = trace.steps[1] step2 = trace.append_step() yes = Node.from_ptr(parse_simple_expression("TRUE")) no = Node.from_ptr(parse_simple_expression("FALSE")) v = be_fsm.encoding.by_name['v'].name step1 += (v, yes) step2 += (v, no) trace.freeze() step1.force_loopback() self.assertTrue(step1.is_loopback) self.assertFalse(step2.is_loopback) step2.force_loopback() self.assertTrue(step1.is_loopback) # last step is never a loopback self.assertFalse(step2.is_loopback) trace.thaw() self.assertFalse(step1.is_loopback) self.assertFalse(step2.is_loopback)
def test_iter(self): """tests the behavior of assign and value""" with BmcSupport(): sexp_fsm = master_bool_sexp_fsm() be_fsm = master_be_fsm() # empty trace trace = Trace.create("Dummy example", TraceType.COUNTER_EXAMPLE, sexp_fsm.symbol_table, sexp_fsm.symbols_list, is_volatile=True) step1 = trace.steps[1] yes = Node.from_ptr(parse_simple_expression("TRUE")) no = Node.from_ptr(parse_simple_expression("FALSE")) v = be_fsm.encoding.by_name['v'].name self.assertEqual([], list(step1)) step1 += v, yes self.assertEqual([(v, yes)], list(step1)) # += really ASSIGNS a value, not append step1 += v, no self.assertEqual([(v, no)], list(step1))
def test_steps(self): with BmcSupport(): sexp_fsm = master_bool_sexp_fsm() trace = Trace.create( "Dummy example", TraceType.COUNTER_EXAMPLE, sexp_fsm.symbol_table, sexp_fsm.symbols_list, is_volatile=True, ) # must raise an exception when the indice is not valid with self.assertRaises(KeyError): trace.steps[-1] with self.assertRaises(KeyError): trace.steps[0] with self.assertRaises(KeyError): trace.steps[2] self.assertIsNotNone(trace.steps[1]) # once a step is appended, we can access one offset further step2 = trace.append_step() self.assertEquals(step2, trace.steps[2])
def test_concat(self): with BmcSupport(): sexp_fsm = master_bool_sexp_fsm() be_fsm = master_be_fsm() trace = Trace.create("Dummy example", TraceType.COUNTER_EXAMPLE, sexp_fsm.symbol_table, sexp_fsm.symbols_list, is_volatile=True) spec = Node.from_ptr(parse_ltl_spec("F (w <-> v)")) bound = 2 problem = generate_ltl_problem(be_fsm, spec, bound=bound) #.inline(True) cnf = problem.to_cnf() solver = SatSolverFactory.create() solver += cnf solver.polarity(cnf, Polarity.POSITIVE) solver.solve() other = generate_counter_example(be_fsm, problem, solver, bound) trace.concat(other) self.assertEquals(-1, trace.id) self.assertFalse(trace.is_registered) self.assertEquals("Dummy example", trace.description) self.assertEquals(TraceType.COUNTER_EXAMPLE, trace.type) self.assertTrue(trace.is_volatile) self.assertEquals(2, trace.length) self.assertEquals(2, len(trace)) self.assertFalse(trace.is_empty) self.assertFalse(trace.is_frozen) self.assertTrue(trace.is_thawed)
def __enter__(self): """Performs what one would usually do in setUp""" init_nusmv() load_from_file(self.model) go_bmc() self.testcase.sexpfsm = master_bool_sexp_fsm() self.testcase.befsm = master_be_fsm() self.testcase.enc = self.testcase.befsm.encoding self.testcase.mgr = self.testcase.enc.manager
def test_input_var(self): with BmcSupport(): sexp_fsm = master_bool_sexp_fsm() trace = Trace.create("Dummy example", TraceType.COUNTER_EXAMPLE, sexp_fsm.symbol_table, sexp_fsm.symbols_list, is_volatile=True) self.assertEquals("NodeList[i]", str(trace.input_vars))
def test_iter(self): with BmcSupport(): sexp_fsm = master_bool_sexp_fsm() trace = Trace.create("Dummy example", TraceType.COUNTER_EXAMPLE, sexp_fsm.symbol_table, sexp_fsm.symbols_list, is_volatile=True) self.assertEquals(list(trace.__iter__()), [trace.steps[1]]) step2 = trace.append_step() self.assertEquals(list(trace.__iter__()), [trace.steps[1], step2])
def test_register(self): with BmcSupport(): sexp_fsm = master_bool_sexp_fsm() trace = Trace.create("Dummy example", TraceType.COUNTER_EXAMPLE, sexp_fsm.symbol_table, sexp_fsm.symbols_list, is_volatile=True) trace.register(42) self.assertEquals(42, trace.id) self.assertTrue(trace.is_registered)
def test_input_var(self): with BmcSupport(): sexp_fsm = master_bool_sexp_fsm() trace = Trace.create( "Dummy example", TraceType.COUNTER_EXAMPLE, sexp_fsm.symbol_table, sexp_fsm.symbols_list, is_volatile=True, ) self.assertEquals("NodeList[i]", str(trace.input_vars))
def test_iter(self): with BmcSupport(): sexp_fsm = master_bool_sexp_fsm() trace = Trace.create( "Dummy example", TraceType.COUNTER_EXAMPLE, sexp_fsm.symbol_table, sexp_fsm.symbols_list, is_volatile=True, ) self.assertEquals(list(trace.__iter__()), [trace.steps[1]]) step2 = trace.append_step() self.assertEquals(list(trace.__iter__()), [trace.steps[1], step2])
def test_append_step(self): with BmcSupport(): sexp_fsm = master_bool_sexp_fsm() trace = Trace.create("Dummy example", TraceType.COUNTER_EXAMPLE, sexp_fsm.symbol_table, sexp_fsm.symbols_list, is_volatile=True) self.assertEquals(0, len(trace)) step = trace.append_step() self.assertIsNotNone(step) self.assertEquals(TraceStep, type(step)) self.assertEquals(1, len(trace))
def test_register(self): with BmcSupport(): sexp_fsm = master_bool_sexp_fsm() trace = Trace.create( "Dummy example", TraceType.COUNTER_EXAMPLE, sexp_fsm.symbol_table, sexp_fsm.symbols_list, is_volatile=True, ) trace.register(42) self.assertEquals(42, trace.id) self.assertTrue(trace.is_registered)
def get_symbol(name): """ Conveniency method to retrieve a symbol (not necessarily a variable, it can also be a DEFINE) by its name. :param name: a string version of the name of the symbol to retrieve :return: a Node standing for the looked up symbol or None if it could not be found. :raises ValueError: when the requested name cannot be found in the symbol table """ try: sexpfsm = glob.master_bool_sexp_fsm() return next(x for x in sexpfsm.symbols_list if str(x) == name) except StopIteration: #raised when the 'name' key could not be found, rethrow raise ValueError("{} not found in the symbol table".format(name))
def test_append_step(self): with BmcSupport(): sexp_fsm = master_bool_sexp_fsm() trace = Trace.create( "Dummy example", TraceType.COUNTER_EXAMPLE, sexp_fsm.symbol_table, sexp_fsm.symbols_list, is_volatile=True, ) self.assertEquals(0, len(trace)) step = trace.append_step() self.assertIsNotNone(step) self.assertEquals(TraceStep, type(step)) self.assertEquals(1, len(trace))
def test_freeze(self): with BmcSupport(): sexp_fsm = master_bool_sexp_fsm() trace = Trace.create("Dummy example", TraceType.COUNTER_EXAMPLE, sexp_fsm.symbol_table, sexp_fsm.symbols_list, is_volatile=True) trace.freeze() self.assertTrue(trace.is_frozen) self.assertFalse(trace.is_thawed) # it may be called two times in a row trace.freeze() self.assertTrue(trace.is_frozen) self.assertFalse(trace.is_thawed)
def test_freeze(self): with BmcSupport(): sexp_fsm = master_bool_sexp_fsm() trace = Trace.create( "Dummy example", TraceType.COUNTER_EXAMPLE, sexp_fsm.symbol_table, sexp_fsm.symbols_list, is_volatile=True, ) trace.freeze() self.assertTrue(trace.is_frozen) self.assertFalse(trace.is_thawed) # it may be called two times in a row trace.freeze() self.assertTrue(trace.is_frozen) self.assertFalse(trace.is_thawed)
def test_is_complete(self): with BmcSupport(): sexp_fsm = master_bool_sexp_fsm() be_fsm = master_be_fsm() trace = Trace.create("Dummy example", TraceType.COUNTER_EXAMPLE, sexp_fsm.symbol_table, sexp_fsm.symbols_list, is_volatile=True) # vacuously true self.assertTrue(trace.is_complete(NodeList.from_list([]))) v = be_fsm.encoding.by_name['v'].name self.assertFalse(trace.is_complete(NodeList.from_list([v]))) step = trace.steps[1] yes = Node.from_ptr(parse_simple_expression("TRUE")) step += (v, yes) self.assertTrue(trace.is_complete(NodeList.from_list([v])))
def test_create(self): # This function may not provoke any segfault (even though) freeit is # manually set to True when creating a trace. # besides that, the trace must be thawed, empty and have length 0 with BmcSupport(): sexp_fsm = master_bool_sexp_fsm() trace = Trace.create("Dummy example", TraceType.COUNTER_EXAMPLE, sexp_fsm.symbol_table, sexp_fsm.symbols_list, is_volatile=True) self.assertEquals(-1, trace.id) self.assertFalse(trace.is_registered) self.assertEquals("Dummy example", trace.description) self.assertEquals(TraceType.COUNTER_EXAMPLE, trace.type) self.assertEquals(0, trace.length) self.assertTrue(trace.is_empty) self.assertTrue(trace.is_volatile) self.assertFalse(trace.is_frozen) self.assertTrue(trace.is_thawed) self.assertEquals(list(trace.symbols), list(sexp_fsm.symbols_list))
def test_force_loopback(self): with BmcSupport(): sexp_fsm = master_bool_sexp_fsm() # empty trace trace = Trace.create("Dummy example", TraceType.COUNTER_EXAMPLE, sexp_fsm.symbol_table, sexp_fsm.symbols_list, is_volatile=True) step1 = trace.steps[1] # because last step is never a loopback trace.append_step() # must fail when trace is thawed with self.assertRaises(NuSmvIllegalTraceStateError): step1.force_loopback() trace.freeze() self.assertFalse(step1.is_loopback) step1.force_loopback() self.assertTrue(step1.is_loopback)
def test_language_contains(self): with BmcSupport(): sexp_fsm = master_bool_sexp_fsm() be_fsm = master_be_fsm() trace = Trace.create("Dummy example", TraceType.COUNTER_EXAMPLE, sexp_fsm.symbol_table, sexp_fsm.symbols_list, is_volatile=True) v = be_fsm.encoding.by_name['v'] w = be_fsm.encoding.by_name['w'] f = be_fsm.encoding.by_name['f'] i = be_fsm.encoding.by_name['i'] self.assertTrue(v.name in trace) self.assertTrue(w.name in trace) self.assertTrue(f.name in trace) self.assertTrue(i.name in trace) x = parse_simple_expression("x") self.assertFalse(Node.from_ptr(x) in trace)
def test_steps(self): with BmcSupport(): sexp_fsm = master_bool_sexp_fsm() trace = Trace.create("Dummy example", TraceType.COUNTER_EXAMPLE, sexp_fsm.symbol_table, sexp_fsm.symbols_list, is_volatile=True) # must raise an exception when the indice is not valid with self.assertRaises(KeyError): trace.steps[-1] with self.assertRaises(KeyError): trace.steps[0] with self.assertRaises(KeyError): trace.steps[2] self.assertIsNotNone(trace.steps[1]) # once a step is appended, we can access one offset further step2 = trace.append_step() self.assertEquals(step2, trace.steps[2])
def mk_observable_names(args): """ returns the set of symbols names that need to be considered observable in the context of this diagnosability test. .. note:: The output of this function is typically what need to be passed to `mk_observable_vars` :param args: the arguments given on the command line :return: the list of variable names corresponding to the patterns specified by the end user. """ # take observable = set(args.observable) # handle the --observable-inputs (-oi) command line flag if args.observable_inputs: scalr_name = lambda x: str(x.scalar) input_vars = map(scalr_name, master_be_fsm().encoding.input_variables) observable = observable | set(input_vars) # handle the external config file (--observable-file // -of) and the # multiple --observable-regex (-or) command line options regexes = set(args.observable_regex) if args.observable_file: with open(args.observable_file) as f: for line in f: regexes = regexes | set(line.split(";")) for symbol in master_bool_sexp_fsm().symbols_list: for regex in regexes: if fullmatch(regex.strip(), str(symbol)): observable.add(str(symbol)) return observable
def test_is_loopback_when_frozen(self): with BmcSupport(): sexp_fsm = master_bool_sexp_fsm() be_fsm = master_be_fsm() # empty trace trace = Trace.create( "Dummy example", TraceType.COUNTER_EXAMPLE, sexp_fsm.symbol_table, sexp_fsm.symbols_list, is_volatile=True, ) step1 = trace.steps[1] step2 = trace.append_step() yes = Node.from_ptr(parse_simple_expression("TRUE")) no = Node.from_ptr(parse_simple_expression("FALSE")) v = be_fsm.encoding.by_name["v"].name step1 += (v, yes) step2 += (v, no) trace.freeze() step1.force_loopback() self.assertTrue(step1.is_loopback) self.assertFalse(step2.is_loopback) step2.force_loopback() self.assertTrue(step1.is_loopback) # last step is never a loopback self.assertFalse(step2.is_loopback) trace.thaw() self.assertFalse(step1.is_loopback) self.assertFalse(step2.is_loopback)
def test_concat(self): with BmcSupport(): sexp_fsm = master_bool_sexp_fsm() be_fsm = master_be_fsm() trace = Trace.create( "Dummy example", TraceType.COUNTER_EXAMPLE, sexp_fsm.symbol_table, sexp_fsm.symbols_list, is_volatile=True, ) spec = Node.from_ptr(parse_ltl_spec("F (w <-> v)")) bound = 2 problem = generate_ltl_problem(be_fsm, spec, bound=bound) # .inline(True) cnf = problem.to_cnf() solver = SatSolverFactory.create() solver += cnf solver.polarity(cnf, Polarity.POSITIVE) solver.solve() other = generate_counter_example(be_fsm, problem, solver, bound) trace.concat(other) self.assertEquals(-1, trace.id) self.assertFalse(trace.is_registered) self.assertEquals("Dummy example", trace.description) self.assertEquals(TraceType.COUNTER_EXAMPLE, trace.type) self.assertTrue(trace.is_volatile) self.assertEquals(2, trace.length) self.assertEquals(2, len(trace)) self.assertFalse(trace.is_empty) self.assertFalse(trace.is_frozen) self.assertTrue(trace.is_thawed)
def test_assign_value__magicmethod__(self): """tests the behavior of assign and value""" with BmcSupport(): sexp_fsm = master_bool_sexp_fsm() be_fsm = master_be_fsm() # empty trace trace = Trace.create("Dummy example", TraceType.COUNTER_EXAMPLE, sexp_fsm.symbol_table, sexp_fsm.symbols_list, is_volatile=True) step1 = trace.steps[1] yes = Node.from_ptr(parse_simple_expression("TRUE")) no = Node.from_ptr(parse_simple_expression("FALSE")) v = be_fsm.encoding.by_name['v'].name self.assertIsNone(step1.value[v]) step1 += (v, yes) self.assertEqual(yes, step1.value[v]) step1 += (v, no) self.assertEqual(no, step1.value[v])
def test_create(self): # This function may not provoke any segfault (even though) freeit is # manually set to True when creating a trace. # besides that, the trace must be thawed, empty and have length 0 with BmcSupport(): sexp_fsm = master_bool_sexp_fsm() trace = Trace.create( "Dummy example", TraceType.COUNTER_EXAMPLE, sexp_fsm.symbol_table, sexp_fsm.symbols_list, is_volatile=True, ) self.assertEquals(-1, trace.id) self.assertFalse(trace.is_registered) self.assertEquals("Dummy example", trace.description) self.assertEquals(TraceType.COUNTER_EXAMPLE, trace.type) self.assertEquals(0, trace.length) self.assertTrue(trace.is_empty) self.assertTrue(trace.is_volatile) self.assertFalse(trace.is_frozen) self.assertTrue(trace.is_thawed) self.assertEquals(list(trace.symbols), list(sexp_fsm.symbols_list))
def test_is_complete(self): with BmcSupport(): sexp_fsm = master_bool_sexp_fsm() be_fsm = master_be_fsm() trace = Trace.create( "Dummy example", TraceType.COUNTER_EXAMPLE, sexp_fsm.symbol_table, sexp_fsm.symbols_list, is_volatile=True, ) # vacuously true self.assertTrue(trace.is_complete(NodeList.from_list([]))) v = be_fsm.encoding.by_name["v"].name self.assertFalse(trace.is_complete(NodeList.from_list([v]))) step = trace.steps[1] yes = Node.from_ptr(parse_simple_expression("TRUE")) step += (v, yes) self.assertTrue(trace.is_complete(NodeList.from_list([v])))
def setUp(self): init_nusmv() glob.load_from_file(tests.current_directory(__file__)+"/models/dummy_define_justice.smv") bmcGlob.go_bmc() self.fsm = glob.master_bool_sexp_fsm()