def get_instances_for_module(self, modtree): """ Return the list of variables that are instances of modules in module modtree. modtree is a part of the AST of the SMV model. modtree.type = MODULE """ # MODULE(MODTYPE(...), declarationlist) varlist = [] declarations = nsnode.cdr(modtree) while declarations is not None: decl = nsnode.car(declarations) if decl.type == nsparser.VAR: decl = nsnode.car(decl) while decl is not None: var = nsnode.car(decl) # var_id : type => COLON(ATOM, type) if nsnode.cdr(var).type == nsparser.MODTYPE: varlist.append(var) decl = nsnode.cdr(decl) declarations = nsnode.cdr(declarations) return varlist
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 show_types(self, node, indent=""): if node is not None: if node.type not in {nsparser.NUMBER, nsparser.ATOM}: print(indent + str(node.type)) self.show_types(nsnode.car(node), indent + " ") self.show_types(nsnode.cdr(node), indent + " ") else: print(indent + str(node.type), ":", nsnode.sprint_node(node)) else: print(indent + "None")
def cdr(this_node): """ Returns the rhs branch of this node. .. note:: This is a simple workaround of `Node.cdr` which does not behave as expected. :param this_node: the node whose rhs (cdr) is wanted. :return: the rhs member of this node. """ return Node.from_ptr(_node.cdr(this_node._ptr))
def __next__(self): """ Performs the iteration :return: the next node :raise: StopIteration when the iteration is over """ if self._ptr is None: raise StopIteration else: ret = Node.from_ptr(self._ptr) self._ptr = _node.cdr(self._ptr) return ret
def _get_instances_args_for_module(modtree): """ Return a dictionary of instance name -> list of instance arguments pairs, with instances of modules in module modtree. modtree is a part of the AST of the SMV model. modtree.type = MODULE """ # MODULE(MODTYPE(...), declarationlist) varlist = {} declarations = nsnode.cdr(modtree) while declarations is not None: decl = nsnode.car(declarations) if decl.type == nsparser.VAR: decl = nsnode.car(decl) while decl is not None: var = nsnode.car(decl) # var_id : type => COLON(ATOM, type) if nsnode.cdr(var).type == nsparser.MODTYPE: varid = nsnode.sprint_node(nsnode.car(var)) if varid in varlist: pass # TODO Variable already defined else: # Compute args list argslist = [] args = nsnode.cdr(nsnode.cdr(var)) while args is not None: arg = nsnode.car(args) argslist.append(arg) args = nsnode.cdr(args) varlist[varid] = argslist decl = nsnode.cdr(decl) declarations = nsnode.cdr(declarations) return varlist
def mas(agents=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. Note: if the MAS is already computed, agents argument has 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() 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() # 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
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