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_problem_with_invars(self): ''' This test clearly shows the difference in validating a property with or without fairness constraint ''' with tests.Configure(self, __file__, "/dummy_with_invar.smv"): # length 0 formula = parseLTL("[] v") noinvar = gen.generate_problem(formula, self.befsm, 0, no_invar=True) self.assertEqual(SatSolverResult.SATISFIABLE, self.satisfiability(noinvar)) w_invar = gen.generate_problem(formula, self.befsm, 0, no_invar=False) self.assertEqual(SatSolverResult.UNSATISFIABLE, self.satisfiability(w_invar)) # length 1 noinvar = gen.generate_problem(formula, self.befsm, 1, no_invar=True) self.assertEqual(SatSolverResult.SATISFIABLE, self.satisfiability(noinvar)) w_invar = gen.generate_problem(formula, self.befsm, 1, no_invar=False) self.assertEqual(SatSolverResult.UNSATISFIABLE, self.satisfiability(w_invar))
def check_ltl_onepb(fml, length, no_fairness=False, no_invar=False, dry_run=False): """ This function verifies that the given FSM satisfies the given property for paths with an exact length of `length`. :param fml: an LTL formula parsed with `tools.bmcLTL.parsing` (hence the abstract syntax tree of that formula). Note, this is *NOT* the NuSMV format (Node). :param length: the exact length of the considered paths :param no_fairness: a flag telling whether or not the generated problem should focus on fair executions only (the considered fairness constraints must be declared in the SMV model). :param no_invar: a flag telling whether or not the generated problem should enforce the declared invariants (these must be declared in the SMV text). :return: a tuple ('OK', None) if the property is satisfied on all paths of length `length` :return: a tuple ('Violation', counter_example) if the property is violated. The counter_example passed along is a trace leading to a violation of the property """ fsm = master_be_fsm() pb = generate_problem(fml, fsm, length, no_fairness, no_invar) if not dry_run: cnf = pb.to_cnf(Polarity.POSITIVE) solver = SatSolverFactory.create() solver+= cnf solver.polarity(cnf, Polarity.POSITIVE) if solver.solve() == SatSolverResult.SATISFIABLE: cnt_ex = generate_counter_example(fsm, pb, solver, length, str(fml)) return ("Violation", cnt_ex) else: return ("Ok", None) return ("Ok", None)