def test_apply_inlining_for_incremental_algo(self): load_from_string(""" MODULE main VAR v : boolean; ASSIGN init(v) := TRUE; next(v) := !v; """) with BmcSupport(): mdl = bmcutils.BmcModel() enc = mdl._fsm.encoding v = enc.by_name['v'].boolean_expression cond = v & v & v | v self.assertEqual( cond.inline(True), bmcutils.apply_inlining_for_incremental_algo(cond)) cond = v | -v self.assertEqual( cond.inline(True), bmcutils.apply_inlining_for_incremental_algo(cond)) cond = v & -v self.assertEqual( cond.inline(True), bmcutils.apply_inlining_for_incremental_algo(cond))
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_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_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 process(path_to, model, formula=None, depths=range(10), flags=IDLE): ''' Initializes PyNuSMV and loads the model, then proceeds to the bulk of the analysis. See `analyze_one` and `analyze_all` for further details about what is done. By default, this analysis generates no output. However the following flags can be customized to generate derived artifacts. + 'dimacs = True' will produce a *.cnf file containing the dimacs representation of the problem + 'structure = True' will produce a *.png file visually representing the variable graph. + 'clouds = True' will produce a wordcloud (*.png file) per analyzed community to show the semantic information that occurs the most often in that community. + 'stats = True' will produce a csv file containing all the raw statistical data alongside with two charts plotting the evolution of the #communities and modulatity over time ''' with init_nusmv(): load(core.merge_model_text(path_to, model + ".smv")) with BmcSupport(): analyze_all(model, formula, depths, flags)
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_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_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_make_nnf_boolean_wff(self): load_from_string(""" MODULE main VAR v : boolean; w : boolean; ASSIGN init(v) := TRUE; next(v) := !v; """) with BmcSupport(): expr = Node.from_ptr(parse_ltl_spec("F G ( w <-> v )")) wff = bmcutils.make_nnf_boolean_wff(expr) self.assertEquals(" F ( G (w <-> v))", str(expr)) self.assertEquals(" F ( G ((!v | w) & (v | !w)))", str(wff)) self.assertEquals(Wff, type(wff))
def test_make_negated_nnf_boolean_wff(self): load_from_string(""" MODULE main VAR v : boolean; w : boolean; ASSIGN init(v) := TRUE; next(v) := !v; """) with BmcSupport(): expr = Node.from_ptr(parse_ltl_spec("F G ( w <-> v )")) wff = bmcutils.make_negated_nnf_boolean_wff(expr) self.assertEquals(" F ( G (w <-> v))", str(expr)) # Via De Morgan Laws self.assertEquals(" G ( F ((v & !w) | (!v & w)))", str(wff))
def test_dump_problem(self): load_from_string(""" MODULE main VAR v : boolean; w : boolean; ASSIGN init(v) := TRUE; next(v) := !v; LTLSPEC F G ( w <-> v ) """) with BmcSupport(): fsm = master_be_fsm() for prop in prop_database(): pb = generate_ltl_problem(fsm, prop.expr) bmcutils.dump_problem(fsm.encoding, pb.to_cnf(), prop, 10, 0, bmcutils.DumpType.DIMACS, "dimacs_dump")
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 main(): args = arguments() with init_nusmv(): load(args.model) if args.verbose: with open(args.model) as f: print(f.read()) with BmcSupport(): if args.spec is not None: check(args.spec, args) else: print("Enter LTL properties, one per line:") for line in sys.stdin: check(line, args)
def test_booleanize(self): load_from_string(""" MODULE main VAR -- requires two bits i : 0..3; -- requires no transformation b : boolean; """) with BmcSupport(): # fails for non existing symbols with self.assertRaises(ValueError): bmcutils.booleanize("c") # works as expected for existing vars self.assertEqual("[i.1, i.0]", str(bmcutils.booleanize("i"))) self.assertEqual("[b]", str(bmcutils.booleanize("b")))
def test_get_symbol(self): load_from_string(""" MODULE main VAR w : boolean; IVAR x : boolean; FROZENVAR y : boolean; DEFINE z := (x & w); """) with BmcSupport(): # fails when not found with self.assertRaises(ValueError): bmcutils.get_symbol("a") # works for all types of vars self.assertEqual("w", str(bmcutils.get_symbol("w"))) self.assertEqual("x", str(bmcutils.get_symbol("x"))) self.assertEqual("y", str(bmcutils.get_symbol("y"))) self.assertEqual("z", str(bmcutils.get_symbol("z")))
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_loop_condition_single_var(self): # test case 1: model with one single var load_from_string(""" MODULE main VAR v : boolean; ASSIGN init(v) := TRUE; next(v) := !v; """) with BmcSupport(): mdl = bmcutils.BmcModel() enc = mdl._fsm.encoding cond = bmcutils.loop_condition(enc, 3, 1) v3 = enc.by_name['v'].at_time[3].boolean_expression v1 = enc.by_name['v'].at_time[1].boolean_expression cond2 = v1.iff(v3) self.assertEqual(cond, cond2)
def test_loop_condition_consistent_values(self): # test case 3: only the state variables are considered load_from_string(""" MODULE main IVAR i : boolean; VAR v : boolean; w : boolean; ASSIGN init(v) := TRUE; next(v) := !v; """) with BmcSupport(): mdl = bmcutils.BmcModel() enc = mdl._fsm.encoding # loop and bound must be consistent (bound >= 0) with self.assertRaises(ValueError): bmcutils.loop_condition(enc, -5, 1) # loop and bound must be consistent (loop <= bound) with self.assertRaises(ValueError): bmcutils.loop_condition(enc, 2, 5)
def test_apply_inlining(self): load_from_string(""" MODULE main VAR v : boolean; ASSIGN init(v) := TRUE; next(v) := !v; """) with BmcSupport(): mdl = bmcutils.BmcModel() enc = mdl._fsm.encoding mgr = enc.manager v = enc.by_name['v'].boolean_expression cond = v & v & v | v self.assertEqual(v, bmcutils.apply_inlining(cond)) cond = v | -v self.assertEqual(Be.true(mgr), bmcutils.apply_inlining(cond)) cond = v & -v self.assertEqual(Be.false(mgr), bmcutils.apply_inlining(cond))
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 proceed(args): """Actually proceeds to the verification""" with init_nusmv(): load(args.model) with BmcSupport(): observable = mk_observable_names(args) if not args.quiet: with open(args.model) as m: model = m.read() print_greeting(model, observable) if args.spec is not None: check(args, args.spec, observable) else: print("*"*80) print("* DIAGNOSABILITY TESTS") print("*"*80) print("Enter diagnosability condition, one per line in the format: 'c1 ; c2'") for line in sys.stdin: check(args, line, observable)
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 test_loop_condition_two_var(self): # test case 1: model with one more variables load_from_string(""" MODULE main VAR v : boolean; w : boolean; ASSIGN init(v) := TRUE; next(v) := !v; """) with BmcSupport(): mdl = bmcutils.BmcModel() enc = mdl._fsm.encoding cond = bmcutils.loop_condition(enc, 3, 1) v = enc.by_name['v'] w = enc.by_name['w'] cond2 = (v.at_time[1].boolean_expression.iff( v.at_time[3].boolean_expression) & w.at_time[1].boolean_expression.iff( w.at_time[3].boolean_expression)) self.assertEqual(cond, cond2)
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_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_loop_condition_not_only_state(self): # test case 3: only the state variables are considered load_from_string(""" MODULE main IVAR i : boolean; VAR v : boolean; w : boolean; ASSIGN init(v) := TRUE; next(v) := !v; """) with BmcSupport(): mdl = bmcutils.BmcModel() enc = mdl._fsm.encoding cond = bmcutils.loop_condition(enc, 3, 1) v = enc.by_name['v'] w = enc.by_name['w'] cond2 = (v.at_time[1].boolean_expression.iff( v.at_time[3].boolean_expression) & w.at_time[1].boolean_expression.iff( w.at_time[3].boolean_expression)) self.assertEqual(cond, cond2)