def _get_variables_by_instances(agents): """ Return a dictionary of instance->list of variables """ st = symb_table() flatHierarchy = nscompile.cvar.mainFlatHierarchy # Populate variables with instances variables = {} for agent in agents: variables[agent] = [] varset = nscompile.FlatHierarchy_get_vars(flatHierarchy) varlist = nsset.Set_Set2List(varset) ite = nsutils.NodeList_get_first_iter(varlist) while not nsutils.ListIter_is_end(ite): var = nsutils.NodeList_get_elem_at(varlist, ite) varname = nsnode.sprint_node(var) isVar = nssymb_table.SymbTable_is_symbol_state_var(st._ptr, var) if isVar: # Put the var in the variables dictionary, under the right instance topcontext = varname.partition(".")[0] if topcontext in variables: variables[topcontext].append(var) ite = nsutils.ListIter_get_next(ite) return variables
def test_get_mod_instance_type(self): glob.load_from_file("tests/pynusmv/models/counters.smv") glob.compute_model() sexp = parse_simple_expression("c1") self.assertIsNotNone(sexp) st = glob.symb_table() tp = nssymb_table.SymbTable_get_type_checker(st._ptr) expr_type = nstype_checking.TypeChecker_get_expression_type( tp, sexp, None) self.assertTrue(nssymb_table.SymbType_is_error(expr_type))
def _flatten_and_filter_variable_args(arguments): """ Return a new dictionary instance name -> list of vars where all vars belong to arguments (under the correct instance name) all vars are VAR types all vars are flattened. arguments -- a dictionary instance name -> list of module arguments """ result = {} st = symb_table() for instance in arguments: result[instance] = [] for argument in arguments[instance]: arg, err = nscompile.FlattenSexp(st._ptr, argument, None) if not err and nssymb_table.SymbTable_is_symbol_var(st._ptr, arg): result[instance].append(arg) return result
def test_access_flat_hierarchy(self): glob.load(*self.counters()) glob.compute_model() flat = glob.flat_hierarchy() symb_table = glob.symb_table() self.assertIsNotNone(flat.init) self.assertIsNotNone(flat.trans) self.assertIsNone(flat.invar) self.assertIsNone(flat.justice) self.assertIsNone(flat.compassion) variables = flat.variables for variable in variables: var_type = symb_table.get_variable_type(variable) self.assertEqual(nssymb_table.SymbType_get_tag(var_type), nssymb_table.SYMB_TYPE_ENUM)
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
def test_get_symb_table(self): glob.load_from_file("tests/pynusmv/models/counters.smv") symb_table = glob.symb_table()
def test_symbol_table(self): self.assertEqual(self.fsm.symbol_table, glob.symb_table())