Beispiel #1
0
    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))
Beispiel #2
0
 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)
Beispiel #3
0
    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])
Beispiel #4
0
 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))
Beispiel #5
0
 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)
Beispiel #6
0
    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))
Beispiel #7
0
 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)
Beispiel #8
0
    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))
Beispiel #9
0
    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))
Beispiel #10
0
    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)
Beispiel #11
0
    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_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)
Beispiel #13
0
 def decode_value(self, list_of_bits_and_value):
     """
     Returns a node (:class:`pynusmv.node.Node`) corresponding to the value of
     the variable encoded by the list of bits and values.
     
     :param list_of_bits_and_value: a sequence of tuples (BeVar, BooleanValue)
         which represent a bit and its value.
     :return: an intelligible value node corresponding to what these bits
         means when interpreted in the context of the SMV model.
     """
     if not list_of_bits_and_value:
         raise ValueError("The given list of bits and values must at least "+
                          "contain one bit")
     # if the variable to be decoded is boolean in the model 
     if not list_of_bits_and_value[0][0].is_bit:
         return list_of_bits_and_value[0][1]
     
     # otherwise decode the bits
     bool_enc = self._bool_enc
     scalar   = list_of_bits_and_value[0][0].scalar
     
     bv = _bool.BitValues_create(bool_enc, scalar._ptr)
     for bit,val in list_of_bits_and_value:
         bit_index = _bool.BoolEnc_get_index_from_bit(bool_enc, bit.name._ptr)
         _bool.BitValues_set(bv, bit_index, val)
         
     result_ptr = _bool.BoolEnc_get_value_from_var_bits(bool_enc, bv)
     
     _bool.BitValues_destroy(bv)
     return Node.from_ptr(result_ptr)
Beispiel #14
0
 def test_clear(self):
     """Verifies that clear works as expected"""
     h = Assoc(_u.new_assoc(), freeit=True)
     a = Node.from_ptr(parse_simple_expression("a.car = 3"), freeit=False)
     h[a] = a
     h.clear()
     self.assertFalse(a in h)
Beispiel #15
0
    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)
Beispiel #16
0
 def test_copy(self):
     """Tests the copy behavior"""
     h = Assoc(_u.new_assoc(), freeit=True)
     a = Node.from_ptr(parse_simple_expression("a.car = 3"), freeit=False)
     h[a] = a
     h2= h.copy()
     self.assertTrue(a in h2)
Beispiel #17
0
 def test_clear(self):
     """Verifies that clear works as expected"""
     h = Assoc(_u.new_assoc(), freeit=True)
     a = Node.from_ptr(parse_simple_expression("a.car = 3"), freeit=False)
     h[a] = a
     h.clear()
     self.assertFalse(a in h) 
    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)
Beispiel #19
0
 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)
Beispiel #20
0
    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_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)
Beispiel #22
0
 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))
     
Beispiel #23
0
 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)
Beispiel #24
0
 def decode_value(self, list_of_bits_and_value):
     """
     Returns a node (:see:`pynusmv.node.Node`) corresponding to the value of
     the variable encoded by the list of bits and values.
     
     :param list_of_bits_and_value: a sequence of tuples (BeVar, BooleanValue)
         which represent a bit and its value.
     :return: an intelligible value node corresponding to what these bits
         means when interpreted in the context of the SMV model.
     """
     if not list_of_bits_and_value:
         raise ValueError("The given list of bits and values must at least "+
                          "contain one bit")
     # if the variable to be decoded is boolean in the model 
     if not list_of_bits_and_value[0][0].is_bit:
         return list_of_bits_and_value[0][1]
     
     # otherwise decode the bits
     bool_enc = self._bool_enc
     scalar   = list_of_bits_and_value[0][0].scalar
     
     bv = _bool.BitValues_create(bool_enc, scalar._ptr)
     for bit,val in list_of_bits_and_value:
         bit_index = _bool.BoolEnc_get_index_from_bit(bool_enc, bit.name._ptr)
         _bool.BitValues_set(bv, bit_index, val)
         
     result_ptr = _bool.BoolEnc_get_value_from_var_bits(bool_enc, bv)
     
     _bool.BitValues_destroy(bv)
     return Node.from_ptr(result_ptr)
Beispiel #25
0
 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)
Beispiel #26
0
    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)
Beispiel #27
0
 def test_copy(self):
     """Tests the copy behavior"""
     h = Assoc(_u.new_assoc(), freeit=True)
     a = Node.from_ptr(parse_simple_expression("a.car = 3"), freeit=False)
     h[a] = a
     h2 = h.copy()
     self.assertTrue(a in h2)
Beispiel #28
0
    def test_empty(self):
        """Tests the empty factory"""
        a = Node.from_ptr(parse_simple_expression("a.car = 3"), freeit=False)
        h = Assoc.empty(freeit=True)
        self.assertFalse(a in h)

        hh = Assoc.empty(initial_capa=1, freeit=True)
        hh[a] = a
        self.assertTrue(a in hh)
Beispiel #29
0
 def name(self):
     """
     Returns the name of this BOOLEAN variable. If this variable was not
     declared boolean in the SMV text, this is going to be the name of one
     of the bits composing that variable. 
     
     :return: the name node corresponding to this boolean variable.
     """
     ptr = _be.BeEnc_index_to_name(self.encoding._ptr, self.untimed.index)
     return Node.from_ptr(ptr)
Beispiel #30
0
 def name(self):
     """
     Returns the name of this BOOLEAN variable. If this variable was not
     declared boolean in the SMV text, this is going to be the name of one
     of the bits composing that variable. 
     
     :return: the name node corresponding to this boolean variable.
     """
     ptr = _be.BeEnc_index_to_name(self.encoding._ptr, self.untimed.index)
     return Node.from_ptr(ptr)
Beispiel #31
0
    def test_associative_array(self):
        """
        This function tests the basic functions of the associative array proto
        """
        h = Assoc(_u.new_assoc(), freeit=True)
        a = Node.from_ptr(parse_simple_expression("a.car = 3"), freeit=False)
        b = Node.from_ptr(parse_simple_expression("b.car = 3"), freeit=False)

        # __contains__
        self.assertFalse(a in h)
        # __setitem__
        h[a] = a
        self.assertTrue(a in h)
        # __getitem__
        self.assertEqual(h[a], a)
        with self.assertRaises(KeyError):
            h[b]
        # __delitem__
        del h[a]
        self.assertFalse(a in h)
Beispiel #32
0
 def __next__(self):
     """
     Performs the iteration
     :return: the next node
     :raise: StopIteration when the iteration is over
     """
     if self._ptr is None:
         raise StopIteration
     else:
         ret = Node.from_ptr(self._ptr)
         self._ptr = _node.cdr(self._ptr)
         return ret
Beispiel #33
0
def cdr(this_node):
    """
    Returns the rhs branch of this node. 

    .. note::

        This is a simple workaround of `Node.cdr` which does not behave as expected.

    :param this_node: the node whose rhs (cdr) is wanted.
    :return: the rhs member of this node.
    """
    return Node.from_ptr(_node.cdr(this_node._ptr))
Beispiel #34
0
def cdr(this_node):
    """
    Returns the rhs branch of this node. 

    .. note::

        This is a simple workaround of `Node.cdr` which does not behave as expected.

    :param this_node: the node whose rhs (cdr) is wanted.
    :return: the rhs member of this node.
    """
    return Node.from_ptr(_node.cdr(this_node._ptr))
Beispiel #35
0
 def __next__(self):
     """
     Performs the iteration
     :return: the next node
     :raise: StopIteration when the iteration is over
     """
     if self._ptr is None:
         raise StopIteration
     else:
         ret = Node.from_ptr(self._ptr)
         self._ptr = _node.cdr(self._ptr)
         return ret
Beispiel #36
0
 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"))
Beispiel #37
0
 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_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())
Beispiel #39
0
 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_eventually_critical_pair(self):
        enc = master_be_fsm().encoding
        f1 = Node.from_ptr(parse_simple_expression("status = active"))
        f2 = Node.from_ptr(parse_simple_expression("status = highlight"))

        constraint = diagnosability.constraint_eventually_critical_pair(
            (f1, f2), 0, 5, 5)

        nnf1 = bmcutils.make_nnf_boolean_wff(f1).to_be(enc)
        nnf2 = bmcutils.make_nnf_boolean_wff(f2).to_be(enc)
        manual = Be.false(enc.manager)

        for i in range(6):  # again, from 0 to 5
            manual |= (enc.shift_to_time(nnf1, i)
                       & enc.shift_to_time(nnf2, 5 + i))

        # observing the clauses generated in both cases, one observes that
        # the generated clauses are the same except that the number of the cnf
        # literals do not match, example:
        #                        [-59, -24, 58]
        #                        [-65, -24, 64]
        # This is due to the fact that some 'fresh' cnf literals are used in the
        # generation of the epxression. Therefore, a comparison (even on the
        # canonical form of the CNF) is not feasible.
        #
        # Satisfiability is just an indication but at least that is .. something
        solver_c = SatSolverFactory.create()
        cnf = constraint.to_cnf()
        solver_c += cnf
        solver_c.polarity(cnf, Polarity.POSITIVE)
        result_c = solver_c.solve()

        solver_m = SatSolverFactory.create()
        cnf = manual.to_cnf()
        solver_m += cnf
        solver_m.polarity(cnf, Polarity.POSITIVE)
        result_m = solver_m.solve()

        self.assertEqual(result_c, result_m)
Beispiel #42
0
 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)
Beispiel #43
0
 def value(self, symbol_node):
     """
     Retrieves the value that was assigned to `symbol_node` in the current
     trace step.
     
     :param symbol_node: a Node (:class:`pynusmv.node.Node`) 
         representing the symbol to which a value is assigned
     :return: a value_node, that is to say a Node (:class:`pynusmv.node.Node`)
         representing the value being assigned to the requested symbol.   
     """
     return Node.from_ptr(
         _trace.Trace_step_get_value(self.trace._ptr, self._ptr,
                                     symbol_node._ptr))
Beispiel #44
0
 def test_eventually_critical_pair(self):
     enc= master_be_fsm().encoding
     f1 = Node.from_ptr(parse_simple_expression("status = active"))
     f2 = Node.from_ptr(parse_simple_expression("status = highlight"))
     
     constraint = diagnosability.constraint_eventually_critical_pair((f1, f2), 0, 5, 5)
     
     nnf1   = bmcutils.make_nnf_boolean_wff(f1).to_be(enc)
     nnf2   = bmcutils.make_nnf_boolean_wff(f2).to_be(enc)
     manual = Be.false(enc.manager)
     
     for i in range(6): # again, from 0 to 5
         manual |= ( enc.shift_to_time(nnf1 , i)
                   & enc.shift_to_time(nnf2 , 5+i))
     
     # observing the clauses generated in both cases, one observes that 
     # the generated clauses are the same except that the number of the cnf
     # literals do not match, example:
     #                        [-59, -24, 58]
     #                        [-65, -24, 64]
     # This is due to the fact that some 'fresh' cnf literals are used in the
     # generation of the epxression. Therefore, a comparison (even on the 
     # canonical form of the CNF) is not feasible.
     #
     # Satisfiability is just an indication but at least that is .. something
     solver_c = SatSolverFactory.create()
     cnf      = constraint.to_cnf()
     solver_c+= cnf
     solver_c.polarity(cnf, Polarity.POSITIVE)
     result_c = solver_c.solve()
     
     solver_m = SatSolverFactory.create()
     cnf      = manual.to_cnf()
     solver_m+= cnf
     solver_m.polarity(cnf, Polarity.POSITIVE)
     result_m = solver_m.solve()
     
     self.assertEqual(result_c, result_m)
Beispiel #45
0
 def scalar(self):
     """
     Returns the name node of this variable as it was declared in the SMV 
     text (hence not the name of the bit, but the name of the variable).
     
     :see:`is_bit`
     :return: the name node corresponding to scalar using this variable.
     """
     bool_enc = self.encoding._bool_enc
     if self.is_bit:
         scalar = _bool.BoolEnc_get_scalar_var_from_bit(bool_enc, self.name._ptr) 
         return Node.from_ptr(scalar)
     else:
         return self.name
Beispiel #46
0
 def scalar(self):
     """
     Returns the name node of this variable as it was declared in the SMV 
     text (hence not the name of the bit, but the name of the variable).
     
     .. seealso:: `is_bit`
     :return: the name node corresponding to scalar using this variable.
     """
     bool_enc = self.encoding._bool_enc
     if self.is_bit:
         scalar = _bool.BoolEnc_get_scalar_var_from_bit(bool_enc, self.name._ptr) 
         return Node.from_ptr(scalar)
     else:
         return self.name
Beispiel #47
0
 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))
Beispiel #48
0
 def value(self, symbol_node):
     """
     Retrieves the value that was assigned to `symbol_node` in the current
     trace step.
     
     :param symbol_node: a Node (:see: :class: `pynusmv.node.Node`) 
         representing the symbol to which a value is assigned
     :return: a value_node, that is to say a Node (:see: :class: `pynusmv.node.Node`)
         representing the value being assigned to the requested symbol.   
     """
     return Node.from_ptr(_trace.Trace_step_get_value(
                                         self.trace._ptr, 
                                         self._ptr, 
                                         symbol_node._ptr))
Beispiel #49
0
 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 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)
Beispiel #51
0
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)
Beispiel #52
0
    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)
Beispiel #53
0
    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)
Beispiel #54
0
    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])
Beispiel #55
0
    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)
Beispiel #56
0
 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)
Beispiel #57
0
 def test_associative_array(self):
     """
     This function tests the basic functions of the associative array proto
     """
     h = Assoc(_u.new_assoc(), freeit=True)
     a = Node.from_ptr(parse_simple_expression("a.car = 3"), freeit=False)
     
     # __contains__
     self.assertFalse(a in h)
     # __setitem__
     h[a] = a
     self.assertTrue(a in h)
     # __getitem__
     self.assertEqual(h[a], a)
     # __delitem__
     del h[a]
     self.assertFalse(a in h)
Beispiel #58
0
    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)
Beispiel #59
0
 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)
Beispiel #60
0
    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)