def test_equal_atoms(self): test = parse_next_expression("test") test = nsnode.find_node(test.type, nsnode.car(test), nsnode.cdr(test)) same = parse_next_expression("test") same = nsnode.find_node(same.type, nsnode.car(same), nsnode.cdr(same)) other = parse_next_expression("testx") other = nsnode.find_node(other.type, nsnode.car(other), nsnode.cdr(other)) self.assertTrue(nsnode.node_equal(test, same) != 0) self.assertTrue(nsnode.node_equal(test, other) == 0)
def false(): """ Return a new specification corresponding to `FALSE`. :rtype: :class:`Spec` """ # freeit=True seems to be erroneous return Spec(nsnode.find_node(nsparser.FALSEEXP, None, None), freeit=False)
def test_trans_in_context(self): car = nsnode.car cdr = nsnode.cdr orig = "(next(c) = c) IN c1" trans = "next(c) = c" context = "c1" origp = parse_next_expression(orig) transp = parse_next_expression(trans) contextp = parse_identifier(context) # contextp is ATOM. We want DOT(None, ATOM) contextp = nsnode.find_node(nsparser.DOT, None, contextp) fullp = nsnode.find_node(nsparser.CONTEXT, contextp, transp) self.checkNodeTypeEqual(origp, fullp)
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)
def __invert__(self): """ Return the specification `NOT self`. :rtype: :class:`Spec` """ # freeit=True seems to be erroneous s = Spec(nsnode.find_node(nsparser.NOT, self._ptr, None), freeit=False) s._car = self return s
def not_(spec): """Return a new specification corresponding to `NOT spec`. :rtype: :class:`Spec` """ if spec is None: raise ValueError() # freeit=True seems to be erroneous s = Spec(nsnode.find_node(nsparser.NOT, spec._ptr, None), freeit=False) s._car = spec return s
def u(left, right): """ Return a new specification corresponding to `left U right`. :rtype: :class:`Spec` """ if left is None or right is None: raise ValueError() # freeit=True seems to be erroneous s = Spec(nsnode.find_node(nsparser.UNTIL, left._ptr, right._ptr), freeit=False) s._car = left s._cdr = right return s
def __or__(self, other): """ Return the specification `self OR other`. :rtype: :class:`Spec` """ if other is None: raise ValueError() # freeit=True seems to be erroneous s = Spec(nsnode.find_node(nsparser.OR, self._ptr, other._ptr), freeit=False) s._car = self s._cdr = other return s
def test_trans(self): # Parse a model #nsparser.ReadSMVFromFile("tests/pynusmv/models/modules.smv") #parsed_tree = nsparser.cvar.parsed_tree nscmd.Cmd_SecureCommandExecute( "read_model -i tests/pynusmv/models/modules.smv") nscmd.Cmd_SecureCommandExecute("flatten_hierarchy") st = nscompile.Compile_get_global_symb_table() # main = nsnode.find_node( # nsparser.ATOM, # nsnode.string2node(nsutils.find_string("main")), # None) # # # Flatten # nscompile.CompileFlatten_init_flattener() # st = nscompile.Compile_get_global_symb_table() # layer = nssymb_table.SymbTable_create_layer(st, "model", # nssymb_table.SYMB_LAYER_POS_BOTTOM) # nssymb_table.SymbTable_layer_add_to_class(st, "model", "Model Class") # nssymb_table.SymbTable_set_default_layers_class_name(st, "Model Class") # # #hierarchy = nscompile.Compile_FlattenHierarchy( # # st, layer, main, None, None, 1, 0, None) # # hierarchy = nscompile.FlatHierarchy_create(st) # instances = nsutils.new_assoc() # # nscompile.Compile_ConstructHierarchy(st, layer, main, None, None, # hierarchy, None, instances) # # fhtrans = nscompile.FlatHierarchy_get_trans(hierarchy) # print("NON FLATTENED") # print(nsnode.sprint_node(fhtrans)) # # print(fhtrans.type) #169 = AND # print(car(fhtrans)) #None # print(cdr(fhtrans).type) #130 = CONTEXT # print(car(cdr(fhtrans)).type) #208 = DOT # print(car(car(cdr(fhtrans)))) #None # print(cdr(car(cdr(fhtrans))).type) #161 = ATOM # print(nsnode.sprint_node(cdr(car(cdr(fhtrans))))) #m # # print(cdr(cdr(fhtrans)).type) #192 = EQUAL # # # # trans = nscompile.Compile_FlattenSexp(st, cdr(fhtrans), None) # print("FLATTENED") # print(nsnode.sprint_node(trans)) layers = nssymb_table.SymbTable_get_class_layer_names(st, None) variables = nssymb_table.SymbTable_get_layers_sf_i_vars(st, layers) ite = nsutils.NodeList_get_first_iter(variables) while not nsutils.ListIter_is_end(ite): variable = nsutils.NodeList_get_elem_at(variables, ite) print(nsnode.sprint_node(variable)) ite = nsutils.ListIter_get_next(ite) top = nsnode.find_node(nsparser.ATOM, nsnode.string2node(nsutils.find_string("top")), None) trans = nssexp.Expr_equal(nssexp.Expr_next(top, st), top, st) flattrans = nscompile.Compile_FlattenSexp(st, trans, None) inmod = nsnode.find_node( nsparser.ATOM, nsnode.string2node(nsutils.find_string("inmod")), None) t = nsnode.find_node(nsparser.ATOM, nsnode.string2node(nsutils.find_string("t")), None) m = nsnode.find_node(nsparser.ATOM, nsnode.string2node(nsutils.find_string("m")), None) my = nsnode.find_node(nsparser.ATOM, nsnode.string2node(nsutils.find_string("my")), None) n = nsnode.find_node(nsparser.ATOM, nsnode.string2node(nsutils.find_string("n")), None) mymod = nsnode.find_node( nsparser.ATOM, nsnode.string2node(nsutils.find_string("mymod")), None) main = nsnode.find_node( nsparser.ATOM, nsnode.string2node(nsutils.find_string("main")), None) minmod = nsnode.find_node(nsparser.DOT, nsnode.find_node(nsparser.DOT, None, m), inmod) ftrans = nssexp.Expr_equal( nssexp.Expr_next(inmod, st), nssexp.Expr_or(inmod, nsnode.find_node(nsparser.DOT, my, inmod)), st) print(nsnode.sprint_node(ftrans)) res, err = nsparser.ReadNextExprFromString( "next(inmod) = (inmod | my.inmod) IN n") self.assertEqual(err, 0) trans = car(res) print(nsnode.sprint_node(trans)) conttrans = nsnode.find_node(nsparser.CONTEXT, nsnode.find_node(nsparser.DOT, None, n), ftrans) print(nsnode.sprint_node(conttrans)) fflattrans = nscompile.Compile_FlattenSexp(st, conttrans, None) flattrans = nscompile.Compile_FlattenSexp(st, trans, None) print(nsnode.sprint_node(fflattrans)) print(nsnode.sprint_node(flattrans))
def mas(agents=None, initial_ordering=None): """ Return (and compute if needed) the multi-agent system represented by the currently read SMV model. If agents is not None, the set of agents (and groups) of the MAS is determined by agents. Otherwise, every top-level module instantiation is considered an agent where - her actions are the inputs variables prefixed by her name; - her observable variables are composed of * the state variables of the system prefixed by her name; * the state variables provided as an argument to the module instantiation. If initial_ordering is not None, it must be the path to a variables ordering file. It is used as the initial ordering for variables of the model. Note: if the MAS is already computed, agents and initial_ordering arguments have no effect. agents -- a set of agents. """ global __mas if __mas is None: # Check cmps if not nscompile.cmp_struct_get_read_model(nscompile.cvar.cmps): raise NuSMVNoReadModelError("Cannot build MAS; no read file.") if agents is None: # Get agents names tree = nsparser.cvar.parsed_tree main = None while tree is not None: module = nsnode.car(tree) if (nsnode.sprint_node(nsnode.car( nsnode.car(module))) == "main"): main = module tree = nsnode.cdr(tree) if main is None: print("[ERROR] No main module.") return # TODO Error, cannot find main module arguments = _get_instances_args_for_module(main) # arguments is a dict instancename(str)->listofargs(node) agents = arguments.keys() # Compute the model _compute_model(variables_ordering=initial_ordering) st = symb_table() # Flatten arguments and filter on variables argvars = _flatten_and_filter_variable_args(arguments) # Get agents observable variables (locals + module parameters) localvars = _get_variables_by_instances(agents) #localvars is a dict instancename(str)->listofvars(node) inputvars = _get_input_vars_by_instances(agents) # Merge instance variable arguments and local variables variables = { key: ((key in argvars and argvars[key] or []) + (key in localvars and localvars[key] or [])) for key in list(argvars.keys()) + list(localvars.keys()) } # Compute epistemic relation singletrans = {} for agent in variables: transexpr = None for var in variables[agent]: var = nsnode.sprint_node(var) transexpr = nsnode.find_node(nsparser.AND, _get_epistemic_trans(var), transexpr) singletrans[agent] = transexpr # Process variables to get strings instead of nodes observedvars = { ag: {nsnode.sprint_node(v) for v in variables[ag]} for ag in variables.keys() } inputvars = { ag: {nsnode.sprint_node(v) for v in inputvars[ag]} for ag in inputvars.keys() } groups = None else: _compute_model(variables_ordering=initial_ordering) # observedvars: a dictionary of agent name -> set of observed vars observedvars = { str(agent.name): [str(var) for var in agent.observables] for agent in agents } # inputsvars: a dictionary of agent name -> set of inputs vars inputvars = { str(agent.name): [str(ivar) for ivar in agent.actions] for agent in agents } # groups: # a dictionary of group name -> names of agents of the group groups = { str(group.name): [str(agent.name) for agent in group.agents] for group in agents if isinstance(group, Group) } # singletrans: a dictionary of agent name -> epistemic transition singletrans = {} for agent in agents: name = str(agent.name) transexpr = None for var in observedvars[name]: transexpr = nsnode.find_node(nsparser.AND, _get_epistemic_trans(var), transexpr) singletrans[name] = transexpr # Create the MAS fsm = _prop_database().master.bddFsm __mas = MAS(fsm._ptr, observedvars, inputvars, singletrans, groups=groups, freeit=False) return __mas