Example #1
0
 def test_create_trans(self):
     fsm = self.model()
     p = eval_simple_expression(fsm, "p")
     new_trans = BddTrans.from_string(fsm.bddEnc.symbTable,
                                      "next(p) = !p")
     self.assertEqual(new_trans.post(p), ~p)
     
     with self.assertRaises(NuSMVFlatteningError):
         new_trans = BddTrans.from_string(fsm.bddEnc.symbTable,
                                          "next(p) = !p",
                                          strcontext="main")
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 _compute_epistemic_trans(self, agents):
     from .glob import symb_table
     trans = None
     for agent in agents:
         if agent not in self._epistemic:
             raise UnknownAgentError(
                 str(agents) + " are an unknown agents names.")
         trans = nsnode.find_node(nsparser.AND, self._epistemic[agent],
                                  trans)
     self._epistemic_trans[frozenset(agents)] = BddTrans.from_trans(
         symb_table(), trans)
Example #4
0
 def _compute_epistemic_trans(self, agents):
     from .glob import symb_table
     trans = None
     for agent in agents:
         if agent not in self._epistemic:
             raise UnknownAgentError(str(agents) +
                                     " are an unknown agents names.")
         trans = nsnode.find_node(nsparser.AND,
                                  self._epistemic[agent],
                                  trans)
     self._epistemic_trans[agents] = BddTrans.from_trans(symb_table(),
                                                         trans)
def encode_strategies(mas, agents, formula, filtered):
    """
    Encode the strategies for agents, to check formula, given the filtered
    moves.
    
    mas -- a multi-agents system;
    agents -- a subset of agents of mas;
    formula -- an ATLK_irF strategic formula where the group is agents;
    filtered -- either the complete protocol of the agents, or the filtered
                moves for agents, for the given formula.
    
    The result is the presence, in mas.transitions[formula], of three relations
    under the "jump", "equiv", and "follow" keys, to perform the model
    checking:
        * the "jump" relation encode the fact that the original state stays the
          same and all strategies can change;
        * the "equiv" relation encode the fact that the states are equivalent
          for some agent in the group of formula, and the strategies of these
          agents are kept the same;
        * the "follow" relation encode the original transition relation with
          each agent of the group of formula following his strategy encoded
          in the current state (and that these strategies are kept the same).
    
    Note: mas.encoded is populated with intermediate cached information:
        * mas.encoded[(agent, filtered)] gives two (model-based) relations:
          + the relation encoding the fact that the encoded strategies of agent
            from filtered are kept the same;
          + the relation encoding the fact that the encoded strategies of agent
            are followed;
          they only depends on the agent and the filtered moves, thus if two
          sub-formulas have the same filtered moves (e.g., pre-filtering is
          not used), the relations are the same;
        * mas.encoded[agent] gives the relation encoding the equivalence for
          agent;
          it only depends on agent, since it only depends on what he observes;
          THIS RELATION DOES NOT ENCODE THE FACT THAT THE STRATEGIES DO NOT
          CHANGE;
        * mas.encoded["jump"] gives the relation encoding the fact that the
          state is the same but the strategies can change;
          it only depends on the MAS, since all strategies are free and only
          the state is kept identical.
    """
    if not hasattr(mas, "transitions"):
        mas.transitions = {}
    if not hasattr(mas, "encoded"):
        mas.encoded = {}

    # if mas.encoded["jump"] does not exist,
    # encode it, based on the original state variables of the model
    if "jump" not in mas.encoded:
        jump = jump_relation(mas)
        mas.encoded["jump"] = jump

    # Encode each agent variables and relations if needed

    # for each agent in agents,
    # if (agent, filtered) is not in mas.encoded,
    # compute them
    for agent in agents:
        if (agent, filtered) not in mas.encoded:
            relations = strategy_relations(mas, agents, agent, filtered)
            mas.encoded[(agent, filtered)] = relations

    # for each agent in agents,
    # if mas.encoded[agent] is not present,
    # compute it
    for agent in agents:
        if agent not in mas.encoded:
            relation = equivalence_relation(mas, agent)
            mas.encoded[agent] = relation

    # Encode the transition relations
    if formula not in mas.transitions:
        mas.transitions[formula] = {}

    # the "jump" relation is just mas.encoded["jump"]
    if "jump" not in mas.transitions[formula]:
        jump = mas.encoded["jump"]
        trans = BddTrans.from_string(mas.bddEnc.symbTable, str(jump))
        mas.transitions[formula]["jump"] = trans

    # the "equiv" relation is based on
    # * the "equiv" relations of each agent in agents
    #   (disjunction, for group knowledge)
    # * the strategies of the agents are the same
    #   (based on the variables of each agent, stored in
    #    mas.encoded[(agent, filtered)])
    if "equiv" not in mas.transitions[formula]:
        equiv = reduce(operator.or_, (mas.encoded[agent] for agent in agents),
                       model.Falseexp())
        equiv = reduce(operator.and_, (mas.encoded[(agent, filtered)][0]
                                       for agent in agents), equiv)
        trans = BddTrans.from_string(mas.bddEnc.symbTable, str(equiv))
        mas.transitions[formula]["equiv"] = trans

    # the "follow" relation is based on
    # * the original transition relation of the MAS;
    # * the fact that the strategies of the agents are the same,
    #   and that the strategies for agents are followed by these agents,
    #   given by the variables in mas.encoded[(agent, filtered)]
    if "follow" not in mas.transitions[formula]:
        flat = glob.flat_hierarchy()
        follow = reduce(operator.and_, (mas.encoded[(agent, filtered)][0]
                                        & mas.encoded[(agent, filtered)][1]
                                        for agent in agents), flat.trans)
        trans = BddTrans.from_string(mas.bddEnc.symbTable, str(follow))
        mas.transitions[formula]["follow"] = trans
Example #6
0
    def test_get_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)

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

        sexpfsm_ptr = nsprop.Prop_get_scalar_sexp_fsm(master._ptr)

        trans = self.trans_for_module(sexpfsm_ptr, "c2")

        # ANALYSE THE TRANS TO UNDERSTAND HOW TO CREATE NUMBERS
        #car = nsnode.car
        #cdr = nsnode.cdr
        #print("TRANS--------------------------------")
        #print(nsnode.sprint_node(cdr(trans)))
        #print("TRANS--------------------------------")
        # cdr(trans) =
        #case
        #run = rc2 : case
        #c2.c + 1 >= stop : start;
        #c2.c + 1 < stop : c2.c + 1;
        #esac;
        #!(run = rc2) : c2.c;
        #esac

        # car(cdr(trans)) =
        #run = rc2 : case
        #c2.c + 1 >= stop : start;
        #c2.c + 1 < stop : c2.c + 1;
        #esac;

        # cdr(car(cdr(trans))) =
        #case
        #c2.c + 1 >= stop : start;
        #c2.c + 1 < stop : c2.c + 1;
        #esac

        # car(cdr(car(cdr(trans)))) =
        #c2.c + 1 >= stop : start

        # car(car(cdr(car(cdr(trans))))) =
        #c2.c + 1 >= stop

        # car(car(car(cdr(car(cdr(trans)))))) =
        #c2.c + 1

        # car(car(car(car(cdr(car(cdr(trans))))))) =
        #c2.c

        # car(car(car(car(car(cdr(car(cdr(trans)))))))) =
        #c2

        # cdr(car(car(car(car(cdr(car(cdr(trans)))))))) =
        #c

        # cdr(car(car(car(cdr(car(cdr(trans))))))) =
        #1

        #print(cdr(cdr(car(car(car(car(cdr(car(cdr(trans))))))))))
        #print(nsnode.sprint_node(cdr(car(car(car(car(cdr(car(cdr(trans))))))))))

        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 | c2c0bdd, fsm.post(fsm.init))
Example #7
0
spec = prop.expr
print(spec)

bdd = pynusmv.mc.eval_ctl_spec(fsm, spec) & fsm.reachable_states
bdd

print("BDD Manipulation\n")

print("reachable states from initial states :")
#init
print(fsm.count_states(fsm.init))
for state in fsm.pick_all_states(fsm.init):
	print(state.get_str_values())

print("\ntransition relations pre or post-images :")
#transition relation
for state in fsm.pick_all_states(fsm.post(fsm.init)):
	print(state.get_str_values())

print("\nspecial case of transition relations co-exist :")
#next
from pynusmv.fsm import BddTrans
trans = BddTrans.from_string(fsm.bddEnc.symbTable,"next(F_operon) = 0")
for state in fsm.pick_all_states(trans.post(fsm.init)):
	print(state.get_str_values())

print("\nFrom the BDD-encoded FSM fsm and the specification spec, we call the eval_ctl_spec function to get all the states of fsm satisfying spec. Conjuncted with the set of reachables states of the model, we get bdd, a BDD representing all the reachable states of fsm satisfying spec. Finally, from this BDD we extract all the single states and display them, that is, we display, for each of them, the value of each state variable of the model :")
satstates = fsm.pick_all_states(bdd)
for state in satstates:
	print(state.get_str_values())