def test_generate_problem_with_fairness(self): ''' This test clearly shows the difference in validating a property with or without fairness constraint ''' with tests.Configure(self, __file__, "/philo.smv"): # length 0 # nusmv has fairness always on. fml_node= Node.from_ptr(parse_ltl_spec("G (p1.waiting -> F !p1.waiting)")) smv = ltlspec.generate_ltl_problem(self.befsm, fml_node, 0) self.assertEqual(SatSolverResult.UNSATISFIABLE, self.satisfiability(smv)) formula = parseLTL("[](p1.waiting => <>!p1.waiting)") unfair = gen.generate_problem(formula, self.befsm, 0, no_fairness=True) self.assertEqual(SatSolverResult.UNSATISFIABLE, self.satisfiability(unfair)) fair = gen.generate_problem(formula, self.befsm, 0, no_fairness=False) self.assertEqual(SatSolverResult.UNSATISFIABLE, self.satisfiability(fair)) # length 1 fml_node= Node.from_ptr(parse_ltl_spec("G (p1.waiting -> F !p1.waiting)")) smv = ltlspec.generate_ltl_problem(self.befsm, fml_node, 1) self.assertEqual(SatSolverResult.UNSATISFIABLE, self.satisfiability(smv)) formula = parseLTL("[](p1.waiting => <>!p1.waiting)") unfair = gen.generate_problem(formula, self.befsm, 1, no_fairness=True) self.assertEqual(SatSolverResult.SATISFIABLE, self.satisfiability(unfair)) fair = gen.generate_problem(formula, self.befsm, 1, no_fairness=False) self.assertEqual(SatSolverResult.UNSATISFIABLE, self.satisfiability(fair))
def test_constraint_context_sigma(self): fsm = master_be_fsm() _true = Node.from_ptr(parse_ltl_spec("TRUE")) _true = bmcutils.make_nnf_boolean_wff(_true) _truen= _true.to_node() cond = Wff(parse_ltl_spec("G !(mouse = hover)"))\ .to_boolean_wff()\ .to_negation_normal_form() off_1 = 0 off_2 = 2 length= 1 # sigma1 problem = diagnosability.generate_sat_problem([], (_truen, _truen), length, _true, cond.to_node(), _truen) tm_cond = ltlspec.bounded_semantics_at_offset(fsm, cond.to_node(), length, off_1) canonical_p = tests.canonical_cnf(problem) canonical_f = tests.canonical_cnf(tm_cond) self.assertTrue(all(clause in canonical_p for clause in canonical_f)) # sigma2 problem = diagnosability.generate_sat_problem([], (_truen, _truen), length, _true, _truen, cond.to_node()) tm_cond = ltlspec.bounded_semantics_at_offset(fsm, cond.to_node(), length, off_2) canonical_p = tests.canonical_cnf(problem) canonical_f = tests.canonical_cnf(tm_cond) self.assertTrue(all(clause in canonical_p for clause in canonical_f))
def test_bounded_semantics_without_loop(self): # parse the ltl property spec = Node.from_ptr(parse_ltl_spec("G ( y <= 7 )")) # it must raise exception when the bound is not feasible with self.assertRaises(ValueError): ltlspec.bounded_semantics_without_loop(self.fsm, spec, bound=-1) # verify that the generated expression corresponds to what is announced no_loop = ltlspec.bounded_semantics_without_loop(self.fsm, spec, 10) # globally w/o loop is false (this is just a test) self.assertEqual(no_loop, Be.false(self.fsm.encoding.manager)) # an other more complex generation spec = Node.from_ptr(parse_ltl_spec("F (y <= 7)")) no_loop = ltlspec.bounded_semantics_without_loop(self.fsm, spec, 10) # # The generated expression is [[f]]^{0}_{k} so (! L_{k}) is not taken # care of. And actually, NuSMV does not generate that part of the # formula: it only enforce the loop condition when the semantics with # loop is used # handcrafted = Be.false(self.fsm.encoding.manager) y_le_seven = Wff(parse_ltl_spec("y <= 7")).to_boolean_wff().to_be(self.fsm.encoding) for time_x in reversed(range(11)): # 11 because range 'eats' up the last step handcrafted |= self.fsm.encoding.shift_to_time(y_le_seven, time_x) #### debuging info ##### #print("noloop = {}".format(no_loop.to_cnf())) #print("hancraft= {}".format(handcrafted.to_cnf())) #print(self.fsm.encoding) self.assertEqual(no_loop, handcrafted)
def test_bounded_semantics_with_loop_optimized_depth1(self): spec = Node.from_ptr(parse_ltl_spec("G ( y <= 7 )")) # depth == 1 # it must raise exception when the bound is not feasible with self.assertRaises(ValueError): ltlspec.bounded_semantics_all_loops_optimisation_depth1( self.fsm, spec, -1) # should yield the same result (w/ opt) as regular all loops when depth is one optimized = ltlspec.bounded_semantics_all_loops_optimisation_depth1( self.fsm, spec, 5) regular = ltlspec.bounded_semantics_all_loops(self.fsm, spec, bound=5, loop=0) self.assertEqual(regular, optimized) # but not when the optim is turned off on 'all loops' regular = ltlspec.bounded_semantics_all_loops(self.fsm, spec, bound=5, loop=0, optimized=False) self.assertNotEqual(regular, optimized) # and it should only be applied when the depth is equal to one spec = Node.from_ptr(parse_ltl_spec("F G ( y <= 7 )")) # depth == 2 self.assertEqual(2, Wff.decorate(spec).depth) optimized = ltlspec.bounded_semantics_all_loops_optimisation_depth1( self.fsm, spec, 5) regular = ltlspec.bounded_semantics_all_loops(self.fsm, spec, bound=5, loop=0) self.assertNotEqual(regular, optimized)
def test_next_with_loop(self): with tests.Configure(self, __file__, "/example.smv"): i, k, l = 0, 2, 0 enc = self.enc # One step a = ast.Proposition("a") formula = ast.Next(a) tool = formula.semantic_with_loop(enc, i, k, l) manual = a.semantic_with_loop(enc, 1, k, l) nusmv = ltlspec.bounded_semantics(self.befsm, Node.from_ptr( parse_ltl_spec("X a")), bound=k, loop=l) loop_cond = bmcutils.loop_condition(enc, k, l) s_tool = tests.canonical_cnf(tool & loop_cond) s_manual = tests.canonical_cnf(manual & loop_cond) s_nusmv = tests.canonical_cnf(nusmv) self.assertEqual(s_tool, s_nusmv) self.assertEqual(s_tool, s_manual) # two steps formula = ast.Next(ast.Next(a)) tool = formula.semantic_with_loop(enc, i, k, l) manual = a.semantic_with_loop(enc, 0, k, l) nusmv = ltlspec.bounded_semantics(self.befsm, Node.from_ptr( parse_ltl_spec("X X a")), bound=k, loop=l) loop_cond = bmcutils.loop_condition(enc, k, l) s_tool = tests.canonical_cnf(tool & loop_cond) s_manual = tests.canonical_cnf(manual & loop_cond) s_nusmv = tests.canonical_cnf(nusmv) self.assertEqual(s_tool, s_nusmv) self.assertEqual(s_tool, s_manual) # Three steps (getting over k) formula = ast.Next(ast.Next(ast.Next(a))) tool = formula.semantic_with_loop(enc, i, k, l) manual = a.semantic_with_loop(enc, 1, k, l) nusmv = ltlspec.bounded_semantics(self.befsm, Node.from_ptr( parse_ltl_spec("X X X a")), bound=k, loop=l) loop_cond = bmcutils.loop_condition(enc, k, l) s_tool = tests.canonical_cnf(tool & loop_cond) s_manual = tests.canonical_cnf(manual & loop_cond) s_nusmv = tests.canonical_cnf(nusmv) self.assertEqual(s_tool, s_nusmv) self.assertEqual(s_tool, s_manual)
def test_next_with_loop(self): with tests.Configure(self, __file__, "/example.smv"): i,k,l = 0,2,0 enc = self.enc # One step a = ast.Proposition("a") formula = ast.Next(a) tool = formula.semantic_with_loop(enc, i, k, l) manual = a.semantic_with_loop(enc, 1, k, l) nusmv = ltlspec.bounded_semantics(self.befsm, Node.from_ptr(parse_ltl_spec("X a")), bound = k, loop = l) loop_cond = bmcutils.loop_condition(enc, k, l) s_tool = tests.canonical_cnf(tool & loop_cond) s_manual= tests.canonical_cnf(manual & loop_cond) s_nusmv = tests.canonical_cnf(nusmv) self.assertEqual(s_tool, s_nusmv) self.assertEqual(s_tool, s_manual) # two steps formula = ast.Next(ast.Next(a)) tool = formula.semantic_with_loop(enc, i, k, l) manual = a.semantic_with_loop(enc, 0, k, l) nusmv = ltlspec.bounded_semantics(self.befsm, Node.from_ptr(parse_ltl_spec("X X a")), bound = k, loop = l) loop_cond = bmcutils.loop_condition(enc, k, l) s_tool = tests.canonical_cnf(tool & loop_cond) s_manual= tests.canonical_cnf(manual & loop_cond) s_nusmv = tests.canonical_cnf(nusmv) self.assertEqual(s_tool, s_nusmv) self.assertEqual(s_tool, s_manual) # Three steps (getting over k) formula = ast.Next(ast.Next(ast.Next(a))) tool = formula.semantic_with_loop(enc, i, k, l) manual = a.semantic_with_loop(enc, 1, k, l) nusmv = ltlspec.bounded_semantics(self.befsm, Node.from_ptr(parse_ltl_spec("X X X a")), bound = k, loop = l) loop_cond = bmcutils.loop_condition(enc, k, l) s_tool = tests.canonical_cnf(tool & loop_cond) s_manual= tests.canonical_cnf(manual & loop_cond) s_nusmv = tests.canonical_cnf(nusmv) self.assertEqual(s_tool, s_nusmv) self.assertEqual(s_tool, s_manual)
def test_next_noloop(self): with tests.Configure(self, __file__, "/example.smv"): i, k = 0, 2 enc = self.enc # One step a = ast.Proposition("a") formula = ast.Next(a) tool = formula.semantic_no_loop(enc, i, k) manual = a.semantic_no_loop(enc, 1, k) nusmv = ltlspec.bounded_semantics(self.befsm, Node.from_ptr( parse_ltl_spec("X a")), bound=k, loop=bmcutils.no_loopback()) s_tool = tests.canonical_cnf(tool) s_manual = tests.canonical_cnf(manual) s_nusmv = tests.canonical_cnf(nusmv) self.assertEqual(s_tool, s_nusmv) self.assertEqual(s_tool, s_manual) # two steps formula = ast.Next(ast.Next(a)) tool = formula.semantic_no_loop(enc, i, k) manual = a.semantic_no_loop(enc, 2, k) nusmv = ltlspec.bounded_semantics(self.befsm, Node.from_ptr( parse_ltl_spec("X X a")), bound=k, loop=bmcutils.no_loopback()) s_tool = tests.canonical_cnf(tool) s_manual = tests.canonical_cnf(manual) s_nusmv = tests.canonical_cnf(nusmv) self.assertEqual(s_tool, s_nusmv) self.assertEqual(s_tool, s_manual) # Three steps (getting over k) formula = ast.Next(ast.Next(ast.Next(a))) tool = formula.semantic_no_loop(enc, i, k) manual = Be.false(enc.manager) nusmv = ltlspec.bounded_semantics(self.befsm, Node.from_ptr( parse_ltl_spec("X X X a")), bound=k, loop=bmcutils.no_loopback()) s_tool = tests.canonical_cnf(tool) s_manual = tests.canonical_cnf(manual) s_nusmv = tests.canonical_cnf(nusmv) self.assertEqual(s_tool, s_nusmv) self.assertEqual(s_tool, s_manual)
def test_is_constant_expr(self): expr = Node.from_ptr(parse_ltl_spec("F G ( w <-> v )")) self.assertFalse(bmcutils.is_constant_expr(expr)) expr = Node.from_ptr(parse_ltl_spec("some_variable")) self.assertFalse(bmcutils.is_constant_expr(expr)) expr = Node.from_ptr(parse_ltl_spec("TRUE")) self.assertTrue(bmcutils.is_constant_expr(expr)) expr = Node.from_ptr(parse_ltl_spec("FALSE")) self.assertTrue(bmcutils.is_constant_expr(expr))
def test_next_noloop(self): with tests.Configure(self, __file__, "/example.smv"): i,k = 0,2 enc = self.enc # One step a = ast.Proposition("a") formula = ast.Next(a) tool = formula.semantic_no_loop(enc, i, k) manual = a.semantic_no_loop(enc, 1, k) nusmv = ltlspec.bounded_semantics(self.befsm, Node.from_ptr(parse_ltl_spec("X a")), bound = k, loop = bmcutils.no_loopback()) s_tool = tests.canonical_cnf(tool) s_manual = tests.canonical_cnf(manual) s_nusmv = tests.canonical_cnf(nusmv) self.assertEqual(s_tool, s_nusmv) self.assertEqual(s_tool, s_manual) # two steps formula = ast.Next(ast.Next(a)) tool = formula.semantic_no_loop(enc, i, k) manual = a.semantic_no_loop(enc, 2, k) nusmv = ltlspec.bounded_semantics(self.befsm, Node.from_ptr(parse_ltl_spec("X X a")), bound = k, loop = bmcutils.no_loopback()) s_tool = tests.canonical_cnf(tool) s_manual = tests.canonical_cnf(manual) s_nusmv = tests.canonical_cnf(nusmv) self.assertEqual(s_tool, s_nusmv) self.assertEqual(s_tool, s_manual) # Three steps (getting over k) formula = ast.Next(ast.Next(ast.Next(a))) tool = formula.semantic_no_loop(enc, i, k) manual = Be.false(enc.manager) nusmv = ltlspec.bounded_semantics(self.befsm, Node.from_ptr(parse_ltl_spec("X X X a")), bound = k, loop = bmcutils.no_loopback()) s_tool = tests.canonical_cnf(tool) s_manual = tests.canonical_cnf(manual) s_nusmv = tests.canonical_cnf(nusmv) self.assertEqual(s_tool, s_nusmv) self.assertEqual(s_tool, s_manual)
def test_is_variable(self): expr = Node.from_ptr(parse_ltl_spec("F G ( w <-> v )")) self.assertFalse(bmcutils.is_variable(expr)) expr = Node.from_ptr(parse_ltl_spec("some_variable")) expr.type = _parser.DOT # just to make sure it is seen as a variable, not an atom self.assertTrue(bmcutils.is_variable(expr)) expr = Node.from_ptr(parse_ltl_spec("TRUE")) self.assertFalse(bmcutils.is_variable(expr)) expr = Node.from_ptr(parse_ltl_spec("FALSE")) self.assertFalse(bmcutils.is_variable(expr))
def test_generate_problem_with_fairness(self): ''' This test clearly shows the difference in validating a property with or without fairness constraint ''' with tests.Configure(self, __file__, "/philo.smv"): # length 0 # nusmv has fairness always on. fml_node = Node.from_ptr( parse_ltl_spec("G (p1.waiting -> F !p1.waiting)")) smv = ltlspec.generate_ltl_problem(self.befsm, fml_node, 0) self.assertEqual(SatSolverResult.UNSATISFIABLE, self.satisfiability(smv)) formula = parseLTL("[](p1.waiting => <>!p1.waiting)") unfair = gen.generate_problem(formula, self.befsm, 0, no_fairness=True) self.assertEqual(SatSolverResult.UNSATISFIABLE, self.satisfiability(unfair)) fair = gen.generate_problem(formula, self.befsm, 0, no_fairness=False) self.assertEqual(SatSolverResult.UNSATISFIABLE, self.satisfiability(fair)) # length 1 fml_node = Node.from_ptr( parse_ltl_spec("G (p1.waiting -> F !p1.waiting)")) smv = ltlspec.generate_ltl_problem(self.befsm, fml_node, 1) self.assertEqual(SatSolverResult.UNSATISFIABLE, self.satisfiability(smv)) formula = parseLTL("[](p1.waiting => <>!p1.waiting)") unfair = gen.generate_problem(formula, self.befsm, 1, no_fairness=True) self.assertEqual(SatSolverResult.SATISFIABLE, self.satisfiability(unfair)) fair = gen.generate_problem(formula, self.befsm, 1, no_fairness=False) self.assertEqual(SatSolverResult.UNSATISFIABLE, self.satisfiability(fair))
def validate_generate_problem(self, bound, custom_text, nusmv_text): fsm = self.befsm # formulae formula = parseLTL(custom_text) fml_node= Node.from_ptr(parse_ltl_spec(nusmv_text)) # IMPORTANT NOTE: each instantiation of the problem creates new CNF # literal which appears in the clauses list (even in canonical form) # hence, the canonical forms of the different instantiations cannot # simply be compared as there is no a priori way to know what CNF # literal reconcile with what other. # However, the different expressions should all have the exact same # satisfiability. So, that's how this test proceeds. smv = ltlspec.generate_ltl_problem(fsm, fml_node, bound) tool = gen.generate_problem(formula, fsm, bound) manual = gen.model_problem(fsm, bound) &\ formula.nnf(True).bounded_semantics(fsm, bound) sat_smv = self.satisfiability(smv) sat_tool= self.satisfiability(tool) sat_man = self.satisfiability(manual) self.assertEqual(sat_tool, sat_man) self.assertEqual(sat_tool, sat_smv)
def test_generate_sat_problem(self): theta = Node.from_ptr(parse_simple_expression("TRUE")) theta = bmcutils.make_nnf_boolean_wff(theta) sigma_12= Node.from_ptr(parse_ltl_spec("TRUE")) sigma_12= bmcutils.make_nnf_boolean_wff(sigma_12).to_node() observable = diagnosability.mk_observable_vars(["mouse"]) f1 = Node.from_ptr(parse_simple_expression("status = active")) f2 = Node.from_ptr(parse_simple_expression("status = inactive")) for i in range(5): problem = diagnosability.generate_sat_problem(observable, (f1, f2), i, theta, sigma_12, sigma_12) solver = SatSolverFactory.create() cnf = problem.to_cnf() solver += cnf solver.polarity(cnf, Polarity.POSITIVE) self.assertEqual(SatSolverResult.UNSATISFIABLE, solver.solve()) f1 = Node.from_ptr(parse_simple_expression("status = active")) f2 = Node.from_ptr(parse_simple_expression("status = highlight")) for i in range(1, 4): # length zero has no input => only an initial state and the # diagnosability condition is not checked problem = diagnosability.generate_sat_problem(observable, (f1, f2), i, theta, sigma_12, sigma_12) solver = SatSolverFactory.create() cnf = problem.to_cnf() solver += cnf solver.polarity(cnf, Polarity.POSITIVE) self.assertEqual(SatSolverResult.SATISFIABLE, solver.solve())
def test_until_with_loop(self): with tests.Configure(self, __file__, "/example.smv"): enc = self.enc i, k, l = 0, 2, 0 a = ast.Proposition("a") b = ast.Proposition("b") expr = ast.Until(a, b) tool = expr.semantic_with_loop(enc, i, k, l) manual = b.semantic_with_loop(enc, i, k, l) | \ (a.semantic_with_loop(enc, i, k, l) & b.semantic_with_loop(enc, i+1, k, l)) spec = Node.from_ptr(parse_ltl_spec("a U b")) nusmv = ltlspec.bounded_semantics(self.befsm, spec, bound=k, loop=l) tool &= bmcutils.loop_condition(enc, k, l) manual &= bmcutils.loop_condition(enc, k, l) # normalized string representation of the BE's (make them comparable) s_tool = tests.canonical_cnf(tool) s_nusmv = tests.canonical_cnf(nusmv) s_manual = tests.canonical_cnf(manual) self.assertEqual(s_tool, s_manual) self.assertEqual(s_tool, s_nusmv)
def test_eventually_with_loop(self): with tests.Configure(self, __file__, "/example.smv"): i,k,l = 0,2,0 enc = self.enc a = ast.Proposition("a") formula = ast.Eventually(a) tool = formula.semantic_with_loop(enc, i, k, l) manual = a.semantic_with_loop(enc, i+1, k, l) |\ a.semantic_with_loop(enc, i , k, l) nusmv = ltlspec.bounded_semantics( self.befsm, Node.from_ptr(parse_ltl_spec("F a")), bound = k, loop = l) # normalized string representation of the BE's (make them comparable) loop_cond = bmcutils.loop_condition(enc, k, l) s_tool = tests.canonical_cnf(tool & loop_cond) s_manual= tests.canonical_cnf(manual & loop_cond) s_nusmv = tests.canonical_cnf(nusmv) self.assertEqual(s_nusmv, s_tool) self.assertEqual(s_manual, s_tool)
def test_verify_exactly(self): theta = Node.from_ptr(parse_simple_expression("TRUE")) theta = bmcutils.make_nnf_boolean_wff(theta) sigma_12= Node.from_ptr(parse_ltl_spec("TRUE")) sigma_12= bmcutils.make_nnf_boolean_wff(sigma_12).to_node() obs_names = ["mouse"] obs_vars = diagnosability.mk_observable_vars(obs_names) f1 = Node.from_ptr(parse_simple_expression("status = active")) f2 = Node.from_ptr(parse_simple_expression("status = inactive")) for i in range(5): res = diagnosability.verify_for_size_exactly_k(obs_names, obs_vars, (f1, f2), i, theta, sigma_12, sigma_12) self.assertEqual("No Violation", res) f1 = Node.from_ptr(parse_simple_expression("status = active")) f2 = Node.from_ptr(parse_simple_expression("status = highlight")) res = diagnosability.verify_for_size_exactly_k(obs_names, obs_vars, (f1, f2), 0, theta, sigma_12, sigma_12) self.assertEqual("No Violation", res) res = diagnosability.verify_for_size_exactly_k(obs_names, obs_vars, (f1, f2), 1, theta, sigma_12, sigma_12) self.assertTrue(res.startswith("############### DIAGNOSABILITY VIOLATION")) res = diagnosability.verify_for_size_exactly_k(obs_names, obs_vars, (f1, f2), 2, theta, sigma_12, sigma_12) self.assertTrue(res.startswith("############### DIAGNOSABILITY VIOLATION")) res = diagnosability.verify_for_size_exactly_k(obs_names, obs_vars, (f1, f2), 3, theta, sigma_12, sigma_12) self.assertTrue(res.startswith("############### DIAGNOSABILITY VIOLATION"))
def test_until_with_loop(self): with tests.Configure(self, __file__, "/example.smv"): enc = self.enc i,k,l= 0,2,0 a = ast.Proposition("a") b = ast.Proposition("b") expr = ast.Until(a, b) tool = expr.semantic_with_loop(enc, i,k,l) manual = b.semantic_with_loop(enc, i, k, l) | \ (a.semantic_with_loop(enc, i, k, l) & b.semantic_with_loop(enc, i+1, k, l)) spec = Node.from_ptr(parse_ltl_spec("a U b")) nusmv = ltlspec.bounded_semantics(self.befsm, spec, bound=k, loop=l) tool &= bmcutils.loop_condition(enc, k, l) manual &= bmcutils.loop_condition(enc, k, l) # normalized string representation of the BE's (make them comparable) s_tool = tests.canonical_cnf(tool) s_nusmv = tests.canonical_cnf(nusmv) s_manual= tests.canonical_cnf(manual) self.assertEqual(s_tool, s_manual) self.assertEqual(s_tool, s_nusmv)
def test_weak_until_noloop(self): with tests.Configure(self, __file__, "/example.smv"): enc = self.enc a = ast.Proposition("a") b = ast.Proposition("b") expr = ast.WeakUntil(a, b) tool = expr.semantic_no_loop(enc, 0, 2) manual = (b.semantic_no_loop(enc, 0, 2) | (a.semantic_no_loop(enc, 0, 2) & (b.semantic_no_loop(enc, 1, 2) | (a.semantic_no_loop(enc, 1, 2) & (b.semantic_no_loop(enc, 2, 2)))))) spec = Node.from_ptr(parse_ltl_spec("a U b")) nusmv = ltlspec.bounded_semantics(self.befsm, spec, bound=2, loop=bmcutils.no_loopback()) # normalized string representation of the BE's (make them comparable) s_tool = tests.canonical_cnf(tool) s_nusmv = tests.canonical_cnf(nusmv) s_manual = tests.canonical_cnf(manual) self.assertEqual(s_tool, s_manual) self.assertEqual(s_tool, s_nusmv)
def test_eventually_with_loop(self): with tests.Configure(self, __file__, "/example.smv"): i, k, l = 0, 2, 0 enc = self.enc a = ast.Proposition("a") formula = ast.Eventually(a) tool = formula.semantic_with_loop(enc, i, k, l) manual = a.semantic_with_loop(enc, i+1, k, l) |\ a.semantic_with_loop(enc, i , k, l) nusmv = ltlspec.bounded_semantics(self.befsm, Node.from_ptr( parse_ltl_spec("F a")), bound=k, loop=l) # normalized string representation of the BE's (make them comparable) loop_cond = bmcutils.loop_condition(enc, k, l) s_tool = tests.canonical_cnf(tool & loop_cond) s_manual = tests.canonical_cnf(manual & loop_cond) s_nusmv = tests.canonical_cnf(nusmv) self.assertEqual(s_nusmv, s_tool) self.assertEqual(s_manual, s_tool)
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 validate_generate_problem(self, bound, custom_text, nusmv_text): fsm = self.befsm # formulae formula = parseLTL(custom_text) fml_node = Node.from_ptr(parse_ltl_spec(nusmv_text)) # IMPORTANT NOTE: each instantiation of the problem creates new CNF # literal which appears in the clauses list (even in canonical form) # hence, the canonical forms of the different instantiations cannot # simply be compared as there is no a priori way to know what CNF # literal reconcile with what other. # However, the different expressions should all have the exact same # satisfiability. So, that's how this test proceeds. smv = ltlspec.generate_ltl_problem(fsm, fml_node, bound) tool = gen.generate_problem(formula, fsm, bound) manual = gen.model_problem(fsm, bound) &\ formula.nnf(True).bounded_semantics(fsm, bound) sat_smv = self.satisfiability(smv) sat_tool = self.satisfiability(tool) sat_man = self.satisfiability(manual) self.assertEqual(sat_tool, sat_man) self.assertEqual(sat_tool, sat_smv)
def test_generate_sat_problem(self): theta = Node.from_ptr(parse_simple_expression("TRUE")) theta = bmcutils.make_nnf_boolean_wff(theta) sigma_12 = Node.from_ptr(parse_ltl_spec("TRUE")) sigma_12 = bmcutils.make_nnf_boolean_wff(sigma_12).to_node() observable = diagnosability.mk_observable_vars(["mouse"]) f1 = Node.from_ptr(parse_simple_expression("status = active")) f2 = Node.from_ptr(parse_simple_expression("status = inactive")) for i in range(5): problem = diagnosability.generate_sat_problem( observable, (f1, f2), i, theta, sigma_12, sigma_12) solver = SatSolverFactory.create() cnf = problem.to_cnf() solver += cnf solver.polarity(cnf, Polarity.POSITIVE) self.assertEqual(SatSolverResult.UNSATISFIABLE, solver.solve()) f1 = Node.from_ptr(parse_simple_expression("status = active")) f2 = Node.from_ptr(parse_simple_expression("status = highlight")) for i in range(1, 4): # length zero has no input => only an initial state and the # diagnosability condition is not checked problem = diagnosability.generate_sat_problem( observable, (f1, f2), i, theta, sigma_12, sigma_12) solver = SatSolverFactory.create() cnf = problem.to_cnf() solver += cnf solver.polarity(cnf, Polarity.POSITIVE) self.assertEqual(SatSolverResult.SATISFIABLE, solver.solve())
def test_bounded_semantics_with_loop(self): # parse the ltl property spec = Node.from_ptr(parse_ltl_spec("G ( y <= 7 )")) # it must raise exception when the bound is not feasible with self.assertRaises(ValueError): ltlspec.bounded_semantics_single_loop(self.fsm, spec, -1, -2) # it must raise exception when the bound and loop are not consistent with self.assertRaises(ValueError): ltlspec.bounded_semantics_single_loop(self.fsm, spec, 5, 6) # verify that the generated problem corresponds to what is announced # without optimisation, the all loops is built as the conjunction of all # the possible 'single_loops' all_loops = ltlspec.bounded_semantics_all_loops(self.fsm, spec, 10, 0, optimized=False) acc_loops = Be.false(self.fsm.encoding.manager) for time_t in range(10): acc_loops |= ltlspec.bounded_semantics_single_loop( self.fsm, spec, 10, time_t) self.assertEqual(acc_loops, all_loops) # with optimisation, it's different all_loops = ltlspec.bounded_semantics_all_loops(self.fsm, spec, 10, 0, optimized=True) self.assertNotEqual(acc_loops, all_loops)
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_mc_ltl_true(self): # Initialize the model glob.load("tests/pynusmv/models/admin.smv") glob.compute_model() fsm = glob.prop_database().master.bddFsm spec = prop.Spec(parser.parse_ltl_spec("G admin = none")) self.assertEqual(mc.check_ltl_spec(spec), False)
def nnf(self, text): """ Utility function to convert text into an equivalent Node form in NNF :return: an NNF node version of the text """ return Wff(parse_ltl_spec(text)).to_boolean_wff()\ .to_negation_normal_form()\ .to_node()
def test_mc_explain_ltl_true(self): # Initialize the model glob.load("tests/pynusmv/models/admin.smv") glob.compute_model() spec = prop.Spec( parser.parse_ltl_spec("(F admin = alice) | (F admin = bob)")) result, explanation = mc.check_explain_ltl_spec(spec) self.assertTrue(result) self.assertIsNone(explanation)
def validate_bounded_semantics(self, bound, custom_text, nusmv_text): fsm = self.befsm # formulae formula = parseLTL(custom_text) fml_node = Node.from_ptr(parse_ltl_spec(nusmv_text)) tool = formula.bounded_semantics(fsm, bound) smv = ltlspec.bounded_semantics(fsm, fml_node, bound) # canonical forms s_tool = tests.canonical_cnf(tool) s_smv = tests.canonical_cnf(smv) self.assertEqual(s_tool, s_smv)
def test_bounded_semantics_with_loop_optimized_depth1(self): spec = Node.from_ptr(parse_ltl_spec("G ( y <= 7 )")) # depth == 1 # it must raise exception when the bound is not feasible with self.assertRaises(ValueError): ltlspec.bounded_semantics_all_loops_optimisation_depth1(self.fsm, spec, -1) # should yield the same result (w/ opt) as regular all loops when depth is one optimized = ltlspec.bounded_semantics_all_loops_optimisation_depth1(self.fsm, spec, 5) regular = ltlspec.bounded_semantics_all_loops(self.fsm, spec, bound=5, loop=0) self.assertEqual(regular, optimized) # but not when the optim is turned off on 'all loops' regular = ltlspec.bounded_semantics_all_loops(self.fsm, spec, bound=5, loop=0, optimized=False) self.assertNotEqual(regular, optimized) # and it should only be applied when the depth is equal to one spec = Node.from_ptr(parse_ltl_spec("F G ( y <= 7 )")) # depth == 2 self.assertEqual(2, Wff.decorate(spec).depth) optimized = ltlspec.bounded_semantics_all_loops_optimisation_depth1(self.fsm, spec, 5) regular = ltlspec.bounded_semantics_all_loops(self.fsm, spec, bound=5, loop=0) self.assertNotEqual(regular, optimized)
def validate_bounded_semantics(self, bound, custom_text, nusmv_text): fsm = self.befsm # formulae formula = parseLTL(custom_text) fml_node= Node.from_ptr(parse_ltl_spec(nusmv_text)) tool = formula.bounded_semantics(fsm, bound) smv = ltlspec.bounded_semantics(fsm, fml_node, bound) # canonical forms s_tool = tests.canonical_cnf(tool) s_smv = tests.canonical_cnf(smv) self.assertEqual(s_tool, s_smv)
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 mk_cnf_with_formula(formula, bound): ''' :return: a `BeCnf` expression representing the verification of `formula` on the loaded model for a `bound` time steps ''' import pynusmv.node as _node import pynusmv.parser as _parser import pynusmv.bmc.glob as _bmc import pynusmv.bmc.ltlspec as _ltlspec prop = _node.Node.from_ptr( _parser.parse_ltl_spec(formula) ) fsm = _bmc.master_be_fsm() problem = _ltlspec.generate_ltl_problem(fsm, prop, bound).to_cnf() return problem
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 check(args, condition_text, observable): """ Performs the verification of the diagnosability of the condition represented by `condition_text` and print its result to stdout. :param args: the arguments that were given on the command line :param condition_text: a string representing the diagnosability condition to be verified in the format 'c1 ; c2'. :param observable: the set of symbols considered observable in the context of this diagnosability test """ try: observable_vars = mk_observable_vars(observable) diagnosability_condition = mk_specs_nodes(condition_text) theta = Node.from_ptr(parse_simple_expression(args.initial_condition)) theta = make_nnf_boolean_wff(theta) sigma1 = Node.from_ptr(parse_ltl_spec(args.sigma1)) sigma1 = make_nnf_boolean_wff(sigma1).to_node() sigma2 = Node.from_ptr(parse_ltl_spec(args.sigma2)) sigma2 = make_nnf_boolean_wff(sigma2).to_node() for k in range(args.bound + 1): result = verify_for_size_exactly_k( observable, observable_vars, diagnosability_condition, k, theta, sigma1, sigma2 ) if "No Violation" != str(result): print("-- {} is *NOT* diagnosable for length {}".format(diagnosability_condition, k)) print(result) return print("-- No counter example found for executions of length <= {}".format(k)) except Exception as e: print("The specified condition contains a syntax error") print(e)
def test_constraint_context_sigma(self): fsm = master_be_fsm() _true = Node.from_ptr(parse_ltl_spec("TRUE")) _true = bmcutils.make_nnf_boolean_wff(_true) _truen = _true.to_node() cond = Wff(parse_ltl_spec("G !(mouse = hover)"))\ .to_boolean_wff()\ .to_negation_normal_form() off_1 = 0 off_2 = 2 length = 1 # sigma1 problem = diagnosability.generate_sat_problem([], (_truen, _truen), length, _true, cond.to_node(), _truen) tm_cond = ltlspec.bounded_semantics_at_offset(fsm, cond.to_node(), length, off_1) canonical_p = tests.canonical_cnf(problem) canonical_f = tests.canonical_cnf(tm_cond) self.assertTrue(all(clause in canonical_p for clause in canonical_f)) # sigma2 problem = diagnosability.generate_sat_problem([], (_truen, _truen), length, _true, _truen, cond.to_node()) tm_cond = ltlspec.bounded_semantics_at_offset(fsm, cond.to_node(), length, off_2) canonical_p = tests.canonical_cnf(problem) canonical_f = tests.canonical_cnf(tm_cond) self.assertTrue(all(clause in canonical_p for clause in canonical_f))
def check(args, condition_text, observable): """ Performs the verification of the diagnosability of the condition represented by `condition_text` and print its result to stdout. :param args: the arguments that were given on the command line :param condition_text: a string representing the diagnosability condition to be verified in the format 'c1 ; c2'. :param observable: the set of symbols considered observable in the context of this diagnosability test """ try: observable_vars = mk_observable_vars(observable) diagnosability_condition = mk_specs_nodes(condition_text) theta = Node.from_ptr(parse_simple_expression(args.initial_condition)) theta = make_nnf_boolean_wff(theta) sigma1= Node.from_ptr(parse_ltl_spec(args.sigma1)) sigma1= make_nnf_boolean_wff(sigma1).to_node() sigma2= Node.from_ptr(parse_ltl_spec(args.sigma2)) sigma2= make_nnf_boolean_wff(sigma2).to_node() for k in range(args.bound+1): result = verify_for_size_exactly_k(observable, observable_vars, diagnosability_condition, k, theta, sigma1, sigma2) if "No Violation" != str(result): print("-- {} is *NOT* diagnosable for length {}".format(diagnosability_condition, k)) print(result) return else: print("-- No counter example at length {}".format(k)) print("-- No counter example found for executions of length <= {}".format(args.bound)) except Exception as e: print("The specified condition contains a syntax error") print(e)
def test_bounded_semantics_without_loop(self): # parse the ltl property spec = Node.from_ptr(parse_ltl_spec("G ( y <= 7 )")) # it must raise exception when the bound is not feasible with self.assertRaises(ValueError): ltlspec.bounded_semantics_without_loop(self.fsm, spec, bound=-1) # verify that the generated expression corresponds to what is announced no_loop = ltlspec.bounded_semantics_without_loop(self.fsm, spec, 10) # globally w/o loop is false (this is just a test) self.assertEqual(no_loop, Be.false(self.fsm.encoding.manager)) # an other more complex generation spec = Node.from_ptr(parse_ltl_spec("F (y <= 7)")) no_loop = ltlspec.bounded_semantics_without_loop(self.fsm, spec, 10) # # The generated expression is [[f]]^{0}_{k} so (! L_{k}) is not taken # care of. And actually, NuSMV does not generate that part of the # formula: it only enforce the loop condition when the semantics with # loop is used # handcrafted = Be.false(self.fsm.encoding.manager) y_le_seven = Wff(parse_ltl_spec("y <= 7")).to_boolean_wff().to_be( self.fsm.encoding) for time_x in reversed( range(11)): # 11 because range 'eats' up the last step handcrafted |= self.fsm.encoding.shift_to_time(y_le_seven, time_x) #### debuging info ##### #print("noloop = {}".format(no_loop.to_cnf())) #print("hancraft= {}".format(handcrafted.to_cnf())) #print(self.fsm.encoding) self.assertEqual(no_loop, handcrafted)
def test_bounded_semantics(self): # parse the ltl property spec = Node.from_ptr(parse_ltl_spec("G ( y <= 7 )")) # it must raise exception when the bound is not feasible with self.assertRaises(ValueError): ltlspec.bounded_semantics(self.fsm, spec, bound=-1) # it must raise exception when the bound and loop are not consistent with self.assertRaises(ValueError): ltlspec.bounded_semantics(self.fsm, spec, bound=5, loop=6) # verify that the generated expression corresponds to what is announced formula = ltlspec.bounded_semantics(self.fsm, spec, bound=10) no_loop = ltlspec.bounded_semantics_without_loop(self.fsm, spec, 10) all_loop= ltlspec.bounded_semantics_all_loops(self.fsm, spec, 10, 0) self.assertEqual(formula, no_loop | all_loop)
def test_bounded_semantics(self): # parse the ltl property spec = Node.from_ptr(parse_ltl_spec("G ( y <= 7 )")) # it must raise exception when the bound is not feasible with self.assertRaises(ValueError): ltlspec.bounded_semantics(self.fsm, spec, bound=-1) # it must raise exception when the bound and loop are not consistent with self.assertRaises(ValueError): ltlspec.bounded_semantics(self.fsm, spec, bound=5, loop=6) # verify that the generated expression corresponds to what is announced formula = ltlspec.bounded_semantics(self.fsm, spec, bound=10) no_loop = ltlspec.bounded_semantics_without_loop(self.fsm, spec, 10) all_loop = ltlspec.bounded_semantics_all_loops(self.fsm, spec, 10, 0) self.assertEqual(formula, no_loop | all_loop)
def test_mc_explain_ltl_false(self): # Initialize the model glob.load("tests/pynusmv/models/admin.smv") glob.compute_model() spec = prop.Spec(parser.parse_ltl_spec("G admin = none")) result, explanation = mc.check_explain_ltl_spec(spec) self.assertFalse(result) self.assertIsNotNone(explanation) #print(explanation[0]) #for inputs, state in zip(explanation[1::2], explanation[2::2]): # print(inputs) # print(state) self.assertTrue( any(state["admin"] != "none" for state in explanation[::2]))
def test_generate_ltl_problem(self): # parse the ltl property spec = Node.from_ptr(parse_ltl_spec("G ( y <= 7 )")) # it must raise exception when the bound is not feasible with self.assertRaises(ValueError): ltlspec.generate_ltl_problem(self.fsm, spec, bound=-1) # it must raise exception when the bound and loop are not consistent with self.assertRaises(ValueError): ltlspec.generate_ltl_problem(self.fsm, spec, bound=5, loop=6) problem = ltlspec.generate_ltl_problem(self.fsm, spec, bound=10) self.assertEqual("No counter example", self.do_verify(problem)) # verify that the generated problem corresponds to what is announced model = BmcModel().path(10) negspec = utils.make_negated_nnf_boolean_wff(spec) formula = ltlspec.bounded_semantics(self.fsm, negspec, bound=10) self.assertEqual(problem, model & formula)
def test_verify_exactly(self): theta = Node.from_ptr(parse_simple_expression("TRUE")) theta = bmcutils.make_nnf_boolean_wff(theta) sigma_12 = Node.from_ptr(parse_ltl_spec("TRUE")) sigma_12 = bmcutils.make_nnf_boolean_wff(sigma_12).to_node() obs_names = ["mouse"] obs_vars = diagnosability.mk_observable_vars(obs_names) f1 = Node.from_ptr(parse_simple_expression("status = active")) f2 = Node.from_ptr(parse_simple_expression("status = inactive")) for i in range(5): res = diagnosability.verify_for_size_exactly_k( obs_names, obs_vars, (f1, f2), i, theta, sigma_12, sigma_12) self.assertEqual("No Violation", res) f1 = Node.from_ptr(parse_simple_expression("status = active")) f2 = Node.from_ptr(parse_simple_expression("status = highlight")) res = diagnosability.verify_for_size_exactly_k(obs_names, obs_vars, (f1, f2), 0, theta, sigma_12, sigma_12) self.assertEqual("No Violation", res) res = diagnosability.verify_for_size_exactly_k(obs_names, obs_vars, (f1, f2), 1, theta, sigma_12, sigma_12) self.assertTrue( res.startswith("############### DIAGNOSABILITY VIOLATION")) res = diagnosability.verify_for_size_exactly_k(obs_names, obs_vars, (f1, f2), 2, theta, sigma_12, sigma_12) self.assertTrue( res.startswith("############### DIAGNOSABILITY VIOLATION")) res = diagnosability.verify_for_size_exactly_k(obs_names, obs_vars, (f1, f2), 3, theta, sigma_12, sigma_12) self.assertTrue( res.startswith("############### DIAGNOSABILITY VIOLATION"))
def test_is_past_operator(self): expr = Node.from_ptr(parse_ltl_spec("F G ( w <-> v )")) self.assertFalse(bmcutils.is_past_operator(expr)) expr = Node.from_ptr(parse_ltl_spec("some_variable")) self.assertFalse(bmcutils.is_past_operator(expr)) expr = Node.from_ptr(parse_ltl_spec("TRUE")) self.assertFalse(bmcutils.is_past_operator(expr)) expr = Node.from_ptr(parse_ltl_spec("FALSE")) self.assertFalse(bmcutils.is_past_operator(expr)) expr = Node.from_ptr(parse_ltl_spec("H variable")) self.assertTrue(bmcutils.is_past_operator(expr)) expr = Node.from_ptr(parse_ltl_spec("Y variable")) self.assertTrue(bmcutils.is_past_operator(expr)) expr = Node.from_ptr(parse_ltl_spec("O var")) self.assertTrue(bmcutils.is_past_operator(expr)) expr = Node.from_ptr(parse_ltl_spec("v1 S v2")) self.assertTrue(bmcutils.is_past_operator(expr))
def test_weak_until_noloop(self): with tests.Configure(self, __file__, "/example.smv"): enc = self.enc a = ast.Proposition("a") b = ast.Proposition("b") expr = ast.WeakUntil(a, b) tool = expr.semantic_no_loop(enc, 0, 2) manual = ( b.semantic_no_loop(enc, 0, 2) | (a.semantic_no_loop(enc, 0, 2) & (b.semantic_no_loop(enc, 1, 2) | (a.semantic_no_loop(enc, 1, 2) & (b.semantic_no_loop(enc, 2, 2)))))) spec = Node.from_ptr(parse_ltl_spec("a U b")) nusmv = ltlspec.bounded_semantics(self.befsm, spec, bound=2, loop=bmcutils.no_loopback()) # normalized string representation of the BE's (make them comparable) s_tool = tests.canonical_cnf(tool) s_nusmv = tests.canonical_cnf(nusmv) s_manual= tests.canonical_cnf(manual) self.assertEqual(s_tool, s_manual) self.assertEqual(s_tool, s_nusmv)
def test_bounded_semantics_with_loop(self): # parse the ltl property spec = Node.from_ptr(parse_ltl_spec("G ( y <= 7 )")) # it must raise exception when the bound is not feasible with self.assertRaises(ValueError): ltlspec.bounded_semantics_single_loop(self.fsm, spec, -1, -2) # it must raise exception when the bound and loop are not consistent with self.assertRaises(ValueError): ltlspec.bounded_semantics_single_loop(self.fsm, spec, 5, 6) # verify that the generated problem corresponds to what is announced # without optimisation, the all loops is built as the conjunction of all # the possible 'single_loops' all_loops = ltlspec.bounded_semantics_all_loops(self.fsm, spec, 10, 0, optimized=False) acc_loops = Be.false(self.fsm.encoding.manager) for time_t in range(10): acc_loops |= ltlspec.bounded_semantics_single_loop(self.fsm, spec, 10, time_t) self.assertEqual(acc_loops, all_loops) # with optimisation, it's different all_loops = ltlspec.bounded_semantics_all_loops(self.fsm, spec, 10, 0, optimized=True) self.assertNotEqual(acc_loops, all_loops)
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_dump_dimacs_filename(self): # parse the ltl property spec = Node.from_ptr(parse_ltl_spec("G ( y <= 7 )")) problem = ltlspec.generate_ltl_problem(self.fsm, spec, bound=10) ltlspec.dump_dimacs_filename(self.fsm.encoding, problem.to_cnf(), 10, "test.dimacs")
def check(formula, args): parsed_fml = Node.from_ptr(parse_ltl_spec(formula.strip())) status,length,trace = check_ltl(parsed_fml, args.bound, args.dry_run) if status != 'Ok': print("-- {} for length {}".format(status, length)) print(trace)
def test_operator_class(self): expr = Node.from_ptr(parse_ltl_spec("F G ( w <-> v )")) self.assertEqual(bmcutils.OperatorType.TIME_OPERATOR, bmcutils.operator_class(expr)) expr = Node.from_ptr(parse_ltl_spec("some_variable")) expr.type = _parser.DOT self.assertEqual(bmcutils.OperatorType.LITERAL, bmcutils.operator_class(expr)) expr = Node.from_ptr(parse_ltl_spec("TRUE")) self.assertEqual(bmcutils.OperatorType.CONSTANT_EXPR, bmcutils.operator_class(expr)) expr = Node.from_ptr(parse_ltl_spec("FALSE")) self.assertEqual(bmcutils.OperatorType.CONSTANT_EXPR, bmcutils.operator_class(expr)) expr = Node.from_ptr(parse_ltl_spec("H variable")) self.assertEqual(bmcutils.OperatorType.TIME_OPERATOR, bmcutils.operator_class(expr)) expr = Node.from_ptr(parse_ltl_spec("Y variable")) self.assertEqual(bmcutils.OperatorType.TIME_OPERATOR, bmcutils.operator_class(expr)) expr = Node.from_ptr(parse_ltl_spec("O var")) self.assertEqual(bmcutils.OperatorType.TIME_OPERATOR, bmcutils.operator_class(expr)) expr = Node.from_ptr(parse_ltl_spec("v1 & v2")) self.assertEqual(bmcutils.OperatorType.PROP_CONNECTIVE, bmcutils.operator_class(expr)) expr = Node.from_ptr(parse_ltl_spec("v1 | v2")) self.assertEqual(bmcutils.OperatorType.PROP_CONNECTIVE, bmcutils.operator_class(expr)) expr = Node.from_ptr(parse_ltl_spec("!v1")) self.assertEqual(bmcutils.OperatorType.LITERAL, bmcutils.operator_class(expr)) # this is something I added over the NuSMV macro (but it makes sense) expr = Node.from_ptr(parse_ltl_spec("v1 -> v2")) self.assertEqual(bmcutils.OperatorType.PROP_CONNECTIVE, bmcutils.operator_class(expr)) expr = Node.from_ptr(parse_ltl_spec("v1 <-> v2")) self.assertEqual(bmcutils.OperatorType.PROP_CONNECTIVE, bmcutils.operator_class(expr)) expr = Node.from_ptr(parse_ltl_spec("v1 U v2")) self.assertEqual(bmcutils.OperatorType.TIME_OPERATOR, bmcutils.operator_class(expr)) expr = Node.from_ptr(parse_ltl_spec("v1 S v2")) self.assertEqual(bmcutils.OperatorType.TIME_OPERATOR, bmcutils.operator_class(expr))