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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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
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)
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)
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)
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
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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
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