Пример #1
0
 def init(self, time):
     """
     Retrieves the init states and compiles them into a BE at time `time`
     
     :param time: the time at which to consider the init.
     :return: a Be corresponding to the init states at time `time`
     :raises ValueError: if the specified time is negative.
     """
     if time < 0:
         raise ValueError("Time cannot be negative")
     if time == 0:
         return Be(_bmc.Bmc_Model_GetInit0(self._fsm._ptr),
                   self._fsm.encoding.manager)
     else:
         return Be(_bmc.Bmc_Model_GetInitI(self._fsm._ptr, time),
                   self._fsm.encoding.manager)
Пример #2
0
 def shift_curr_to_next(self, expr):
     """
     Returns an *untimed* Be expression corresponding to `expr` in which all 
     variables v have been shifted to next(v). Example:
         
         v == True & w == False becomes next(v) == True & next(w) == False
     
     .. note::
         Despite the fact that this operation performs a shift of the 
         variables it remains in the *untimed* block. (next of untimed vars 
         are also untimed vars). Hence the returned expression is an *untimed*
         expression. Therefore, in order to use it in (ie a transition 
         relation unrolling), it must be shifted again to a time block using
         one of :
         
             - :meth:`shift_to_time`
             - :meth:`shift_to_times`
             - :func:`or_interval`
             - :func:`and_interval`
     
     .. warning:: 
         argument 'expr' must contain only untimed current state variables 
         and untimed frozen variables, otherwise results will be 
         unpredictable. Unfortunately, there is no way to preemptively check
         that a given expression contains only untimed variable so it is up
         to the programmer to make sure he calls this method in an 
         appropriate way.
     
     :param expr: the expression to shift
     :return: an expression equivalent to expr but with the variables shifted
         to the next-state portion of the block.
     """
     ptr = _be.BeEnc_shift_curr_to_next(self._ptr, expr._ptr)
     return Be(ptr, self.manager)
Пример #3
0
def fairness_constraint(fsm, k, l):
    """
    Computes a step of the constraint to be added to the loop side of the BE 
    when one wants to take fairness into account for the case where we consider 
    the existence of a k-l loop (between k and l obviously).
    
    .. note::
    
        This code was first implemented in Python with PyNuSMV but, since
        the Python implementation proved to be a huge performance bottleneck
        (profiling revealed that useless memory management was dragging the
        whole system behind), it has been translated back to C to deliver much
        better perf. results.
    
    :param fsm: the fsm whose transition relation must be unrolled
    :param k: the maximum (horizon/bound) time of the problem
    :param l: the time where the loop starts 
    :return: a step of the fairness constraint to force fair execution on the
        k-l loop.
    :raises ValueError: when the given `k` and `l` are not consistent with each 
        other or when the bound `k` is negative.
    """
    check_consistency(k, l)

    # Note: this code was first implemented in Python with PyNuSMV but, since
    #       the Python implementation proved to be a huge performance bottleneck
    #       (profiling revealed that useless memory management was dragging the
    #       whole system behind).
    return Be(_lower.fairness_constraint(fsm._ptr, k, l), fsm.encoding.manager)
Пример #4
0
 def shift_to_times(self, expr, curr_time, frozen_time, ivar_time, next_time):
     """
     Returns a *timed* Be expression corresponding to `expr` in which:
     
         - all the current state variables are shifted to time `curr_time`
         - all the frozen variables are shifted to time `frozen_time`
         - all the input variables are shifted to time `ivar_time`
         - all the next state variables are shifted to time `next_time`
         
     .. warning:: 
         argument 'expr' must contain only untimed current state variables 
         and untimed frozen variables, otherwise results will be 
         unpredictable. Unfortunately, there is no way to preemptively check
         that a given expression contains only untimed variable so it is up
         to the programmer to make sure he calls this method in an 
         appropriate way. 
     
     :param expr: the expression to shift
     :param curr_time: the time to shift the current variables to
     :param frozen_time: the time to shift the frozen variables to
     :param ivar_time: the time to shift the input variables to
     :param next_time: the time to shift the next state variables to.
     :return: an expression equivalent to `expr` but with the sets of 
         variables shifted to the time blocks.
     """
     ptr = _be.BeEnc_untimed_expr_to_times(self._ptr, 
                                           expr._ptr, 
                                           curr_time,
                                           frozen_time, 
                                           ivar_time, 
                                           next_time)
     return Be(ptr, self.manager)
Пример #5
0
    def invar_dual_forward_unrolling(self, invarspec, i):
        """
        Performs one step in the unrolling of the invarspec property.
        
        In terms of pseudo code, this corresponds to::
        
            if i == 0 : 
                return Invar[0]
            else
                return Trans[i-1] & Invar[i] & Property[i-1]
        
        .. note:: 
            
            this is specific to the INVARSPEC verification
            
        :param invarspec: a booleanized, NNF formula representing an invariant 
            property.
        :param i: the time step for which the unrolling is generated.
        :return: Trans[i-1] & Invar[i] & Property[i-1]
        :raise ValueError: in case the given parameters are incorrect.
        """
        if invarspec is None:
            raise ValueError("an invarspec is expected")
        if i < 0:
            raise ValueError("Time must be a non negative integer")

        return Be(
            _bmc.Bmc_Model_Invar_Dual_forward_unrolling(
                self._fsm._ptr, invarspec._ptr, i), self._fsm.encoding.manager)
Пример #6
0
def bounded_semantics_without_loop_at_offset(fsm, formula, time, bound,
                                             offset):
    """
    Generates the Be :math:`[[formula]]^{time}_{bound}` corresponding to the bounded semantic 
    of `formula` when there is no loop on the path but encodes it with an `offset` long shift 
    in the timeline of the encoder.

    .. note::
    
        This code was first implemented in Python with PyNuSMV but, since
        the Python implementation proved to be a huge performance bottleneck
        (profiling revealed that useless memory management was dragging the
        whole system behind), it has been translated back to C to deliver much
        better perf. results.

    .. note:: 

        This function plays the same role as `bounded_semantics_without_loop` but allows to 
        position the time blocks at some place we like in the encoder timeline. This is mostly
        helpful if you want to devise verification methods that need to have multiple parallel
        verifications. (ie. diagnosability).

        Note however, that the two implementations are different.

    .. warning::

        So far, the only supported temporal operators are F, G, U, R, X

    :param fsm: the BeFsm for which the property will be verified. Actually, it is only used to 
        provide the encoder used to assign the variables to some time blocks. The api was kept 
        this ways to keep uniformity with its non-offsetted counterpart.
    :param formula: 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 time: the logical time at which the semantics is to be evaluated. (Leave out the offset for
        this param. If you intend the 3rd state of a trace, say time 2).
    :param bound: the logical time bound to the problem. (Leave out the offset for this param: if you
        intend to have a problem with at most 10 steps, say bound=10)
    :param offset: the time offset in the encoding block where the sem of this formula will be 
        generated.
    :return: a Be corresponding to the semantics of `formula` at `time` for a problem with a maximum
        of `bound` steps encoded to start at time `offset` in the `fsm` encoding timeline.
    """
    if time < 0:
        raise ValueError("Time must be a positive integer")
    if bound < 0:
        raise ValueError("Bound must be a positive integer")
    if offset < 0:
        raise ValueError("The offset must be a positive integer")

    # Note: this code was first implemented in Python with PyNuSMV but, since
    #       the Python implementation proved to be a huge performance bottleneck
    #       (profiling revealed that useless memory management was dragging the
    #       whole system behind).
    _ptr = _lower.sem_no_loop_offset(fsm._ptr, formula._ptr, time, bound,
                                     offset)
    return Be(_ptr, fsm.encoding.manager)
Пример #7
0
    def be_index_to_var(self, index):
        """
        Retrieves the BE variable (expression) corresponding to the given index
        (index may be retrieved from the literals managed by this manager)

        :param index: the index
        :return: the be corresponding to this index
        """
        return Be(_be.Be_Index2Var(self._ptr, index), self)
Пример #8
0
 def path(self, k, with_init=True):
     """
     Returns the path for the model from 0 to k. If the flag `with_init` is
     off, only the invariants are taken into account (and no init) otherwise
     both are taken into account.
     
     :param k: the end time
     :param with_init: a flag indicating whether or not to consider the init
     :retunr: a Be representing the paths in the model from times 0 to `k`.
     :raises ValueError: if the specified time k is negative.
     """
     if k < 0:
         raise ValueError("time must be positive")
     if with_init:
         return Be(_bmc.Bmc_Model_GetPathWithInit(self._fsm._ptr, k),
                   self._fsm.encoding.manager)
     else:
         return Be(_bmc.Bmc_Model_GetPathNoInit(self._fsm._ptr, k),
                   self._fsm.encoding.manager)
Пример #9
0
 def trans(self, time):
     """
     Retrieves the trans and compiles them into a BE at the given time.
     
     :param time: the time at which to consider the trans.
     :return: a Be corresponding to the trans at time `time`
     :raises ValueError: if the specified time is negative.
     """
     if time < 0:
         raise ValueError("Time cannot be negative")
     return Be(_bmc.Bmc_Model_GetTransAtTime(self._fsm._ptr, time),
               self._fsm.encoding.manager)
Пример #10
0
def bounded_semantics_all_loops(fsm, prop_node, bound, loop, optimized=True):
    """
    Generates a Be expression corresponding to the bounded semantics of the
    given LTL formula in the case where the formula is evaluated against a path 
    that contains a loop at any of the positions in the range [loop; bound]
    
    In the literature, the resulting formula would be denoted as 
    
    .. math::
    
        \\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` in the case where there is may be a loop anywhere on the 
        path between the positions `loop` and `bound`
    :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)

    if optimized and ltl_wff.depth == 1 and len(fsm.fairness_list) == 0:
        return bounded_semantics_all_loops_optimisation_depth1(
            fsm, prop_node, bound)
    else:
        be_ptr = _bmc.Bmc_Tableau_GetAllLoops(fsm._ptr, ltl_wff._ptr, bound,
                                              loop)
        return Be(be_ptr, fsm.encoding.manager)
Пример #11
0
 def boolean_expression(self):
     """
     :return: the boolean expression :class:`Be` used to encode this variable 
     """
     ptr = None
     if self.is_untimed:
         ptr = _be.BeEnc_index_to_var(self.encoding._ptr, self.index)
     else:
         time        = self.time
         untimed_idx = _be.BeEnc_index_to_untimed_index(self.encoding._ptr, self.index) 
         ptr = _be.BeEnc_index_to_timed(self.encoding._ptr, untimed_idx, time)
     mgr = self.encoding.manager
     return Be(ptr, mgr)
Пример #12
0
 def trans(self):
     """
     The boolean expression representing the transition relation of the FSM
     
     .. note::
     
         Transition expression shifted at time zero is what brings you to 
         state one. Hence::
         
             shift_to_time(init, 0) & shift_to_time(trans, 0) == STATE_1 
     """
     _expr = _be.BeFsm_get_trans(self._ptr)
     return Be(_expr, self.encoding.manager) if _expr is not None else None
Пример #13
0
def apply_inlining(be_expr):
    """
    Performs the inlining of `be_expr` (same effect as :func:`pynusmv.be.expression.Be.inline`)
    but uses the global user's settings in order to determine the value that 
    should be given to the `add_conj` parameter.
    
    :param be_expr: a Be expression (:class:`pynusmv.be.expression.Be`) that 
        needs to be inlined.
    :return: a boolean expression (:class:`pynusmv.be.expression.Be`) 
        equivalent to `be_expr` but inlined according to the user's preferences.
    """
    ptr = _bmc.Bmc_Utils_apply_inlining(be_expr._manager._ptr, be_expr._ptr)
    return Be(ptr, be_expr._manager)
Пример #14
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)
Пример #15
0
 def or_interval(self, expr, start, end):
     """
     This method is an utility meant to let you easily compute the 
     disjunction of the given `expr` shifted at all the times in the interval
     [start, end]. Mathematically, this corresponds to the following formula:
     
     .. math:: 
         \\underset{t=start}{\\overset{t=end}{\\bigvee}} shift\\_to\\_time(expr, t)
     """
     ptr = _be.BeEnc_untimed_to_timed_or_interval(self._ptr, 
                                                   expr._ptr, 
                                                   start, 
                                                   end)
     return Be(ptr, self.manager)
Пример #16
0
 def _fairness_conversion(self, fairness):
     """
     Converts the given `fairness` into a Be representation.
     
     .. note::
         This function is present for purely technical reason: under the 
         hood, NuSMV encodes the fairness list as a NodeList however the
         'car' (value) of these nodes is nothing that can be understood 
         AST-wise. Indeed, the values are opaque pointers (be_ptr that is 
         to say void*) to a structure representing a Be. 
     """
     beptr = _be.node_ptr_to_be_ptr(_node.car(fairness._ptr))
     bexpr = Be(beptr, self.encoding.manager)
     return bexpr
Пример #17
0
 def unrolling_fragment(self, i):
     """
     Generates the ith fragment of the transition relation unrolling. 
     (useful for incremental algorithms). Concretely, unrolls the transition 
     relation from i-1 to i
     
     :param i: the time index of the fragment to generate. 
     :return: a Be expression corresponding to the ith unrolling of the 
         transition relation.
     :raise ValueError: when `i` is negative
     """
     if i < 0:
         raise ValueError("time indices start at 0")
     ptr = _bmc.Bmc_Gen_UnrollingFragment(self._fsm._ptr, i)
     return Be(ptr, self._fsm.encoding.manager)
Пример #18
0
def bounded_semantics_without_loop(fsm, prop_node, bound):
    """
    Generates a Be expression corresponding to the bounded semantics of the
    given LTL formula in the case where the formula is evaluated against paths 
    that contain no loop and have a maximal length of `bound`.
    
    .. note::
    
        This function proves to be very useful since the bounded semantics of
        LTL depends on two cases: (a) when the encountered path contains loops
        (in that case the unbounded semantics of LTL can be maintained since
        there exists infinite paths) and (b) the case where there are no 
        possible loops (and the semantics has to be altered slightly).
        
        In the literature, the expression generated by this function is denoted
        :math:`[[f]]^{0}_{k}`
        
        With f used to represent the formula `prop_node`, and k for `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.
        
    :return: a boolean expression corresponding to the bounded semantics of 
        `prop_node` in the case where there is no loop on the path.
    :raises ValueError: when the specified problem bound is negative
    """
    if bound < 0:
        raise ValueError("The problem bound may not be negative")
    ltl_wff = utils.make_nnf_boolean_wff(prop_node)
    be_ptr = _bmc.Bmc_Tableau_GetNoLoop(fsm._ptr, ltl_wff._ptr, bound)
    return Be(be_ptr, fsm.encoding.manager)
Пример #19
0
 def unrolling(self, j, k):
     """
     Unrolls the transition relation from j to k, taking into account of 
     invars.
     
     :param j: the start time
     :param k: the end time
     :return: a Be representing the unrolling of the fsm from time i to k
     :raises ValueError: if one of the specified times (k,j) is negative and 
         when k < j
     """
     if j < 0 or k < 0:
         raise ValueError("time must be positive")
     if k < j:
         raise ValueError(
             "unrolling can only increase the amount of constraints")
     return Be(_bmc.Bmc_Model_GetUnrolling(self._fsm._ptr, j, k),
               self._fsm.encoding.manager)
Пример #20
0
def apply_inlining_for_incremental_algo(be_expr):
    """
    Performs the inlining of `be_expr` in a way that guarantees soundness of
    incremental algorithms. 
    
    .. note::
        
        Calling this function is strictly equivalent to calling 
        `be_expr.inline(True)`.
    
    :param be_expr: a Be expression (:class:`pynusmv.be.expression.Be`) that 
        needs to be inlined.
    :return: a boolean expression (:class:`pynusmv.be.expression.Be`) 
        equivalent to `be_expr` but inlined according to the user's preferences.
    """
    ptr = _bmc.Bmc_Utils_apply_inlining4inc(be_expr._manager._ptr,
                                            be_expr._ptr)
    return Be(ptr, be_expr._manager)
Пример #21
0
def bounded_semantics_single_loop(fsm, prop_node, bound, loop):
    """
    Generates a Be expression corresponding to the bounded semantics of the
    given LTL formula in the case where the formula is evaluated against a path 
    that contains one single loop starting at position `loop`.
    
    In the literature, the resulting formula would be denoted as :math:`{}_{l}L_{k} \\wedge {}_{l}[[f]]_{k}^{0}`
        
    where l is used to denote `loop`, f for `prop_node` and k for the `bound`.
    
    In other words, the generated boolean expression is the conjunction of the
    constraint imposing that there be a k-l loop from `bound` to `loop` and that
    the formula is evaluated at time 0 out of `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.
        
    :return: a boolean expression corresponding to the bounded semantics of 
        `prop_node` in the case where there is a loop from bound to loop 
    :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_GetSingleLoop(fsm._ptr, ltl_wff._ptr, bound,
                                            loop)
    return Be(be_ptr, fsm.encoding.manager)
Пример #22
0
 def fairness(self, k, l):
     """
     Generates and returns an expression representing all fairnesses in a 
     conjunctioned form.
     
     :param k: the maximum length of the considered problem
     :param l: the time when a loop may start
     
     :return:  an expression representing all fairnesses in a conjunctioned form.
     :raises ValueError: when the k and l parameters are incorrect (namely, when
         one says the loop must start after the problem bound).
     """
     if k < 0:
         raise ValueError("time (k) must be positive")
     if l >= k:
         raise ValueError(
             "loop may not start after the problem bound hence l<k")
     return Be(_bmc.Bmc_Model_GetFairness(self._fsm._ptr, k, l),
               self._fsm.encoding.manager)
Пример #23
0
def generate_invar_problem(be_fsm, prop_node):
    """
    Builds and returns the invariant problem of the given propositional formula

    Concretely, this is the negation of (which needs to be satisfiable):
    
    .. math::
    
        (I0 \\implies P0) \\wedge \\left( \\left(P0 \\wedge R01\\right) \\implies P1 \\right)
        
    :param be_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`).
    :return: the invariant problem of the given propositional formula
    """
    ptr = _bmc.Bmc_Gen_InvarProblem(be_fsm._ptr, prop_node._ptr)
    return Be(ptr, be_fsm.encoding.manager)
Пример #24
0
def generate_base_step(be_fsm, prop_node):
    """
    Builds and returns the boolean expression corresponding to the base step
    of the invariant problem to be generated for the given invar problem.

    Concretely, this is::
        
        I0 -> P0, where I0 is the init and invar at time 0, 
                  and   P0 is the given formula  at time 0
        
    :param be_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`).
    :return: the invariant problem of the given propositional formula
    """
    ptr = _bmc.Bmc_Gen_InvarBaseStep(be_fsm._ptr, prop_node._ptr)
    return Be(ptr, be_fsm.encoding.manager)
Пример #25
0
 def shift_to_time(self, expr, time):
     """
     Returns a *timed* Be expression corresponding to `expr` in which all 
     variables v have been shifted to the given `time` block. Natually, the
     variables of the `next` sub-block are shifted to time t+1 (which 
     corresponds to what one would intuitively expect). 
         
     .. warning:: 
         argument 'expr' must contain only untimed current state variables 
         and untimed frozen variables, otherwise results will be 
         unpredictable. Unfortunately, there is no way to preemptively check
         that a given expression contains only untimed variable so it is up
         to the programmer to make sure he calls this method in an 
         appropriate way. 
     
     :param expr: the expression to shift
     :param time: the time to shift the expression to
     :return: an expression equivalent to `expr` but with the variables 
         shifted to the given `time` block.
     """
     ptr = _be.BeEnc_untimed_expr_to_timed(self._ptr, expr._ptr, time)
     return Be(ptr, self.manager)
Пример #26
0
def loop_condition(enc, k, l):
    """
    This function generates a Be expression representing the loop condition
    which is necessary to determine that k->l is a backloop.
    
    Formally, the returned constraint is denoted :math:`{}_{l}L_{k}`
    
    Because the transition relation is encoded in Nusmv as formula (and not as
    a relation per-se), we determine the existence of a backloop between 
    l < k and forall var, var(i) == var(k)
     
    That is to say: if it is possible to encounter two times the same state
    (same state being all variables have the same value in both states) we know
    there is a backloop on the path
    
    .. note::
    
        This code was first implemented in Python with PyNuSMV but, since
        the Python implementation proved to be a huge performance bottleneck
        (profiling revealed that useless memory management was dragging the
        whole system behind), it has been translated back to C to deliver much
        better perf. results.
    
    :param fsm: the fsm on which the condition will be evaluated
    :param k: the highest time
    :param l: the time where the loop is assumed to start
    :return: a Be expression representing the loop condition that verifies that
        k-l is a loop path.
    :raises ValueError: when the given `k` and `l` are not consistent with each 
        other or when the bound `k` is negative.
    """
    check_consistency(k, l)

    # Note: this code was first implemented in Python with PyNuSMV but, since
    #       the Python implementation proved to be a huge performance bottleneck
    #       (profiling revealed that useless memory management was dragging the
    #       whole system behind).
    return Be(_lower.loop_condition(enc._ptr, k, l), enc.manager)
Пример #27
0
def bounded_semantics_all_loops_optimisation_depth1(fsm, prop_node, bound):
    """
    Generates a Be expression corresponding to the bounded semantics of the
    given LTL formula in the case where the formula is evaluated against a path 
    that contains a loop at any of the positions in the range [0; bound] and 
    *the 'depth'(:attr:`pynusmv.wff.Wff.depth`) of the formula is 1 and no fairness 
    constraint comes into play*.
    
    .. note::
    
        Unless you know precisely why you are using this function, it is 
        probably safer to just use bounded_semantics_all_loops with the 
        optimized flag turned on.
            
    :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.
        
    :return: a boolean expression corresponding to the bounded semantics of 
        `prop_node` in the case where there is may be a loop anywhere on the 
        path between the positions `loop` and `bound` and the formula has a 
        depth of exactly one.
    :raises ValueError: when the specified propblem bound is negative
    """
    if bound < 0:
        raise ValueError("The problem bound may not be negative")
    ltl_wff = utils.make_nnf_boolean_wff(prop_node)
    be_ptr = _bmc.Bmc_Tableau_GetAllLoopsDepth1(fsm._ptr, ltl_wff._ptr, bound)
    return Be(be_ptr, fsm.encoding.manager)
Пример #28
0
 def init(self):
     """The BE representing the initial states of this FSM"""
     _expr = _be.BeFsm_get_init(self._ptr)
     return Be(_expr, self.encoding.manager) if _expr is not None else None
Пример #29
0
 def invariants(self):
     """The boolean expression representing the invariants of this FSM"""
     _expr = _be.BeFsm_get_invar(self._ptr)
     return Be(_expr, self.encoding.manager) if _expr is not None else None