Exemplo n.º 1
0
    def test_loop_from_string(self):
        self.assertEqual(4, bmcutils.loop_from_string("4"))
        self.assertEqual(-1, bmcutils.loop_from_string("-1"))
        self.assertEqual(bmcutils.all_loopbacks(),
                         bmcutils.loop_from_string("*"))
        self.assertEqual(bmcutils.all_loopbacks(),
                         bmcutils.loop_from_string("All"))
        self.assertEqual(bmcutils.all_loopbacks(),
                         bmcutils.loop_from_string("All Loops"))
        self.assertEqual(bmcutils.all_loopbacks(),
                         bmcutils.loop_from_string("all"))
        self.assertEqual(bmcutils.all_loopbacks(),
                         bmcutils.loop_from_string("all loops"))

        self.assertEqual(bmcutils.no_loopback(),
                         bmcutils.loop_from_string("x"))
        self.assertEqual(bmcutils.no_loopback(),
                         bmcutils.loop_from_string("No"))
        self.assertEqual(bmcutils.no_loopback(),
                         bmcutils.loop_from_string("None"))
        self.assertEqual(bmcutils.no_loopback(),
                         bmcutils.loop_from_string("No Loop"))
        self.assertEqual(bmcutils.no_loopback(),
                         bmcutils.loop_from_string("no"))
        self.assertEqual(bmcutils.no_loopback(),
                         bmcutils.loop_from_string("none"))
        self.assertEqual(bmcutils.no_loopback(),
                         bmcutils.loop_from_string("no loop"))
Exemplo n.º 2
0
 def test_no_loopback(self):
     self.assertTrue(bmcutils.is_no_loopback(bmcutils.no_loopback()))
     self.assertFalse(bmcutils.is_no_loopback(1000))
     self.assertFalse(bmcutils.is_no_loopback(bmcutils.all_loopbacks()))
     self.assertFalse(bmcutils.is_no_loopback(-1 *
                                              bmcutils.all_loopbacks()))
     self.assertFalse(bmcutils.is_no_loopback(-10000))
Exemplo n.º 3
0
def check_ltl_incrementally(
        ltl_prop,
        bound=10,
        loop=utils.all_loopbacks(),
        one_problem=False,
):
    """
    Performs the same end to end LTL property verification as `check_ltl` but
    generates the problem /incrementally/ instead of doing it all at once.
    
    Concretely, this means that it does not compute the complete unrolling of 
    the transition relation :math:`[[M]]_{k}` up front but computes each unrolling
    step separately and adds it to a group of the incremental sat solver. 
    
    The bounded semantics conversion of `ltl_prop` is done the exact same way 
    as in `check_ltl`. So the real gain of calling this function resides in 
    the avoidance of the regeneration of the formula representing the unrolled
    transition relation for lengths < bound. (and thus in the reduction of the 
    size of the generated formula that needs to be solved).
    
    :param ltl_prop: the LTL property to be verified. This should be an instance
        of Prop similar to what you obtain querying PropDb 
        (:func:`pynusmv.glob.prop_database()`)
    :param bound: the bound of the problem, that is to say the maximum number of 
        times the problem will be unrolled. This parameter corresponds to the 
        value `k` used in the formal definitions of a bmc problem.
    :param loop: a loop definition. This is an integer value corresponding to 
        the moment in time where the loop might be starting (the parameter `l`
        in the formal definitions). However, this value is not as 'crude' as an
        absolute moment in time since it may indicate:
        
            - an absolute moment in time (obviously) when the value is positive
            - indicate a relative moment in time (when it is a negative number
              (for instance value -2 indicates that the loops are supposed to
              start 2 states ago)
            - that NO loop at all must be considered (ignore infinite behaviors)
              when this parameter takes the special value defined in 
              :func:`pynusmv.bmc.utils.no_loopback()`
            - that ALL possible loops in the model must be taken into account
              when this parameter takes the special value defined in
              :func:`pynusmv.bmc.utils.all_loopback()` (this is the default)
              
    :param one_problem: a flag indicating whether the problem should be verified
        for all possible execution lengths UP TO `bound` or if it should be 
        evaluated only for executions that have the exact length `bound`.
        By default this flag is OFF and all problem lengths up to `bound` are 
        verified.
    :raises NuSmvSatSolverError: when the verification could not be
        performed because of a problem related to the sat solver
        (solver could not be created)
    :raises ValueError: when the bound is infeasible (negative value) or when
        the loop and bound values are inconsistent (loop is greater than the
        bound but none of the special values described above)
    """
    utils.check_consistency(bound, loop)

    result = _bmc.Bmc_GenSolveLtlInc(ltl_prop._ptr, bound, loop,
                                     not one_problem)
    if result == 1:
        raise NuSmvSatSolverError("The sat solver could not be created")
Exemplo n.º 4
0
def check_ltl_incrementally(ltl_prop, 
                            bound=10, 
                            loop=utils.all_loopbacks(), 
                            one_problem=False, ):
    """
    Performs the same end to end LTL property verification as `check_ltl` but
    generates the problem /incrementally/ instead of doing it all at once.
    
    Concretely, this means that it does not compute the complete unrolling of 
    the transition relation [[M]]_{k} up front but computes each unrolling
    step separately and adds it to a group of the incremental sat solver. 
    
    The bounded semantics conversion of `ltl_prop` is done the exact same way 
    as in `check_ltl`. So the real gain of calling this function resides in 
    the avoidance of the regeneration of the formula representing the unrolled
    transition relation for lengths < bound. (and thus in the reduction of the 
    size of the generated formula that needs to be solved).
    
    :param ltl_prop: the LTL property to be verified. This should be an instance
        of Prop similar to what you obtain querying PropDb 
        (:see:`pynusmv.glob.prop_database())s
    :param bound: the bound of the problem, that is to say the maximum number of 
        times the problem will be unrolled. This parameter corresponds to the 
        value `k` used in the formal definitions of a bmc problem.
    :param loop: a loop definition. This is an integer value corresponding to 
        the moment in time where the loop might be starting (the parameter `l`
        in the formal definitions). However, this value is not as 'crude' as an
        absolute moment in time since it may indicate::
            - an absolute moment in time (obviously) when the value is positive
            - indicate a relative moment in time (when it is a negative number
              (for instance value -2 indicates that the loops are supposed to
              start 2 states ago)
            - that NO loop at all must be considered (ignore infinite behaviors)
              when this parameter takes the special value defined in 
              :see:`pynusmv.bmc.utils.no_loopback()`
            - that ALL possible loops in the model must be taken into account
              when this parameter takes the special value defined in
              :see:`pynusmv.bmc.utils.all_loopback()` (this is the default)
    :param one_problem: a flag indicating whether the problem should be verified
        for all possible execution lengths UP TO `bound` or if it should be 
        evaluated only for executions that have the exact length `bound`.
        By default this flag is OFF and all problem lengths up to `bound` are 
        verified.
    :raises NuSmvSatSolverError: when the verification could not be
        performed because of a problem related to the sat solver
        (solver could not be created)
    :raises ValueError: when the bound is infeasible (negative value) or when
        the loop and bound values are inconsistent (loop is greater than the
        bound but none of the special values described above)
    """
    utils.check_consistency(bound, loop)
    
    result = _bmc.Bmc_GenSolveLtlInc(ltl_prop._ptr,bound, loop, not one_problem)
    if result == 1:
        raise NuSmvSatSolverError("The sat solver could not be created")
Exemplo n.º 5
0
    def test_check_consistency(self):
        # when the bound is not meaningful
        with self.assertRaises(ValueError):
            bmcutils.check_consistency(-1, 2)

        # when the loop is greater than the bound
        with self.assertRaises(ValueError):
            bmcutils.check_consistency(1, 2)

        # unless it is a special value
        bmcutils.check_consistency(4, bmcutils.all_loopbacks())
        bmcutils.check_consistency(4, bmcutils.no_loopback())
Exemplo n.º 6
0
def generate_ltl_problem(fsm, prop_node, bound=10, loop=utils.all_loopbacks()):
    """
    Generates a (non-incremental) Be expression corresponding to the SAT problem
    denoted by :math:`[[fsm, prop\\_node]]_{bound}^{loop}`
    
    That is to say it generates the problem that combines both the formula and
    and the model to perform the verification. Put another way, this problem
    can be read as: 
    
    .. math::
    
        [[fsm]]_{bound} \\wedge \\neg ( (\\neg L_k \\wedge [[ \\neg prop\\_node]]_{k}) \\vee {}_{l}[[ \\neg prop\\_node]]_{k}^{l} )
     
    :param fsm: the BeFsm object that represents the model against which the 
        property will be verified. (if in doubt, it can be obtained via 
        :func:`pynusmv.bmc.glob.master_be_fsm()` )
    :param prop_node: the property for which to generate a verification problem
        represented in a 'node' format (subclass of :class:`pynusmv.node.Node`)
        which corresponds to the format obtained from the ast. (remark: if you
        need to manipulate [ie negate] the formula before passing it, it is
        perfectly valid to pass a node decorated by `Wff.decorate`).
    :param bound: the bound of the problem, that is to say the maximum number of 
        times the problem will be unrolled. This parameter corresponds to the 
        value `k` used in the formal definitions of a bmc problem.
    :param loop: a loop definition. This is an integer value corresponding to 
        the moment in time where the loop might be starting (the parameter `l`
        in the formal definitions). However, this value is not as 'crude' as an
        absolute moment in time since it may indicate:
        
            - an absolute moment in time (obviously) when the value is positive
            - indicate a relative moment in time (when it is a negative number
              (for instance value -2 indicates that the loops are supposed to
              start 2 states ago)
            - that NO loop at all must be considered (ignore infinite behaviors)
              when this parameter takes the special value defined in 
              :func:`pynusmv.bmc.utils.no_loopback()`
            - that ALL possible loops in the model must be taken into account
              when this parameter takes the special value defined in
              :func:`pynusmv.bmc.utils.all_loopback()` (this is the default)
              
    :return: a Be boolean expression representing the satisfiability problem of
        for the verification of this property.
    :raises ValueError: when the bound is infeasible (negative value) or when
        the loop and bound values are inconsistent (loop is greater than the
        bound but none of the special values described above)
    """
    utils.check_consistency(bound, loop)

    ltl_wff = utils.make_negated_nnf_boolean_wff(prop_node)
    be_ptr = _bmc.Bmc_Gen_LtlProblem(fsm._ptr, ltl_wff._ptr, bound, loop)
    return Be(be_ptr, fsm.encoding.manager)
Exemplo n.º 7
0
def generate_ltl_problem(fsm, prop_node, bound=10, loop=utils.all_loopbacks()):
    """
    Generates a (non-incremental) Be expression corresponding to the SAT problem
    denoted by [[fsm, prop_node]]_{bound}^{loop} 
    
    That is to say it generates the problem that combines both the formula and
    and the model to perform the verification. Put another way, this problem
    can be read as::
    
        [[fsm]]_{bound} & ! ( (!Lk & [[ ! prop_node]]_{k}) | _{l}[[ ! prop_node]]_{k}^{l} )
     
    :param fsm: the BeFsm object that represents the model against which the 
        property will be verified. (if in doubt, it can be obtained via 
        :see:`pynusmv.bmc.glob.master_be_fsm()` )
    :param prop_node: the property for which to generate a verification problem
        represented in a 'node' format (subclass of :see::class:`pynusmv.node.Node`)
        which corresponds to the format obtained from the ast. (remark: if you
        need to manipulate [ie negate] the formula before passing it, it is
        perfectly valid to pass a node decorated by `Wff.decorate`).
    :param bound: the bound of the problem, that is to say the maximum number of 
        times the problem will be unrolled. This parameter corresponds to the 
        value `k` used in the formal definitions of a bmc problem.
    :param loop: a loop definition. This is an integer value corresponding to 
        the moment in time where the loop might be starting (the parameter `l`
        in the formal definitions). However, this value is not as 'crude' as an
        absolute moment in time since it may indicate::
            - an absolute moment in time (obviously) when the value is positive
            - indicate a relative moment in time (when it is a negative number
              (for instance value -2 indicates that the loops are supposed to
              start 2 states ago)
            - that NO loop at all must be considered (ignore infinite behaviors)
              when this parameter takes the special value defined in 
              :see:`pynusmv.bmc.utils.no_loopback()`
            - that ALL possible loops in the model must be taken into account
              when this parameter takes the special value defined in
              :see:`pynusmv.bmc.utils.all_loopback()` (this is the default)
    :return: a Be boolean expression representing the satisfiability problem of
        for the verification of this property.
    :raises ValueError: when the bound is infeasible (negative value) or when
        the loop and bound values are inconsistent (loop is greater than the
        bound but none of the special values described above)
    """
    utils.check_consistency(bound, loop)
    
    ltl_wff = utils.make_negated_nnf_boolean_wff(prop_node)
    be_ptr  = _bmc.Bmc_Gen_LtlProblem(fsm._ptr, ltl_wff._ptr, bound, loop)
    return Be(be_ptr, fsm.encoding.manager)
Exemplo n.º 8
0
def bounded_semantics(fsm, prop_node, bound=10, loop=utils.all_loopbacks()):
    """
    Generates a Be expression corresponding to the bounded semantics of the
    given LTL formula. It combines the bounded semantics of the formula when 
    there is a loop and when there is none with the loop condition.
    
    In the literature, the resulting formula would be denoted as 
    
    .. math::
    
       [[f]]_{k} :=
           (\\neg L_{k} \\wedge [[f]]^{0}_{k} ) \\vee (\\bigvee_{j=l}^{k} {}_{j}L_{k} \\wedge {}_{j}[[f]]_{k}^{0})
        
    where l is used to denote `loop`, f for `prop_node` and k for the `bound`.
        
    .. note::
    
        Fairness is taken into account in the generation of the resulting 
        expression
        
    :param fsm: the fsm against which the formula will be evaluated. It is not
        directly relevant to the generation of the formula for `prop_node` but
        is used to determine to generate fairness constraints for this model
        which are combined with `prop_node` constraint.
    :param prop_node: the property for which to generate a verification problem
        represented in a 'node' format (subclass of :class:`pynusmv.node.Node`)
        which corresponds to the format obtained from the ast.(remark: if you
        need to manipulate [ie negate] the formula before passing it, it is
        perfectly valid to pass a node decorated by `Wff.decorate`).
    :param bound: the bound of the problem, that is to say the maximum number of 
        times the problem will be unrolled. This parameter corresponds to the 
        value `k` used in the formal definitions of a bmc problem.
    :param optimized: a flag indicating whether or not the use of the 
        optimisation for formulas of depth 1 is desired.
        
    :return: a boolean expression corresponding to the bounded semantics of 
        `prop_node`
    :raises ValueError: when the bound is infeasible (negative value) or when
        the loop and bound values are inconsistent (loop is greater than the
        bound but none of the special values described above)
    """
    utils.check_consistency(bound, loop)

    ltl_wff = utils.make_nnf_boolean_wff(prop_node)
    be_ptr = _bmc.Bmc_Tableau_GetLtlTableau(fsm._ptr, ltl_wff._ptr, bound,
                                            loop)
    return Be(be_ptr, fsm.encoding.manager)
Exemplo n.º 9
0
def bounded_semantics(fsm, prop_node, bound=10, loop=utils.all_loopbacks()):
    """
    Generates a Be expression corresponding to the bounded semantics of the
    given LTL formula. It combines the bounded semantics of the formula when 
    there is a loop and when there is none with the loop condition.
    
    In the literature, the resulting formula would be denoted as .. math::
    
       [[f]]_{k} :=
           (! L_{k} & [[f]]^{0}_{k} ) \vee 
           (\bigvee_{j=l}^{k} _{j}L_{k} \wedge _{j}[[f]]_{k}^{0})
        
    where l is used to denote `loop`, f for `prop_node` and k for the `bound`.
        
    .. note::
    
        Fairness is taken into account in the generation of the resulting 
        expression
        
    :param fsm: the fsm against which the formula will be evaluated. It is not
        directly relevant to the generation of the formula for `prop_node` but
        is used to determine to generate fairness constraints for this model
        which are combined with `prop_node` constraint.
    :param prop_node: the property for which to generate a verification problem
        represented in a 'node' format (subclass of :see::class:`pynusmv.node.Node`)
        which corresponds to the format obtained from the ast.(remark: if you
        need to manipulate [ie negate] the formula before passing it, it is
        perfectly valid to pass a node decorated by `Wff.decorate`).
    :param bound: the bound of the problem, that is to say the maximum number of 
        times the problem will be unrolled. This parameter corresponds to the 
        value `k` used in the formal definitions of a bmc problem.
    :param optimized: a flag indicating whether or not the use of the 
        optimisation for formulas of depth 1 is desired.
        
    :return: a boolean expression corresponding to the bounded semantics of 
        `prop_node`
    :raises ValueError: when the bound is infeasible (negative value) or when
        the loop and bound values are inconsistent (loop is greater than the
        bound but none of the special values described above)
    """
    utils.check_consistency(bound, loop)
    
    ltl_wff = utils.make_nnf_boolean_wff(prop_node)
    be_ptr  = _bmc.Bmc_Tableau_GetLtlTableau(fsm._ptr, ltl_wff._ptr, bound,loop)
    return Be(be_ptr, fsm.encoding.manager)
Exemplo n.º 10
0
def check_ltl(ltl_prop, 
              bound=10, 
              loop=utils.all_loopbacks(), 
              one_problem=False, 
              solve=True, 
              dump_type=utils.DumpType.NONE, 
              fname_template=None):
    """
    High level function that performs the verification of an LTL property 
    (LTLSPEC property as obtained from the :class:`pynusmv.prop.PropDb`).
    
    This function performs an end to end verification of the given LTL property
    and prints the outcome (satisfaction or violation result) to standard output
    
    Formally, it tries to determine if the problem [[M,f]]_{k} is satisfiable. 
    This problem is generated as  
        [[M]]_{k} & ! ( (!Lk & [[ltl_prop]]_{k}) | _{l}[[ltl_prop]]_{k}^{l} )
    
    :param ltl_prop: the LTL property to be verified. This should be an instance
        of Prop similar to what you obtain querying PropDb 
        (:see:`pynusmv.glob.prop_database())s
    :param bound: the bound of the problem, that is to say the maximum number of 
        times the problem will be unrolled. This parameter corresponds to the 
        value `k` used in the formal definitions of a bmc problem.
    :param loop: a loop definition. This is an integer value corresponding to 
        the moment in time where the loop might be starting (the parameter `l`
        in the formal definitions). However, this value is not as 'crude' as an
        absolute moment in time since it may indicate::
            - an absolute moment in time (obviously) when the value is positive
            - indicate a relative moment in time (when it is a negative number
              (for instance value -2 indicates that the loops are supposed to
              start 2 states ago)
            - that NO loop at all must be considered (ignore infinite behaviors)
              when this parameter takes the special value defined in 
              :see:`pynusmv.bmc.utils.no_loopback()`
            - that ALL possible loops in the model must be taken into account
              when this parameter takes the special value defined in
              :see:`pynusmv.bmc.utils.all_loopback()` (this is the default)
    :param one_problem: a flag indicating whether the problem should be verified
        for all possible execution lengths UP TO `bound` or if it should be 
        evaluated only for executions that have the exact length `bound`.
        By default this flag is OFF and all problem lengths up to `bound` are 
        verified.
    :param solve: a flag indicating whether or not the verification should 
        actually be performed. (when this flag is turned off, no sat solver is 
        not used to perform the bmc verification and the function can serve to
        simply dump the ltl problem to files). 
    :param dump_type: the format in which to perform a dump of the generated sat
        problem (ie dimacs). By default, this parameter takes the value 
        :see:`pynusmv.bmc.utils.DumpType.NONE` which means that the problem is
        not dumped to file. Should you want to change this behavior, then this
        parameter is used to specify a file format in conjunction with 
        `fname_template` which is used to specify the name of the location where
        the file will be output.
    :param fname_template: the file name template of the location where to output
        the dump file.
    :raises NuSmvSatSolverError: when the verification could not be
        performed because of a problem related to the sat solver
        (solver could not be created) 
    :raises ValueError: when the bound is infeasible (negative value) or when
        the loop and bound values are inconsistent (loop is greater than the
        bound but none of the special values described above)
    """
    utils.check_consistency(bound, loop)
    
    if dump_type is not utils.DumpType.NONE and fname_template is None:
        raise ValueError("a filename must be specified when dump_type is set")
    
    if fname_template is not None and dump_type is utils.DumpType.NONE:
        raise ValueError("a filename is specified but dump_type is not set")
    
    result = _bmc.Bmc_GenSolveLtl(ltl_prop._ptr, 
                                  bound, loop, 
                                  not one_problem, 
                                  solve, 
                                  dump_type, 
                                  fname_template)
    if result == 1:
        raise NuSmvSatSolverError("The sat solver could not be created")
Exemplo n.º 11
0
def check_ltl(ltl_prop,
              bound=10,
              loop=utils.all_loopbacks(),
              one_problem=False,
              solve=True,
              dump_type=utils.DumpType.NONE,
              fname_template=None):
    """
    High level function that performs the verification of an LTL property 
    (LTLSPEC property as obtained from the :class:`pynusmv.prop.PropDb`).
    
    This function performs an end to end verification of the given LTL property
    and prints the outcome (satisfaction or violation result) to standard output
    
    Formally, it tries to determine if the problem :math:`[[M,f]]_{k}` is satisfiable. 
    This problem is generated as 
    
    .. math::
    
        [[M]]_{k} \\wedge \\neg ( (\\neg L_{k} \\wedge [[ltl\\_prop]]_{k}) \\vee {}_{l}[[ltl\\_prop]]_{k}^{l} )
    
    :param ltl_prop: the LTL property to be verified. This should be an instance
        of Prop similar to what you obtain querying PropDb 
        (:func:`pynusmv.glob.prop_database()`)
    :param bound: the bound of the problem, that is to say the maximum number of 
        times the problem will be unrolled. This parameter corresponds to the 
        value `k` used in the formal definitions of a bmc problem.
    :param loop: a loop definition. This is an integer value corresponding to 
        the moment in time where the loop might be starting (the parameter `l`
        in the formal definitions). However, this value is not as 'crude' as an
        absolute moment in time since it may indicate:
        
            - an absolute moment in time (obviously) when the value is positive
            - indicate a relative moment in time (when it is a negative number
              (for instance value -2 indicates that the loops are supposed to
              start 2 states ago)
            - that NO loop at all must be considered (ignore infinite behaviors)
              when this parameter takes the special value defined in 
              :func:`pynusmv.bmc.utils.no_loopback()`
            - that ALL possible loops in the model must be taken into account
              when this parameter takes the special value defined in
              :func:`pynusmv.bmc.utils.all_loopback()` (this is the default)
              
    :param one_problem: a flag indicating whether the problem should be verified
        for all possible execution lengths UP TO `bound` or if it should be 
        evaluated only for executions that have the exact length `bound`.
        By default this flag is OFF and all problem lengths up to `bound` are 
        verified.
    :param solve: a flag indicating whether or not the verification should 
        actually be performed. (when this flag is turned off, no sat solver is 
        not used to perform the bmc verification and the function can serve to
        simply dump the ltl problem to files). 
    :param dump_type: the format in which to perform a dump of the generated sat
        problem (ie dimacs). By default, this parameter takes the value 
        :data:`pynusmv.bmc.utils.DumpType.NONE` which means that the problem is
        not dumped to file. Should you want to change this behavior, then this
        parameter is used to specify a file format in conjunction with 
        `fname_template` which is used to specify the name of the location where
        the file will be output.
    :param fname_template: the file name template of the location where to output
        the dump file.
    :raises NuSmvSatSolverError: when the verification could not be
        performed because of a problem related to the sat solver
        (solver could not be created) 
    :raises ValueError: when the bound is infeasible (negative value) or when
        the loop and bound values are inconsistent (loop is greater than the
        bound but none of the special values described above)
    """
    utils.check_consistency(bound, loop)

    if dump_type is not utils.DumpType.NONE and fname_template is None:
        raise ValueError("a filename must be specified when dump_type is set")

    if fname_template is not None and dump_type is utils.DumpType.NONE:
        raise ValueError("a filename is specified but dump_type is not set")

    result = _bmc.Bmc_GenSolveLtl(ltl_prop._ptr, bound, loop, not one_problem,
                                  solve, dump_type, fname_template)
    if result == 1:
        raise NuSmvSatSolverError("The sat solver could not be created")