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_next_no_loop(self): with Configure(self, __file__, "/models/flipflops.smv"): fsm = self.befsm formula = self.nnf("X (a <-> !b)") # bound 0 ref_expr= ltlspec.bounded_semantics_without_loop(fsm, formula, 0) expr = ltlspec.bounded_semantics_without_loop_at_offset(fsm, formula, 0, 0, 0) self.assertEqual(canonical_cnf(expr), canonical_cnf(ref_expr)) # bound 1 ref_expr= ltlspec.bounded_semantics_without_loop(fsm, formula, 1) expr = ltlspec.bounded_semantics_without_loop_at_offset(fsm, formula, 0, 1, 0) self.assertEqual(canonical_cnf(expr), canonical_cnf(ref_expr)) # ---- other offset ---- # bound 0 offset = 1 ref_expr= Be.false(fsm.encoding.manager) expr = ltlspec.bounded_semantics_without_loop_at_offset(fsm, formula, 0, 0, offset) self.assertEqual(canonical_cnf(expr), canonical_cnf(ref_expr)) # bound 1 offset = 1 ref_expr= Wff.decorate(ltlspec.car(formula)).to_be(fsm.encoding) ref_expr= fsm.encoding.shift_to_time(ref_expr, offset+1) expr = ltlspec.bounded_semantics_without_loop_at_offset(fsm, formula, 0, 1, offset) self.assertEqual(canonical_cnf(expr), canonical_cnf(ref_expr))
def test_globally_no_loop(self): with Configure(self, __file__, "/models/flipflops.smv"): fsm = self.befsm formula = self.nnf("G (a <-> !b)") # bound 0 ref_expr= ltlspec.bounded_semantics_without_loop(fsm, formula, 0) expr = ltlspec.bounded_semantics_without_loop_at_offset(fsm, formula, 0, 0, 0) self.assertEqual(canonical_cnf(expr), canonical_cnf(ref_expr)) # bound 1 ref_expr= ltlspec.bounded_semantics_without_loop(fsm, formula, 1) expr = ltlspec.bounded_semantics_without_loop_at_offset(fsm, formula, 0, 1, 0) self.assertEqual(canonical_cnf(expr), canonical_cnf(ref_expr)) # ---- other offset ---- # bound 0 offset = 1 ref_expr= Be.false(fsm.encoding.manager) expr = ltlspec.bounded_semantics_without_loop_at_offset(fsm, formula, 0, 0, offset) self.assertEqual(canonical_cnf(expr), canonical_cnf(ref_expr)) # bound 1 offset = 1 ref_expr= Be.false(fsm.encoding.manager) expr = ltlspec.bounded_semantics_without_loop_at_offset(fsm, formula, 0, 1, offset) self.assertEqual(canonical_cnf(expr), canonical_cnf(ref_expr))
def test_releases_no_loop(self): with Configure(self, __file__, "/models/flipflops.smv"): fsm = self.befsm formula = self.nnf("(a V b)") # bound 0 ref_expr= ltlspec.bounded_semantics_without_loop(fsm, formula, 0) expr = ltlspec.bounded_semantics_without_loop_at_offset(fsm, formula, 0, 0, 0) self.assertEqual(canonical_cnf(expr), canonical_cnf(ref_expr)) # bound 1 ref_expr= ltlspec.bounded_semantics_without_loop(fsm, formula, 1) expr = ltlspec.bounded_semantics_without_loop_at_offset(fsm, formula, 0, 1, 0) self.assertEqual(canonical_cnf(expr), canonical_cnf(ref_expr)) # bound 2 -- verification must be done by hand because the different # cnf literals mess the comparison ref_expr= ltlspec.bounded_semantics_without_loop(fsm, formula, 2) expr = ltlspec.bounded_semantics_without_loop_at_offset(fsm, formula, 0, 2, 0) self.assertEqual(canonical_cnf(expr), canonical_cnf(ref_expr)) # ---- other offset ---- # bound 0 offset = 1 bound = 0 left = Wff.decorate(ltlspec.car(formula)).to_be(fsm.encoding) right = Wff.decorate(ltlspec.cdr(formula)).to_be(fsm.encoding) ref_expr= self.enc.shift_to_time(right, offset) & self.enc.shift_to_time(left, offset) expr = ltlspec.bounded_semantics_without_loop_at_offset(fsm, formula, 0, bound, offset) self.assertEqual(canonical_cnf(expr), canonical_cnf(ref_expr)) # bound 1 offset = 1 bound = 1 left = Wff.decorate(ltlspec.car(formula)).to_be(fsm.encoding) right = Wff.decorate(ltlspec.cdr(formula)).to_be(fsm.encoding) ref_expr= self.enc.shift_to_time(right, offset) & ( self.enc.shift_to_time(left, offset) \ | (self.enc.shift_to_time(right, 1+offset) & self.enc.shift_to_time(left, 1+offset))) expr = ltlspec.bounded_semantics_without_loop_at_offset(fsm, formula, 0, bound, offset) self.assertEqual(canonical_cnf(expr), canonical_cnf(ref_expr))
def test_until_no_loop(self): with Configure(self, __file__, "/models/flipflops.smv"): fsm = self.befsm formula = self.nnf("(a U b)") # bound 0 ref_expr= ltlspec.bounded_semantics_without_loop(fsm, formula, 0) expr = ltlspec.bounded_semantics_without_loop_at_offset(fsm, formula, 0, 0, 0) self.assertEqual(canonical_cnf(expr), canonical_cnf(ref_expr)) # bound 1 ref_expr= ltlspec.bounded_semantics_without_loop(fsm, formula, 1) expr = ltlspec.bounded_semantics_without_loop_at_offset(fsm, formula, 0, 1, 0) self.assertEqual(canonical_cnf(expr), canonical_cnf(ref_expr)) # bound 2 -- verification must be done by hand because the different # cnf literals mess the comparison # ref_expr= ltlspec.bounded_semantics_without_loop(fsm, formula, 2) # expr = ltlspec.bounded_semantics_without_loop_at_offset(fsm, formula, 0, 2, 0) # self.assertEqual(canonical_cnf(expr), canonical_cnf(ref_expr)) # ---- other offset ---- # bound 0 offset = 1 ref_expr= Wff.decorate(ltlspec.cdr(formula)).to_be(fsm.encoding) ref_expr= fsm.encoding.shift_to_time(ref_expr, offset) expr = ltlspec.bounded_semantics_without_loop_at_offset(fsm, formula, 0, 0, offset) self.assertEqual(canonical_cnf(expr), canonical_cnf(ref_expr)) # bound 1 offset = 1 cdr = Wff.decorate(ltlspec.cdr(formula)).to_be(fsm.encoding) car = Wff.decorate(ltlspec.car(formula)).to_be(fsm.encoding) ref_expr= fsm.encoding.shift_to_time(cdr, offset) \ | ( fsm.encoding.shift_to_time(car, offset) \ & fsm.encoding.shift_to_time(cdr, offset+1)) expr = ltlspec.bounded_semantics_without_loop_at_offset(fsm, formula, 0, 1, offset) self.assertEqual(canonical_cnf(expr), canonical_cnf(ref_expr))
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)