コード例 #1
0
    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)
コード例 #2
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)
コード例 #3
0
    def test_not_with_loop(self):
        with tests.Configure(self, __file__, "/example.smv"):
            # constant
            expr = ast.Not(ast.Constant("TRUE"))
            self.assertEqual(
                ast.Constant("FALSE").semantic_with_loop(self.enc, 2, 3, 1),
                expr.semantic_with_loop(self.enc, 2, 3, 1))

            # variable
            expr = ast.Not(ast.Proposition("a"))
            self.assertEqual(
                -ast.Proposition("a").semantic_with_loop(self.enc, 2, 3, 1),
                expr.semantic_with_loop(self.enc, 2, 3, 1))

            # not
            expr = ast.Not(ast.Not(ast.Proposition("a")))
            self.assertEqual(
                ast.Proposition("a").semantic_with_loop(self.enc, 2, 3, 1),
                expr.semantic_with_loop(self.enc, 2, 3, 1))

            # expression: and
            expr = ast.Not(ast.And(ast.Proposition("a"), ast.Proposition("b")))
            self.assertEqual(
                -(ast.Proposition("a").semantic_with_loop(self.enc, 2, 3, 1)
                  & ast.Proposition("b").semantic_with_loop(self.enc, 2, 3,
                                                            1)),
                expr.semantic_with_loop(self.enc, 2, 3, 1))

            # expression: weak until
            expr = ast.WeakUntil(ast.Proposition("a"), ast.Proposition("b"))
            nega = ast.Not(expr)
            self.assertEqual(-expr.semantic_with_loop(self.enc, 2, 3, 1),
                             nega.semantic_with_loop(self.enc, 2, 3, 1))
コード例 #4
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)
コード例 #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)
コード例 #6
0
 def test_variable_noloop(self):
     with tests.Configure(self, __file__, "/example.smv"):
         expr = ast.Proposition("a")
         self.assertEqual(
             self.enc.by_name['a'].at_time[3].boolean_expression,
             expr.semantic_no_loop(self.enc, 3, 5))
         # bound has little impact on the BE for a variable
         self.assertEqual(
             self.enc.by_name['a'].at_time[3].boolean_expression,
             expr.semantic_no_loop(self.enc, 3, 3))
コード例 #7
0
    def test_globally_no_loop(self):
        with tests.Configure(self, __file__, "/example.smv"):
            i, k = 0, 2
            enc = self.enc
            mgr = enc.manager
            a = ast.Proposition("a")
            formula = ast.Globally(a)

            tool = formula.semantic_no_loop(enc, i, k)
            self.assertEqual(Be.false(mgr), tool)
コード例 #8
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)
コード例 #9
0
 def test_variable_withloop(self):
     with tests.Configure(self, __file__, "/example.smv"):
         # bound and loop have no impact on the way BE for a variable is
         # generated (successor index not enforced)
         expr = ast.Proposition("a")
         self.assertEqual(
             self.enc.by_name['a'].at_time[3].boolean_expression,
             expr.semantic_with_loop(self.enc, 3, 5, 2))
         self.assertEqual(
             self.enc.by_name['a'].at_time[3].boolean_expression,
             expr.semantic_with_loop(self.enc, 3, 3, 3))
コード例 #10
0
    def test_imply_noloop(self):
        with tests.Configure(self, __file__, "/example.smv"):
            expr = ast.Imply(ast.Proposition("a"), ast.Proposition("b"))
            self.assertEqual(
                (ast.Proposition("a").semantic_no_loop(self.enc, 2, 3).imply(
                    ast.Proposition("b").semantic_no_loop(self.enc, 2, 3))),
                expr.semantic_no_loop(self.enc, 2, 3))

            expr = ast.Imply(ast.Globally(ast.Proposition("a")),
                             ast.Eventually(ast.Proposition("b")))
            self.assertEqual(
                (-ast.Globally(ast.Proposition("a")).semantic_no_loop(
                    self.enc, 2, 3)
                 | ast.Eventually(ast.Proposition("b")).semantic_no_loop(
                     self.enc, 2, 3)), expr.semantic_no_loop(self.enc, 2, 3))
コード例 #11
0
    def test_weak_until_with_loop(self):
        with tests.Configure(self, __file__, "/example.smv"):
            enc = self.enc
            mgr = enc.manager
            i, k, l = 0, 2, 0
            a = ast.Proposition("a")
            b = ast.Proposition("b")

            expr = ast.WeakUntil(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) | \
                                a.semantic_with_loop(enc, i+1, k, l) & Be.true(mgr)
                            )
                         )

            # normalized string representation of the BE's (make them comparable)
            s_tool = tests.canonical_cnf(tool)
            s_manual = tests.canonical_cnf(manual)

            self.assertEqual(s_tool, s_manual)
コード例 #12
0
    def test_xor_with_loop(self):
        with tests.Configure(self, __file__, "/example.smv"):
            expr = ast.Xor(ast.Proposition("a"), ast.Proposition("b"))
            self.assertEqual(
                (ast.Proposition("a").semantic_with_loop(self.enc, 2, 3, 1)
                 ^ ast.Proposition("b").semantic_with_loop(self.enc, 2, 3, 1)),
                expr.semantic_with_loop(self.enc, 2, 3, 1))

            expr = ast.Xor(ast.Globally(ast.Proposition("a")),
                           ast.Eventually(ast.Proposition("b")))
            self.assertEqual(
                (ast.Globally(ast.Proposition("a")).semantic_with_loop(
                    self.enc, 2, 3, 1)
                 ^ ast.Eventually(ast.Proposition("b")).semantic_with_loop(
                     self.enc, 2, 3, 1)),
                expr.semantic_with_loop(self.enc, 2, 3, 1))
コード例 #13
0
def make_plain_proposition(s,l,tokens):
    """
    This parse action makes a plain Proposition (as defined in 
    :see:`pynusmv_tools.bmcLTL.ast.Proposition`) from the parsed text. 
    
    .. note::
        This action 'flattens' the expression; meaning that the result of the
        parsing of a complex proposition such as '(a + b) << 4 >= c - 6' will
        result in one single `Proposition` blob instead of being decomposed. 
        Namely, the previous example would yield::
        
            ast.Proposition( (a + b) << 4 >= c - 6 )
        
        This is a design choice motivated by the fact that:
        
            1. the objective of this tool is to illustrate the functioning of
               LTL bounded model checking and how its reduction to propositional 
               satisfiability (SAT) can be implemented with PyNuSMV as if it 
               were a brand new logical formalism; not to demonstrate how 
                relational and arithmetic expressions can be booleanized.
            2. the expressions represented this way do not contain any of the
               logical connectives which are part of LTL syntax and are as such
               out of the scope of this tool. (They can have no impact on the
               generated BMC problem).
            3. Relational and arithmetic 
               operators are only provided for the sake of being able to perform
               useful verification on realistic like models without being forced
               to go through the burden of defining DEFINE for each of the 
               expressions used.
               
    .. note::
        You should really not worry to much about the meaning of the parameters,
        there are inherited from the parseAction protocol.
        
    :param s: the original string corresponding to the text that has been parsed
    :param l: the location in the string where matching started
    :param tokens: the list of the matched tokens (actually a 
        :see:`pyparsing.ParseResult`)
    :return: a `Proposition` ast node encapsulating the parsed expression. 
    """
    members = tokens[0]
    text_of = lambda x: '('+x.id+')' if hasattr(x, 'id') else x
    members = list(map(text_of, members))
    return ast.Proposition(' '.join(members))
コード例 #14
0
"""
This module contains the class definition of the symbols and grammar of an LTL
formula
"""

import pyparsing as pp
import pynusmv_tools.bmcLTL.ast as ast

###############################################################################
# Symbols and keywords
###############################################################################

# terminals
number   = pp.Regex("[0-9]+").setParseAction(lambda s,l,t: ast.Constant(t[0]))
variable = pp.Regex("[a-zA-Z_@]+[a-zA-Z0-9_@.]*").setParseAction(lambda s,l,t: ast.Proposition(t[0]))
true     = pp.Keyword("TRUE" ).setParseAction(lambda s,l,t: ast.Constant("TRUE"))
false    = pp.Keyword("FALSE").setParseAction(lambda s,l,t: ast.Constant("FALSE"))

# temporal operators
op_G     = pp.Literal("[]")
op_F     = pp.Literal("<>")
op_X     = pp.Literal("()")
op_U     = pp.Keyword("U")
op_W     = pp.Keyword("W")

# propositional operators
op_not   = pp.Literal("!")
op_and   = pp.Literal("&")
op_or    = pp.Literal("|")
op_xor   = pp.Literal("^")
op_impl  = pp.Literal("=>")