def test_trans(self): # time must be >= 0 with self.assertRaises(ValueError): BmcModel(self.fsm).trans[-1] # at time 0 trans = self.fsm.encoding.shift_to_time(self.fsm.trans, 0) self.assertEqual(trans, BmcModel(self.fsm).trans[0]) # at time 4 trans = self.fsm.encoding.shift_to_time(self.fsm.trans, 4) self.assertEqual(trans, BmcModel(self.fsm).trans[4])
def test_init(self): # time must be >= 0 with self.assertRaises(ValueError): BmcModel(self.fsm).init[-1] # at time 0 init0 = self.fsm.encoding.shift_to_time(self.fsm.init, 0) self.assertEqual(init0, BmcModel(self.fsm).init[0]) # at time 4 init4 = self.fsm.encoding.shift_to_time(self.fsm.init, 4) self.assertEqual(init4, BmcModel(self.fsm).init[4])
def test_invar(self): # time must be >= 0 with self.assertRaises(ValueError): BmcModel(self.fsm).invar[-1] # at time 0 invar0 = self.fsm.encoding.shift_to_time(self.fsm.invariants, 0) self.assertEqual(invar0, BmcModel(self.fsm).invar[0]) # at time 4 invar4 = self.fsm.encoding.shift_to_time(self.fsm.invariants, 4) self.assertEqual(invar4, BmcModel(self.fsm).invar[4])
def test_path(self): model = BmcModel(self.fsm) noinit = model.path(3, with_init=False) w_init = model.path(3) self.assertEqual(w_init, (noinit & model.init[0])) self.assertEqual(noinit, model.unrolling(0, 3))
def test_fairness(self): model = BmcModel(self.fsm) # K, L must be consistent with one another with self.assertRaises(ValueError): model.fairness(0, 1) self.assertIsNotNone(model.fairness(3, 0)) self.assertEqual(Be, type(model.fairness(3, 0))) # Manual verification, this should output the following formula: # (NOT (AND (NOT X3) (AND (NOT X4) (NOT X5)))) self.enc.manager.dump_sexpr(model.fairness(3, 0), StdioFile.stdout())
def generate_path(offset, length): """ Returns a boolean expression representing a path of length `length` in the fsm described by the loaded model. :param length: the length of the path in the fsm :param offset: the offset at which the path should be starting :return: a boolean expression representing a path of length `length` in the loaded fsm. """ model = BmcModel() path = model.init[offset] & model.unrolling(offset, offset + length) return path
def test_generate_base_step(self): # BASE STEP = (I0 -> P0 ) for prop in prop_database(): expr = utils.make_nnf_boolean_wff(prop.expr) gen = invarspec.generate_base_step(self.fsm, expr) # model = BmcModel() i0 = model.init[0] & model.invar[0] # recall: the prop has to be shifted to time 0 p0 = self.fsm.encoding.shift_to_time(expr.to_be(self.fsm.encoding), 0) manual = i0.imply(p0) self.assertEqual(gen.to_cnf().vars_list, manual.to_cnf().vars_list)
def test_generate_inductive_step(self): # INDUCT = (P0 and R01) -> P1 for prop in prop_database(): expr = utils.make_nnf_boolean_wff(prop.expr) gen = invarspec.generate_inductive_step(self.fsm, expr) # model = BmcModel() r01 = model.unrolling(0, 1) # recall: the prop has to be shifted to time 0 p = expr.to_be(self.fsm.encoding) p0 = self.fsm.encoding.shift_to_time(p, 0) p1 = self.fsm.encoding.shift_to_time(p, 1) manual = (p0 & r01).imply(p1) self.assertEqual(gen.to_cnf().vars_list, manual.to_cnf().vars_list)
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_unrolling_fragment(self): # comparing the clauses list is not feasible because of the formula # literal which is embedded in the clauses and vary from one implem # to the next # Thus, this test lets us at least get some confidence about the # equivalence between the two Be's model = BmcModel(self.fsm) # time index starts at 1 with self.assertRaises(ValueError): model.unrolling_fragment[-1] self.assertEquals(model.init[0], model.unrolling_fragment[0]) manual = model.invar[1] & model.trans[1] & model.invar[2] tested = model.unrolling_fragment[2] # because the var ordering does not matter at all manual_set = set(manual.to_cnf().vars_list) tested_set = set(tested.to_cnf().vars_list) self.assertEqual(manual_set, tested_set)
def test_unrolling(self): # comparing the clauses list is not feasible because of the formula # literal which is embedded in the clauses and vary from one implem # to the next # Thus, this test lets us at least get some confidence about the # equivalence between the two Be's def manual_unrolling(j, bound): trans = Be.true(self.enc.manager) for k in range(j, bound): trans = trans & self.enc.shift_to_time(self.fsm.trans, k) return trans model = BmcModel(self.fsm) manual = manual_unrolling(4, 5) tested = model.unrolling(4,5) # because the var ordering does not matter at all manual_set = set(manual.to_cnf().vars_list) tested_set = set(tested.to_cnf().vars_list) self.assertEqual(manual_set, tested_set)
def test_invar_dual_forward(self): print(BmcModel(self.fsm).unrolling(4,5))