Example #1
0
def encode_variables_for_layers(layers=None, init=False):
    """
    Encode the BDD variables of the given layers and store them in global data
    structures.

    :param layers: the set of layers variables to encode
    :type layers: :class:`set`
    :param bool init: whether or not initialize the global encodings

    .. warning: Global encodings should be initialized only once, otherwise,
                NuSMV quits unexpectingly. Note that :func:`encode_variables`
                initializes them, and should be called before any call to
                this function.

    """
    if init:
        nsenc.Enc_init_bool_encoding()

    # See to understand why setting a default set value is not a good idea
    # http://pylint-messages.wikidot.com/messages:w0102
    layers = layers or {"model"}

    bool_enc = nsenc.Enc_get_bool_encoding()
    base_enc = nsboolenc.boolenc2baseenc(bool_enc)
    for layer in layers:
        nsbaseenc.BaseEnc_commit_layer(base_enc, layer)

    if init:
        nsenc.Enc_init_bdd_encoding()
    bdd_enc = nsenc.Enc_get_bdd_encoding()
    base_enc = nsbddenc.bddenc2baseenc(bdd_enc)
    for layer in layers:
        nsbaseenc.BaseEnc_commit_layer(base_enc, layer)
Example #2
0
    def test_create_trans_counters_assign(self):

        fsm = self.model("tests/pynusmv/models/counters-assign.smv")

        c1c0bdd = evalSexp(fsm, "c1.c = 0")
        c2c0bdd = evalSexp(fsm, "c2.c = 0")
        c1c1bdd = evalSexp(fsm, "c1.c = 1")
        c2c1bdd = evalSexp(fsm, "c2.c = 1")

        self.assertEqual(c1c0bdd & c2c0bdd, fsm.init)
        self.assertEqual(c1c0bdd & c2c1bdd | c1c1bdd & c2c0bdd,
                         fsm.post(fsm.init))

        fsmbuilder = nscompile.Compile_get_global_fsm_builder()
        enc = nsenc.Enc_get_bdd_encoding()
        ddmanager = nsbddenc.BddEnc_get_dd_manager(enc)
        base_enc = nsbddenc.bddenc2baseenc(enc)
        symb_table = nsbaseenc.BaseEnc_get_symb_table(base_enc)

        propDb = glob.prop_database()
        master = propDb.master

        sexpfsm_ptr = nsprop.Prop_get_scalar_sexp_fsm(master._ptr)

        # Create a new expr trans
        c2c = self.get_variable_from_string(sexpfsm_ptr, "c2.c")
        self.assertIsNotNone(c2c)
        # trans = next(c2c) = (c2.c + 1) % 4
        nextc2c = nssexp.Expr_next(c2c, symb_table)
        one = nsnode.create_node(parser.NUMBER, None, None)
        one.left.nodetype = nsnode.int2node(1)
        self.assertEqual(nsnode.sprint_node(one), "1")
        four = nsnode.create_node(parser.NUMBER, None, None)
        four.left.nodetype = nsnode.int2node(4)
        self.assertEqual(nsnode.sprint_node(four), "4")
        c2cp1 = nssexp.Expr_plus(c2c, one)
        c2cp1m4 = nssexp.Expr_mod(c2cp1, four)
        trans = nssexp.Expr_equal(nextc2c, c2cp1m4, symb_table)

        clusters = nsfsm.FsmBuilder_clusterize_expr(fsmbuilder, enc, trans)
        cluster_options = nsbddtrans.ClusterOptions_create(
            nsopt.OptsHandler_get_instance())

        bddTrans = BddTrans(
            nsbddtrans.BddTrans_create(
                ddmanager, clusters, nsbddenc.BddEnc_get_state_vars_cube(enc),
                nsbddenc.BddEnc_get_input_vars_cube(enc),
                nsbddenc.BddEnc_get_next_state_vars_cube(enc),
                nsopt.get_partition_method(nsopt.OptsHandler_get_instance()),
                cluster_options))

        fsm.trans = bddTrans

        self.assertEqual(c1c0bdd & c2c0bdd, fsm.init)
        self.assertEqual(c2c1bdd, fsm.post(fsm.init))
Example #3
0
def build_model():
    """
    Build the BDD FSM of the current model and store it in global data
    structures.

    :raise: a :exc:`NuSMVNeedFlatModelError
            <pynusmv.exception.NuSMVNeedFlatModelError>` if the Sexp FSM
            of the model is not built yet
    :raise: a :exc:`NuSMVNeedVariablesEncodedError
            <pynusmv.exception.NuSMVNeedVariablesEncodedError>` if the
            variables of the model are not encoded yet
    :raise: a :exc:`NuSMVModelAlreadyBuiltError
            <pynusmv.exception.NuSMVModelAlreadyBuiltError>` if the BDD FSM
            of the model is already built

    """
    # Check cmps
    if not nscompile.cmp_struct_get_build_flat_model(global_compile_cmps()):
        raise NuSMVNeedFlatModelError("Need flat model.")
    if not nscompile.cmp_struct_get_encode_variables(global_compile_cmps()):
        raise NuSMVNeedVariablesEncodedError("Need variables encoded.")
    if nscompile.cmp_struct_get_build_model(global_compile_cmps()):
        raise NuSMVModelAlreadyBuiltError("The model is already built.")

    # Build the model
    pd = nsprop.PropPkg_get_prop_database()
    sexp_fsm = nsprop.PropDb_master_get_scalar_sexp_fsm(pd)
    bdd_fsm = nsfsm.FsmBuilder_create_bdd_fsm(
        nscompile.Compile_get_global_fsm_builder(),
        nsenc.Enc_get_bdd_encoding(), sexp_fsm,
        nsopt.get_partition_method(nsopt.OptsHandler_get_instance()))

    nsprop.PropDb_master_set_bdd_fsm(pd, bdd_fsm)

    # Register executors
    enc = nsbddfsm.BddFsm_get_bdd_encoding(bdd_fsm)

    nstrace.TraceManager_register_complete_trace_executor(
        nstrace.TracePkg_get_global_trace_manager(), "bdd",
        "BDD partial trace execution",
        nstraceexec.bddCompleteTraceExecutor2completeTraceExecutor(
            nstraceexec.BDDCompleteTraceExecutor_create(bdd_fsm, enc)))

    nstrace.TraceManager_register_partial_trace_executor(
        nstrace.TracePkg_get_global_trace_manager(), "bdd",
        "BDD complete trace execution",
        nstraceexec.bddPartialTraceExecutor2partialTraceExecutor(
            nstraceexec.BDDPartialTraceExecutor_create(bdd_fsm, enc)))

    # Update cmps
    nscompile.cmp_struct_set_build_model(global_compile_cmps())
Example #4
0
def bdd_encoding():
    """
    Return the main bdd encoding of the current model.

    :rtype: :class:`BddEnc <pynusmv.dd.BddEnc>`

    """
    # Encode variables if needed
    global __bdd_encoding
    if __bdd_encoding is None:
        if nscompile.cmp_struct_get_encode_variables(global_compile_cmps()):
            __bdd_encoding = BddEnc(nsenc.Enc_get_bdd_encoding())
        else:
            encode_variables()
    return __bdd_encoding
Example #5
0
def encode_variables(layers=None, variables_ordering=None):
    """
    Encode the BDD variables of the current model and store it in global data
    structures.
    If variables_ordering is provided, use this ordering to encode the
    variables; otherwise, the default ordering method is used.

    :param layers: the set of layers variables to encode
    :type layers: :class:`set`
    :param variables_ordering: the file containing a custom ordering
    :type variables_ordering: path to file

    :raise: a :exc:`NuSMVNeedFlatHierarchyError
            <pynusmv.exception.NuSMVNeedFlatHierarchyError>` if the model is
            not flattened
    :raise: a :exc:`NuSMVModelAlreadyEncodedError
            <pynusmv.exception.NuSMVModelAlreadyEncodedError>`
            if the variables are already encoded

    """
    # Check cmps
    if not nscompile.cmp_struct_get_flatten_hrc(global_compile_cmps()):
        raise NuSMVNeedFlatHierarchyError("Need flat hierarchy.")
    if nscompile.cmp_struct_get_encode_variables(global_compile_cmps()):
        raise NuSMVModelAlreadyEncodedError(
            "The variables are already encoded.")

    # See to understand why setting a default set value is not a good idea
    # http://pylint-messages.wikidot.com/messages:w0102
    layers = layers or {"model"}

    if variables_ordering is not None:
        nsopt.set_input_order_file(nsopt.OptsHandler_get_instance(),
                                   variables_ordering)

    encode_variables_for_layers(layers, init=True)

    # Update cmps
    nscompile.cmp_struct_set_encode_variables(global_compile_cmps())

    # Get global encoding
    global __bdd_encoding
    __bdd_encoding = BddEnc(nsenc.Enc_get_bdd_encoding())
Example #6
0
def build_boolean_model(force=False):
    """
    Compiles the flattened hierarchy into a boolean model (SEXP) and stores it
    it a global variable.

    .. note::
        This function is subject to the following requirements:

            - hierarchy must already be flattened (:func:`flatten_hierarchy`)
            - encoding must be already built (:func:`encode_variables`)
            - boolean model must not exist yet (or the force flag must be on)

    :param force: a flag telling whether or not the boolean model must be built
       even though the cone of influence option is turned on.

    :raises NuSMVNeedFlatHierarchyError: if the hierarchy wasn't flattened yet.
    :raises NuSMVNeedVariablesEncodedError: if the variables are not yet encoded
    :raises NuSMVModelAlreadyBuiltError: if the boolean model is already built and force=False
    """
    global __bool_sexp_fsm

    # check the preconditions
    if not nscompile.cmp_struct_get_encode_variables(global_compile_cmps()):
        raise NuSMVNeedVariablesEncodedError("Need variables encoded.")
    if nscompile.cmp_struct_get_build_bool_model(
            global_compile_cmps()) and not force:
        raise NuSMVModelAlreadyBuiltError(
            "The boolean model is already built and the force flag is off")

    # create the flat model if need be.
    if not nscompile.cmp_struct_get_build_flat_model(global_compile_cmps()):
        build_flat_model()

    # Create the boolean model proper (CompileCmd.c/compile_create_boolean_model)
    propdb = nsprop.PropPkg_get_prop_database()
    bool_sexp_fsm = nsprop.PropDb_master_get_bool_sexp_fsm(propdb)

    # even though the force flag is on, a call to this method will have no effect
    # if the bool sexp_fsm already exists in the propdb (reproduces the behavior
    # of CompileCmd.c/compile_create_boolean_model() )
    if bool_sexp_fsm is None:
        benc = __bdd_encoding
        symb = benc.symbTable
        mgr = benc.DDmanager

        # Temporarily disable reordering (if needed)
        reord = nsdd.wrap_dd_reordering_status(mgr._ptr)
        if reord.status == 1:
            nsdd.dd_autodyn_disable(mgr._ptr)

        # add 'determ' to the default and Artifact classes
        determ = symb.create_layer("determ",
                                   nssymb_table.SYMB_LAYER_POS_BOTTOM)
        nssymb_table.SymbTable_layer_add_to_class(symb._ptr, "determ", None)
        nssymb_table.SymbTable_layer_add_to_class(symb._ptr, "determ",
                                                  "Artifacts Class")

        # THIS IS THE REAL CREATION !!
        scalar_sexp_fsm = nsprop.PropDb_master_get_scalar_sexp_fsm(propdb)
        bool_sexp_fsm = nssexp.BoolSexpFsm_create_from_scalar_fsm(
            scalar_sexp_fsm, benc._ptr, determ)

        __bool_sexp_fsm = BoolSexpFsm(bool_sexp_fsm, freeit=False)
        nsprop.PropDb_master_set_bool_sexp_fsm(propdb, bool_sexp_fsm)
        # unfortunately, if the C malloc fails, the C assertion will also fail
        # and result in a program crash.

        boolenc = nsboolenc.boolenc2baseenc(nsenc.Enc_get_bool_encoding())
        nsbaseenc.BaseEnc_commit_layer(boolenc, "determ")

        bddenc = nsbddenc.bddenc2baseenc(nsenc.Enc_get_bdd_encoding())
        nsbaseenc.BaseEnc_commit_layer(bddenc, "determ")

        # Re-enable reordering if it had been disabled
        if reord.status == 1:
            nsdd.dd_autodyn_enable(mgr._ptr, reord.method)

    # Tell NuSMV that the boolean model was built
    nscompile.cmp_struct_set_build_bool_model(global_compile_cmps())