def print_vars_and_trans(self, modelpath): fsm = BddFsm.from_filename(modelpath) self.assertIsNotNone(fsm) propDb = glob.prop_database() master = propDb.master print("MODEL:", modelpath) print("============================================================") sexpfsm_ptr = nsprop.Prop_get_scalar_sexp_fsm(master._ptr) var_list = nssexp.SexpFsm_get_vars_list(sexpfsm_ptr) var_list_length = nsutils.NodeList_get_length(var_list) print("var_list length:", var_list_length) var_list_iter = nsutils.NodeList_get_first_iter(var_list) while var_list_iter is not None: item = nsutils.NodeList_get_elem_at(var_list, var_list_iter) print(nsnode.sprint_node(item)) print("--------------------------") var_init = nssexp.SexpFsm_get_var_init(sexpfsm_ptr, item) print(nsnode.sprint_node(var_init)) print("--------------------------") var_trans = nssexp.SexpFsm_get_var_trans(sexpfsm_ptr, item) print(nsnode.sprint_node(var_trans)) print("--------------------------") print() var_list_iter = nsutils.ListIter_get_next(var_list_iter)
def test_get_instances_after_flattening(self): car = nsnode.car cdr = nsnode.cdr glob.load_from_file("tests/tools/ctlk/dining-crypto.smv") # Flatten glob.flatten_hierarchy() # Get parsed tree tree = nsparser.cvar.parsed_tree self.assertIsNotNone(tree) self.assertIsNotNone(car(tree)) print(tree.type) # 145 = CONS print(car(tree).type) # 117 = MODULE print(nsnode.sprint_node(car(car(car(tree))))) # main print(cdr(car(tree)).type) # 145 = CONS print(car(cdr(car(tree))).type) # 113 = DEFINE print(cdr(cdr(car(tree)))) # None print(cdr(tree).type) # 145 = CONS print(car(cdr(tree)).type) # 117 = MODULE print(nsnode.sprint_node(car(car(car(cdr(tree)))))) # cryptograph print("----- Instances after flattening") # main module is car(tree) main_vars = self.get_instances_for_module(car(tree)) # Variables are removed from parsed_tree when flattening self.assertEqual(len(main_vars), 0) instances_args = {} for var in main_vars: # var = COLON(ATOM, MODTYPE(ATOM, CONS)) varname = nsnode.sprint_node(car(var)) instances_args[varname] = [] args = cdr(cdr(var)) argslist = [] while args is not None: arg = car(args) instances_args[varname].append(arg) argslist.append(nsnode.sprint_node(arg)) args = cdr(args) print(varname, ":", nsnode.sprint_node(car(cdr(var))), argslist) print("------------------------------------------------------")
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_good_identifiers(self): exprs = ["a", "a[4]", "t[v.r]", "inn", "AA", "a.b"] for expr in exprs: node = parse_identifier(expr) self.assertIsNotNone(node) self.assertIsNotNone(nsnode.sprint_node(node))
def test_printing_parsed_tree(self): car = nsnode.car cdr = nsnode.cdr glob.load_from_file("tests/tools/ctlk/dining-crypto.smv") # Get parsed tree tree = nsparser.cvar.parsed_tree print(tree.type) # 145 = CONS print(car(tree).type) # 117 = MODULE print(car(car(tree)).type) # 119 = MODTYPE print(nsnode.sprint_node(car(car(car(tree))))) # main print(cdr(tree).type) # 145 = CONS print(car(cdr(tree)).type) # 117 = MODULE print(car(car(car(cdr(tree)))).type) # 161 = ATOM print(nsnode.sprint_node(car(car(car(cdr(tree)))))) # cryptograph print(cdr(cdr(tree))) # None
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 get_variable_from_string(self, sexpfsm_ptr, var_string): var_list = nssexp.SexpFsm_get_vars_list(sexpfsm_ptr) var_list_iter = nsutils.NodeList_get_first_iter(var_list) while var_list_iter is not None: var = nsutils.NodeList_get_elem_at(var_list, var_list_iter) if nsnode.sprint_node(var) == var_string: return var var_list_iter = nsutils.ListIter_get_next(var_list_iter) return None
def test_good_identifiers(self): exprs = ["a", "a[4]", "t[v.r]", "inn", "AA", "a.b" ] for expr in exprs: node = parse_identifier(expr) self.assertIsNotNone(node) self.assertIsNotNone(nsnode.sprint_node(node))
def test_good_simple_expressions(self): exprs = ["a.car = 3", "e <= 56", "a[4] & t[v]", "inn | outt -> TRUE", "AA + B = C - D", "a -- b = c" # OK because b = c is commented so the expr is 'a' ] for expr in exprs: node = parse_simple_expression(expr) self.assertIsNotNone(node) self.assertIsNotNone(nsnode.sprint_node(node))
def test_good_next_expressions(self): exprs = ["next(a) = a", "e.ne <= next(53)", "a[4] & t[next(v)]", "inn | next(outt) -> TRUE", "AA + B = next(C) - D", "a -- b = init(c) % 5" # OK because b = init(c) % 5 # is commented so the expr is 'a' ] for expr in exprs: node = parse_next_expression(expr) self.assertIsNotNone(node) self.assertIsNotNone(nsnode.sprint_node(node))
def test_good_simple_expressions(self): exprs = [ "a.car = 3", "e <= 56", "a[4] & t[v]", "inn | outt -> TRUE", "AA + B = C - D", "a -- b = c" # OK because b = c is commented so the expr is 'a' ] for expr in exprs: node = parse_simple_expression(expr) self.assertIsNotNone(node) self.assertIsNotNone(nsnode.sprint_node(node))
def test_good_next_expressions(self): exprs = [ "next(a) = a", "e.ne <= next(53)", "a[4] & t[next(v)]", "inn | next(outt) -> TRUE", "AA + B = next(C) - D", "a -- b = init(c) % 5" # OK because b = init(c) % 5 # is commented so the expr is 'a' ] for expr in exprs: node = parse_next_expression(expr) self.assertIsNotNone(node) self.assertIsNotNone(nsnode.sprint_node(node))
def print_transs(self, filepath): # Parse a model nsparser.ReadSMVFromFile(filepath) parsed_tree = nsparser.cvar.parsed_tree print("----------------------------------") print(filepath) print("----------------------------------") # Get the trans trs = self.transs(parsed_tree) for tr in trs: self.assertEqual(tr.type, nsparser.TRANS) print("----- TRANS ----------------------") print(nsnode.sprint_node(car(tr)))
def trans_for_module(self, sexpfsm_ptr, module): var_list = nssexp.SexpFsm_get_vars_list(sexpfsm_ptr) trans = None var_list_iter = nsutils.NodeList_get_first_iter(var_list) while var_list_iter is not None: var = nsutils.NodeList_get_elem_at(var_list, var_list_iter) if nsnode.sprint_node(nsnode.car(var)) == module: var_trans = nssexp.SexpFsm_get_var_trans(sexpfsm_ptr, var) trans = nssexp.Expr_and_nil(trans, var_trans) var_list_iter = nsutils.ListIter_get_next(var_list_iter) return trans
def print_mainFlatHierarchy(self, filepath): fsm = self.model(filepath) flatHierarchy = nscompile.cvar.mainFlatHierarchy print("-------------------------------------------") print(filepath) print("-------------------------------------------") # VARS print("----- VARS --------------------------------") var_set = nscompile.FlatHierarchy_get_vars(flatHierarchy) ite = nsset.Set_GetFirstIter(var_set) while not nsset.Set_IsEndIter(ite): var = nsset.Set_GetMember(var_set, ite) print(nsnode.sprint_node(var)) ite = nsset.Set_GetNextIter(ite) # INIT print("----- INIT --------------------------------") init = nscompile.FlatHierarchy_get_init(flatHierarchy) print(nsnode.sprint_node(init)) # INPUT print("----- INPUT -------------------------------") inp = nscompile.FlatHierarchy_get_trans(flatHierarchy) print(nsnode.sprint_node(inp)) # TRANS print("----- TRANS -------------------------------") trans = nscompile.FlatHierarchy_get_trans(flatHierarchy) print(nsnode.sprint_node(trans)) # TRANS print("----- ASSIGN ------------------------------") assign = nscompile.FlatHierarchy_get_assign(flatHierarchy) # assign is a list of pairs <process-name, its-assignements> while assign is not None: pa_pair = car(assign) process = car(pa_pair) print("process:", nsnode.sprint_node(process)) expr = cdr(pa_pair) print(nsnode.sprint_node(expr)) assign = cdr(assign)
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 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): """ 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 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))
def print_instances(self, filepath): print("----- Instances for", filepath) car = nsnode.car cdr = nsnode.cdr glob.load_from_file(filepath) # Get parsed tree tree = nsparser.cvar.parsed_tree print("--- Main instances") # main module is car(tree) main_vars = self.get_instances_for_module(car(tree)) instances_args = {} for var in main_vars: # var = COLON(ATOM, MODTYPE(ATOM, CONS)) varname = nsnode.sprint_node(car(var)) instances_args[varname] = [] args = cdr(cdr(var)) argslist = [] while args is not None: arg = car(args) instances_args[varname].append(arg) argslist.append(nsnode.sprint_node(arg)) args = cdr(args) print(varname, ":", nsnode.sprint_node(car(cdr(var))), argslist) # Get FSM and stuff glob.compute_model() fsm = glob.prop_database().master.bddFsm self.assertIsNotNone(fsm) flatH = nscompile.cvar.mainFlatHierarchy st = nscompile.Compile_get_global_symb_table() self.assertIsNotNone(flatH) print("--- Check arguments instances") for instance in instances_args: print("INSTANCE", instance) for arg in instances_args[instance]: arg, err = nscompile.FlattenSexp(st, arg, None) self.assertEqual(err, 0) isVar = nssymb_table.SymbTable_is_symbol_var(st, arg) if isVar: print("VAR", nsnode.sprint_node(arg)) else: print("NOT VAR", nsnode.sprint_node(arg)) print("--- All vars") varset = nscompile.FlatHierarchy_get_vars(flatH) self.assertIsNotNone(varset) varlist = nsset.Set_Set2List(varset) self.assertIsNotNone(varlist) ite = nsutils.NodeList_get_first_iter(varlist) while not nsutils.ListIter_is_end(ite): var = nsutils.NodeList_get_elem_at(varlist, ite) isInput = nssymb_table.SymbTable_is_symbol_input_var(st, var) isVar = nssymb_table.SymbTable_is_symbol_var(st, var) if isInput: print("IVAR", "\t", "IN", "'" + nsnode.sprint_node(car(var)) + "'", "\t", nsnode.sprint_node(var)) elif isVar: print("VAR", "\t", "IN", "'" + nsnode.sprint_node(car(var)) + "'", "\t", nsnode.sprint_node(var)) else: print("[ERROR] Unknown type:", nsnode.sprint_node(var)) ite = nsutils.ListIter_get_next(ite) print("------------------------------------------------------")
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