def cew_si(fsm, agents, phi, psi, strat=None): """ Return the set of state/inputs pairs of strat satisfying <agents>[phi W psi] under full observability in strat. If strat is None, strat is considered true. fsm -- a MAS representing the system agents -- a list of agents names phi -- a BDD representing the set of states of fsm satisfying phi psi -- a BDD representing the set of states of fsm satisfying psi strat -- a BDD representing allowed state/inputs pairs, or None """ if not strat: strat = BDD.true(fsm.bddEnc.DDmanager) phi = phi & fsm.bddEnc.statesInputsMask & strat psi = psi & fsm.bddEnc.statesInputsMask & strat nfair = nfair_gamma_si(fsm, agents, strat) return fp( lambda Y: (psi | phi | nfair) & (psi | fsm.pre_strat_si(Y, agents, strat)), BDD.true(fsm.bddEnc.DDmanager))
def eg(fsm, phi): """ Return the set of states of fsm satisfying EG phi. fsm -- a MAS representing the system phi -- a BDD representing the set of states of fsm satisfying phi """ # def inner(Z): # res = Z # for f in fsm.fairness_constraints: # res = res & fp(lambda Y : (Z & f) | (phi & fsm.weak_pre(Y)), # BDD.false(fsm.bddEnc.DDmanager)) # return phi & fsm.weak_pre(res) # # r = fp(inner, BDD.true(fsm.bddEnc.DDmanager)) # return r.forsome(fsm.bddEnc.inputsCube) phi = phi.forsome(fsm.bddEnc.inputsCube) & fsm.bddEnc.statesMask if len(fsm.fairness_constraints) == 0: return fp(lambda Z: phi & fsm.pre(Z), BDD.true(fsm.bddEnc.DDmanager)).forsome(fsm.bddEnc.inputsCube) else: def inner(Z): res = phi for f in fsm.fairness_constraints: res = res & fsm.pre(fp(lambda Y: (Z & f) | (phi & fsm.pre(Y)), BDD.false(fsm.bddEnc.DDmanager))) return res return fp(inner, BDD.true(fsm.bddEnc.DDmanager)).forsome(fsm.bddEnc.inputsCube)
def complete_compatible(mas, agents, moves): """ Return the given moves extended with the set of moves reachable from these ones and compatible with them. mas -- a multi-agent system; agents -- a subset of agents of mas; moves -- a set of non-agents-conflicting moves. """ result = moves new_states = (post_through(mas, agents, BDD.true(mas), result) - result.forsome(mas.bddEnc.inputsCube)) new_moves = compatible_moves(mas, agents, new_states & mas.protocol(agents), moves) while new_moves.isnot_false(): result = result | new_moves new_states = (post_through(mas, agents, BDD.true(mas), result) - result.forsome(mas.bddEnc.inputsCube)) new_moves = compatible_moves(mas, agents, new_states & mas.protocol(agents), moves) return result
def caw(fsm, agents, phi, psi): """ Return the set of states of fsm satisfying [agents][phi W psi]. fsm -- a MAS representing the system agents -- a list of agents names phi -- a BDD representing the set of states of fsm satisfying phi psi -- a BDD representing the set of states of fsm satisfying psi """ if len(fsm.fairness_constraints) == 0: return fp(lambda Z : psi | (phi & fsm.pre_nstrat(Z, agents)), BDD.true(fsm.bddEnc.DDmanager)) else: def inner(Z): res = phi for f in fsm.fairness_constraints: res = res & fsm.pre_nstrat(fp(lambda Y : (psi &fair_gamma_states(fsm, agents)) | (Z & f) | (phi & fsm.pre_nstrat(Y, agents)), BDD.false(fsm.bddEnc.DDmanager)), agents) return (psi &fair_gamma_states(fsm, agents)) | res return fp(inner, BDD.true(fsm.bddEnc.DDmanager))
def eg(fsm, phi): """ Return the set of states of fsm satisfying EG phi. fsm -- a MAS representing the system phi -- a BDD representing the set of states of fsm satisfying phi """ #def inner(Z): # res = Z # for f in fsm.fairness_constraints: # res = res & fp(lambda Y : (Z & f) | (phi & fsm.weak_pre(Y)), # BDD.false(fsm.bddEnc.DDmanager)) # return phi & fsm.weak_pre(res) # #r = fp(inner, BDD.true(fsm.bddEnc.DDmanager)) #return r.forsome(fsm.bddEnc.inputsCube) phi = phi.forsome(fsm.bddEnc.inputsCube) & fsm.bddEnc.statesMask if len(fsm.fairness_constraints) == 0: return fp(lambda Z : phi & fsm.pre(Z), BDD.true(fsm.bddEnc.DDmanager)).forsome(fsm.bddEnc.inputsCube) else: def inner(Z): res = phi for f in fsm.fairness_constraints: res = res & fsm.pre(fp(lambda Y : (Z & f) | (phi & fsm.pre(Y)), BDD.false(fsm.bddEnc.DDmanager))) return res return (fp(inner, BDD.true(fsm.bddEnc.DDmanager)) .forsome(fsm.bddEnc.inputsCube))
def caw(fsm, agents, phi, psi): """ Return the set of states of fsm satisfying [agents][phi W psi]. fsm -- a MAS representing the system agents -- a list of agents names phi -- a BDD representing the set of states of fsm satisfying phi psi -- a BDD representing the set of states of fsm satisfying psi """ if len(fsm.fairness_constraints) == 0: return fp(lambda Z: psi | (phi & fsm.pre_nstrat(Z, agents)), BDD.true(fsm.bddEnc.DDmanager)) else: def inner(Z): res = phi for f in fsm.fairness_constraints: res = res & fsm.pre_nstrat( fp( lambda Y: (psi & fair_gamma_states(fsm, agents)) | (Z & f) | (phi & fsm.pre_nstrat(Y, agents)), BDD.false(fsm.bddEnc.DDmanager), ), agents, ) return (psi & fair_gamma_states(fsm, agents)) | res return fp(inner, BDD.true(fsm.bddEnc.DDmanager))
def pre(self, states, inputs=None, subsystem=None): """ Return the pre image of states, through inputs (if any) and in subsystem (if any). """ if inputs is None: inputs = BDD.true(self.bddEnc.DDmanager) if subsystem is None: subsystem = BDD.true(self.bddEnc.DDmanager) return ((self.weak_pre(states & inputs) & subsystem).forsome( self.bddEnc.inputsCube) & self.bddEnc.statesMask)
def post(self, states, inputs=None, subsystem=None): """ Return the post image of states, through inputs (if any) and in subsystem (if any). """ if inputs is None: inputs = BDD.true(self.bddEnc.DDmanager) if subsystem is None: subsystem = BDD.true(self.bddEnc.DDmanager) states = states & subsystem return super(MAS, self).post(states, inputs)
def pre(self, states, inputs=None, subsystem=None): """ Return the pre image of states, through inputs (if any) and in subsystem (if any). """ if inputs is None: inputs = BDD.true(self.bddEnc.DDmanager) if subsystem is None: subsystem = BDD.true(self.bddEnc.DDmanager) return ((self.weak_pre(states & inputs) & subsystem).forsome(self.bddEnc.inputsCube) & self.bddEnc.statesMask)
def test_nfair_gamma_si(self): fsm = self.cardgame_post_fair() s0 = eval_simple_expression(fsm, "step = 0") s1 = eval_simple_expression(fsm, "step = 1") s2 = eval_simple_expression(fsm, "step = 2") pa = eval_simple_expression(fsm, "pcard = Ac") pk = eval_simple_expression(fsm, "pcard = K") pq = eval_simple_expression(fsm, "pcard = Q") da = eval_simple_expression(fsm, "dcard = Ac") dk = eval_simple_expression(fsm, "dcard = K") dq = eval_simple_expression(fsm, "dcard = Q") dda = eval_simple_expression(fsm, "ddcard = Ac") ddk = eval_simple_expression(fsm, "ddcard = K") ddq = eval_simple_expression(fsm, "ddcard = Q") pan = eval_simple_expression(fsm, "player.action = none") pak = eval_simple_expression(fsm, "player.action = keep") pas = eval_simple_expression(fsm, "player.action = swap") dan = eval_simple_expression(fsm, "dealer.action = none") win = eval_simple_expression(fsm, "win") lose = eval_simple_expression(fsm, "lose") true = eval_simple_expression(fsm, "TRUE") false = eval_simple_expression(fsm, "FALSE") agents = {'dealer'} strats = split(fsm, fsm.protocol(agents), agents) strat = strats.pop() nf = ~fsm.fairness_constraints[0] & fsm.bddEnc.statesInputsMask self.assertEqual( nf & fsm.pre_strat_si(BDD.true(fsm.bddEnc.DDmanager), agents, strat), nf & fsm.pre_strat_si(BDD.true(fsm.bddEnc.DDmanager), agents, strat) & fsm.bddEnc.statesInputsMask) nfp = nfair_gamma_si(fsm, {'player'}) nfd = nfair_gamma_si(fsm, {'dealer'}) self.assertTrue(nfp.is_false()) self.assertTrue(fsm.protocol({'dealer'}) <= nfd)
def test_size(self): (fsm, enc, manager) = self.init_model() true = BDD.true(manager) false = BDD.false(manager) init = fsm.init noadmin = eval_simple_expression(fsm, "admin = none") alice = eval_simple_expression(fsm, "admin = alice") processing = eval_simple_expression(fsm, "state = processing") self.assertEqual(BDD.true().size, 1) self.assertEqual(BDD.false().size, 1) self.assertEqual(fsm.pick_one_state(BDD.true()).size, len(fsm.bddEnc.get_variables_ordering("bits")) + 1) self.assertEqual(init.size, 5) self.assertEqual(processing.size, 3)
def _fair(mas): if not mas.fairness_constraints: return BDD.true(mas) else: run = mas.trans # fair = nu Z. /\_fc pre(mu Y. (Z /\ fc) \/ pre(Y)) def inner(Z): res = BDD.true(mas) for fc in mas.fairness_constraints: fc = fc.forsome(mas.bddEnc.inputsCube) res = res & run.pre( fixpoint(lambda Y: (Z & fc) | run.pre(Y), BDD.false(mas))) return res return fixpoint(inner, BDD.true(mas))
def filter_cew_moves(mas, agents, moves_1, moves_2, moves): """ mas -- a multi-agent system; agents -- a subset of agents of mas; moves_1 -- a subset of moves for agents; moves_2 -- a subset of moves for agents; moves -- a closed set of moves for agents. """ # Abstract away actions of states states_1 = moves_1.forsome(mas.bddEnc.inputsCube) states_2 = moves_2.forsome(mas.bddEnc.inputsCube) states_1 = states_1 & mas.bddEnc.statesMask states_2 = states_2 & mas.bddEnc.statesMask moves_1 = states_1 & mas.protocol(agents) moves_2 = states_2 & mas.protocol(agents) # If there are no fairness constraints, the computation is simpler if not mas.fairness_constraints: # nu Q'. moves_2 & moves | (moves_1 & moves & pre_ce(Q')) return fixpoint(lambda Z: moves_2 & moves | (moves_1 & moves & pre_ce_moves(mas, agents, Z, moves)), BDD.true(mas)) else: moves_1_2_n = moves_1 | moves_2 | nfair_ce_moves(mas, agents, moves) moves_1_2_n = moves_1_2_n & moves return stay_ce_moves(mas, agents, moves_1_2_n, states_2 & moves, moves)
def filter_cew(mas, agents, states_1, states_2, moves): """ Return the set of states of mas for which there exists a strategy for agents compatible with moves such that all fair paths enforced by the strategy reach a state of states_2 through states of states_1, or stay in states_1 forever. mas -- a multi-agent system; agents -- a subset of agents of mas; states_1 -- a subset of states of mas; states_2 -- a subset of states of mas; moves -- a closed set of moves for agents. """ # Abstract away actions of states states_1 = states_1.forsome(mas.bddEnc.inputsCube) states_2 = states_2.forsome(mas.bddEnc.inputsCube) states_1 = states_1 & mas.bddEnc.statesMask states_2 = states_2 & mas.bddEnc.statesMask # If there are no fairness constraints, the computation is simpler if not mas.fairness_constraints: # nu Q'. states_2 | (states_1 & pre_ce(Q')) return fixpoint(lambda Z: states_2 | (states_1 & pre_ce(mas, agents, Z, moves)), BDD.true(mas)) else: states_1_2_n = states_1 | states_2 | nfair_ce(mas, agents, moves) return stay_ce(mas, agents, states_1_2_n, states_2, moves)
def nfair_gamma_si(fsm, agents, strat=None): """ Return the set of state/inputs pairs of strat in which agents can avoid a fair path in strat. If strat is None, it is considered true. fsm -- the model agents -- a list of agents names strat -- a BDD representing allowed state/inputs pairs, or None """ if not strat: strat = BDD.true(fsm.bddEnc.DDmanager) if len(fsm.fairness_constraints) == 0: return BDD.false(fsm.bddEnc.DDmanager) else: def inner(Z): res = BDD.false(fsm.bddEnc.DDmanager) for f in fsm.fairness_constraints: nf = ~f & fsm.bddEnc.statesMask & strat res = res | fsm.pre_strat_si( fp(lambda Y: (Z | nf) & fsm.pre_strat_si(Y, agents, strat), BDD.true(fsm.bddEnc.DDmanager)), agents, strat) return res return fp(inner, BDD.false(fsm.bddEnc.DDmanager))
def test_size(self): (fsm, enc, manager) = self.init_model() true = BDD.true(manager) false = BDD.false(manager) init = fsm.init noadmin = eval_simple_expression(fsm, "admin = none") alice = eval_simple_expression(fsm, "admin = alice") processing = eval_simple_expression(fsm, "state = processing") self.assertEqual(BDD.true().size, 1) self.assertEqual(BDD.false().size, 1) self.assertEqual( fsm.pick_one_state(BDD.true()).size, len(fsm.bddEnc.get_variables_ordering("bits")) + 1) self.assertEqual(init.size, 5) self.assertEqual(processing.size, 3)
def fair_states(fsm): """ Return the set of fair states of the model. fsm - the model """ return eg(fsm, BDD.true(fsm.bddEnc.DDmanager))
def check_free_choice(self): """ Check whether this MAS satisfies the free-choice property, that is, in every state, the choices of actions for each agent is not constrained by the choices of other agents. Return the set of moves that are not present in the MAS and should, or that are present but should not. """ if len(self.agents) <= 0: return BDD.false(self.bddEnc.DDmanager) true = BDD.true(self.bddEnc.DDmanager) protocols = {agent: self.protocol({agent}) for agent in self.agents} enabled = (self.weak_pre(self.reachable_states) & self.reachable_states & self.bddEnc.statesInputsMask) for s in self.pick_all_states(self.reachable_states): product = self.bddEnc.statesInputsMask for agent in self.agents: product &= protocols[agent] & s if (enabled & s) != product: return product.xor(enabled & s) return BDD.false(self.bddEnc.DDmanager)
def inner(Z): res = BDD.true(mas) for fc in mas.fairness_constraints: fc = fc.forsome(mas.bddEnc.inputsCube) res = res & run.pre( fixpoint(lambda Y: (Z & fc) | run.pre(Y), BDD.false(mas))) return res
def nfair_gamma_si(fsm, agents, strat=None): """ Return the set of state/inputs pairs of strat in which agents can avoid a fair path in strat. If strat is None, it is considered true. fsm -- the model agents -- a list of agents names strat -- a BDD representing allowed state/inputs pairs, or None """ if not strat: strat = BDD.true(fsm.bddEnc.DDmanager) if len(fsm.fairness_constraints) == 0: return BDD.false(fsm.bddEnc.DDmanager) else: def inner(Z): res = BDD.false(fsm.bddEnc.DDmanager) for f in fsm.fairness_constraints: nf = ~f & fsm.bddEnc.statesMask & strat res = res | fsm.pre_strat_si(fp(lambda Y : (Z | nf) & fsm.pre_strat_si(Y, agents, strat), BDD.true(fsm.bddEnc.DDmanager)), agents, strat) return res return fp(inner, BDD.false(fsm.bddEnc.DDmanager))
def pre_strat(self, states, agents, strat=None): """ Return the set of states s of this MAS such that there exists values of input variables of the agents such that for all values of input variables of the other agents, all successors of s through these inputs belong to states. If strat is not None, restrict to strat. states -- a BDD representing a set of states of this MAS; if states represents a set of state/inputs pairs, inputs are abstracted away; agents -- a set of agents names, agents of this MAS; strat -- a BDD representing allowed state/inputs pairs, or None. """ if not strat: strat = BDD.true(self.bddEnc.DDmanager) gamma_cube = self.inputs_cube_for_agents(agents) ngamma_cube = self.bddEnc.inputsCube - gamma_cube # Abstract away actions of states states = states.forsome(self.bddEnc.inputsCube) nstates = ~states & self.bddEnc.statesInputsMask strat = strat & self.bddEnc.statesInputsMask return ((~(self.weak_pre(nstates).forsome(ngamma_cube)) & self.weak_pre(states)).forsome(ngamma_cube) & strat & self.bddEnc.statesInputsMask).forsome(self.bddEnc.inputsCube)
def pre_strat_si(self, states, agents, strat=None): """ Return the set of state/inputs pairs <s,i_agents> of this MAS such that there exist values of input variables of the agents i_agents, all successors of s through i_agents U i_nagents belong to states. Restrict to strat if not None. states -- a BDD representing a set of states of this MAS; if states represents a set of state/inputs pairs, inputs are abstracted away; agents -- a set of agents names, agents of this MAS; strat -- a BDD representing a set of allowed state/inputs pairs. """ if strat is None: strat = BDD.true(self.bddEnc.DDmanager) gamma_cube = self.inputs_cube_for_agents(agents) ngamma_cube = self.bddEnc.inputsCube - gamma_cube # Abstract inputs from states to avoid mixing with the possible actions # present in states. states = states.forsome(self.bddEnc.inputsCube) nstates = ~states & self.bddEnc.statesInputsMask strat = strat & self.bddEnc.statesInputsMask return ((~(self.weak_pre(nstates).forsome(ngamma_cube)) & self.weak_pre(states)).forsome(ngamma_cube) & strat & self.bddEnc.statesInputsMask)
def explain_fair(fsm, state): """ Explain why state of fsm is a fair state. fsm -- the fsm; state -- a fair state of fsm. """ return explain_eg(fsm, state, BDD.true(fsm.bddEnc.DDmanager))
def fair_gamma_states(fsm, agents): """ Return the set of states in which agents cannot avoid a fair path. fsm -- the model agents -- a list of agents names """ return cag(fsm, agents, BDD.true(fsm.bddEnc.DDmanager))
def inner(Z): res = BDD.false(fsm.bddEnc.DDmanager) for f in fsm.fairness_constraints: nf = ~f # & fsm.bddEnc.statesMask res = res | fsm.pre_strat( fp(lambda Y: (Z | nf) & fsm.pre_strat(Y, agents), BDD.true(fsm.bddEnc.DDmanager)), agents ) return res
def test_nfair_gamma_si(self): fsm = self.cardgame_post_fair() s0 = eval_simple_expression(fsm, "step = 0") s1 = eval_simple_expression(fsm, "step = 1") s2 = eval_simple_expression(fsm, "step = 2") pa = eval_simple_expression(fsm, "pcard = Ac") pk = eval_simple_expression(fsm, "pcard = K") pq = eval_simple_expression(fsm, "pcard = Q") da = eval_simple_expression(fsm, "dcard = Ac") dk = eval_simple_expression(fsm, "dcard = K") dq = eval_simple_expression(fsm, "dcard = Q") dda = eval_simple_expression(fsm, "ddcard = Ac") ddk = eval_simple_expression(fsm, "ddcard = K") ddq = eval_simple_expression(fsm, "ddcard = Q") pan = eval_simple_expression(fsm, "player.action = none") pak = eval_simple_expression(fsm, "player.action = keep") pas = eval_simple_expression(fsm, "player.action = swap") dan = eval_simple_expression(fsm, "dealer.action = none") win = eval_simple_expression(fsm, "win") lose = eval_simple_expression(fsm, "lose") true = eval_simple_expression(fsm, "TRUE") false = eval_simple_expression(fsm, "FALSE") agents = {"dealer"} strats = split(fsm, fsm.protocol(agents), agents) strat = strats.pop() nf = ~fsm.fairness_constraints[0] & fsm.bddEnc.statesInputsMask self.assertEqual( nf & fsm.pre_strat_si(BDD.true(fsm.bddEnc.DDmanager), agents, strat), nf & fsm.pre_strat_si(BDD.true(fsm.bddEnc.DDmanager), agents, strat) & fsm.bddEnc.statesInputsMask, ) nfp = nfair_gamma_si(fsm, {"player"}) nfd = nfair_gamma_si(fsm, {"dealer"}) self.assertTrue(nfp.is_false()) self.assertTrue(fsm.protocol({"dealer"}) <= nfd)
def eg(fsm, phi): res = BDD.true(fsm.bddEnc.DDmanager) old = BDD.false(fsm.bddEnc.DDmanager) while res != old: old = res new = ex(fsm, res) res = res & new & phi & fsm.reachable_states return res
def inner(Z): res = BDD.false(fsm.bddEnc.DDmanager) for f in fsm.fairness_constraints: nf = ~f & fsm.bddEnc.statesMask & strat res = res | fsm.pre_strat_si( fp(lambda Y: (Z | nf) & fsm.pre_strat_si(Y, agents, strat), BDD.true(fsm.bddEnc.DDmanager)), agents, strat) return res
def eg(fsm, phi): """ Return the set of states of fsm satisfying EG phi. fsm -- a MAS representing the system phi -- a BDD representing the set of states of fsm satisfying phi """ return fp(lambda Z: (phi & fsm.pre(Z)), BDD.true(fsm.bddEnc.DDmanager))
def inner(Z): res = BDD.true(mas) for fc in mas.fairness_constraints: fc = fc.forsome(mas.bddEnc.inputsCube) res = res & run.pre( fixpoint( lambda Y: (states_2 & _fair(mas)) | (Z & fc) | (states_1 & run.pre(Y)), BDD.false(mas))) return (res & states_1) | (states_2 & _fair(mas))
def ew(mas, states_1, states_2): run = mas.trans if not mas.fairness_constraints: return fixpoint(lambda Z: states_2 | (states_1 & run.pre(Z)), BDD.true(mas)) else: def inner(Z): res = BDD.true(mas) for fc in mas.fairness_constraints: fc = fc.forsome(mas.bddEnc.inputsCube) res = res & run.pre( fixpoint( lambda Y: (states_2 & _fair(mas)) | (Z & fc) | (states_1 & run.pre(Y)), BDD.false(mas))) return (res & states_1) | (states_2 & _fair(mas)) return fixpoint(inner, BDD.true(mas))
def test_init(self): fsm = self.init_model() manager = fsm.bddEnc.DDmanager init = fsm.init initState = fsm.pick_one_state(init) self.assertTrue(BDD.false(manager) <= init <= BDD.true(manager)) self.assertTrue(BDD.false(manager) < initState <= init)
def inner(Z): # \/_fc []_group_follow(nu Y. (Z \/ ~fc) /\ []_group_follow(Y)) res = BDD.false(mas) for fc in mas.fairness_constraints: fc = fc.forsome(mas.bddEnc.inputsCube) nfc = ~fc res = res | ~follow.pre(~fixpoint( lambda Y: (Z | nfc) & ~follow.pre(~Y), BDD.true(mas))) return res
def ceg(fsm, agents, phi): """ Return the set of states of fsm satisfying <agents> G phi. fsm -- a MAS representing the system agents -- a list of agents names phi -- a BDD representing the set of states of fsm satisfying phi """ return fp(lambda Z: phi & fsm.pre_strat(Z, agents), BDD.true(fsm.bddEnc.DDmanager))
def inner(Z): res = psi for f in fsm.fairness_constraints: nf = ~f & fsm.bddEnc.statesMask & strat res = res | fsm.pre_strat_si( fp( lambda Y: (phi | psi | nfair) & (Z | nf) & (psi | fsm.pre_strat_si(Y, agents, strat)), BDD.true(fsm.bddEnc.DDmanager)), agents, strat) return (psi | phi | nfair) & res
def test_elements(self): # Initialize the model ret = cmd.Cmd_SecureCommandExecute("read_model -i" "tests/pynusmv/models/admin.smv") self.assertEqual(ret, 0, "cannot read the model") ret = cmd.Cmd_SecureCommandExecute("go") self.assertEqual(ret, 0, "cannot build the model") propDb = glob.prop_database() master = propDb.master fsm = propDb.master.bddFsm init = fsm.init ln = BDDList.from_tuple((init, BDD.true(init._manager), init)) self.assertEqual(len(ln), 3) self.assertSequenceEqual((init, BDD.true(init._manager), init), ln.to_tuple()) del ln
def test_true_false_equalities(self): (fsm, enc, manager) = self.init_model() true = BDD.true(manager) false = BDD.false(manager) self.assertTrue(false != true) self.assertFalse(false == true) self.assertTrue(false == false) self.assertTrue(true == true) self.assertTrue((false != true) == (not false == true))
def test_true_false_xor(self): (fsm, enc, manager) = self.init_model() true = BDD.true(manager) false = BDD.false(manager) init = fsm.init self.assertTrue(true ^ false == true) self.assertTrue(true ^ true == false) self.assertTrue(false ^ false == false) self.assertTrue(init ^ true == ~init) self.assertTrue(init ^ false == init)
def test_true_false_not(self): (fsm, enc, manager) = self.init_model() true = BDD.true(manager) false = BDD.false(manager) init = fsm.init self.assertTrue(~true == -true) self.assertTrue(~false == -false) self.assertTrue(~true == false) self.assertTrue(~false == true) self.assertTrue(false < ~init < true)
def cag(fsm, agents, phi): """ Return the set of states of fsm satisfying [agents] G phi. fsm -- a MAS representing the system agents -- a list of agents names phi -- a BDD representing the set of states of fsm satisfying phi """ if len(fsm.fairness_constraints) == 0: return fp(lambda Z: phi & fsm.pre_nstrat(Z, agents), BDD.true(fsm.bddEnc.DDmanager)) else: def inner(Z): res = phi for f in fsm.fairness_constraints: res = res & fsm.pre_nstrat( fp(lambda Y: (Z & f) | (phi & fsm.pre_nstrat(Y, agents)), BDD.false(fsm.bddEnc.DDmanager)), agents ) return res return fp(inner, BDD.true(fsm.bddEnc.DDmanager))
def ceg_si(fsm, agents, phi, strat=None): """ Return the set of state/inputs pairs of strat satisfying <agents> G phi under full observability in strat. If strat is None, strat is considered true. fsm -- a MAS representing the system agents -- a list of agents names phi -- a BDD representing the set of states of fsm satisfying phi strat -- a BDD representing allowed state/inputs pairs, or None """ if not strat: strat = BDD.true(fsm.bddEnc.DDmanager) phi = phi & fsm.bddEnc.statesInputsMask & strat nfair = nfair_gamma_si(fsm, agents, strat) return fp(lambda Y : (phi | nfair) & fsm.pre_strat_si(Y, agents, strat), BDD.true(fsm.bddEnc.DDmanager))
def inner(Z): res = psi for f in fsm.fairness_constraints: nf = ~f res = res | fsm.pre_strat(fp(lambda Y : (phi | psi | nfair) & (Z | nf) & (psi | fsm.pre_strat(Y, agents, strat)), BDD.true(fsm.bddEnc.DDmanager)), agents, strat) return (psi | phi | nfair) & res
def test_fairness(self): fsm = BddFsm.from_filename("tests/pynusmv/models/counters-fair.smv") self.assertIsNotNone(fsm) false = BDD.false(fsm.bddEnc.DDmanager) true = BDD.true(fsm.bddEnc.DDmanager) rc1 = evalSexp(fsm, "run = rc1") rc2 = evalSexp(fsm, "run = rc2") fairBdds = fsm.fairness_constraints self.assertEqual(len(fairBdds), 2) for fair in fairBdds: self.assertTrue(fair == rc1 or fair == rc2)
def test_dup(self): (fsm, enc, manager) = self.init_model() false = BDD.false(manager) true = BDD.true(manager) init = fsm.init self.assertEqual(false, false.dup()) self.assertEqual(true, true.dup()) self.assertEqual(init, init.dup()) self.assertNotEqual(true, init.dup()) self.assertNotEqual(init, false.dup())
def test_true_false_or(self): (fsm, enc, manager) = self.init_model() true = BDD.true(manager) false = BDD.false(manager) init = fsm.init self.assertTrue((true | false) == (true + false)) self.assertTrue(true | false == true) self.assertTrue(true | true == true) self.assertTrue(false | false == false) self.assertTrue(init | true == true) self.assertTrue(init | false == init)
def test_true_false_and(self): (fsm, enc, manager) = self.init_model() true = BDD.true(manager) false = BDD.false(manager) init = fsm.init self.assertTrue((true & false) == (true * false)) self.assertTrue(true & false == false) self.assertTrue(true & true == true) self.assertTrue(false & false == false) self.assertTrue(init & true == init) self.assertTrue(init & false == false)
def test_pick_states_inputs(self): fsm = self.model() false = BDD.false(fsm.bddEnc.DDmanager) true = BDD.true(fsm.bddEnc.DDmanager) p = evalSexp(fsm, "p") q = evalSexp(fsm, "q") a = evalSexp(fsm, "a") pstates = fsm.pick_all_states_inputs(p & a) self.assertEqual(len(pstates), 2) for pstate in pstates: self.assertTrue(false < pstate < p)
def test_init_equalities(self): (fsm, enc, manager) = self.init_model() true = BDD.true(manager) false = BDD.false(manager) init = fsm.init self.assertIsNotNone(init) self.assertTrue(init != true) self.assertTrue(init != false) self.assertFalse(init == true) self.assertFalse(init == false)
def aaf(fsm, alpha, phi): """aaf(a, p) = ~_eu(a, ~p, ~p & ~_ex(a, true)) & ~_eg(a, ~p)""" true = BDD.true(fsm.bddEnc.DDmanager) return ( ~_eu(fsm, alpha, (~phi), (~phi) & (~_ex(fsm, alpha, true)) ) & (~_eg(fsm, alpha, (~phi))) )