Example #1
0
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))
Example #2
0
 def check_cax(self, fsm, explanation, agents, phi):
     """Check that the explanation is correct."""
     # Get the cubes
     gamma_cube = fsm.inputs_cube_for_agents(agents)
     ngamma_cube = fsm.bddEnc.inputsCube - gamma_cube
     
     # The first state satisfies the spec
     self.assertTrue(explanation.state <= ~cex(fsm, agents, ~phi))
     acts = BDD.false(fsm.bddEnc.DDmanager)
     states = BDD.false(fsm.bddEnc.DDmanager)
     for (act, succ) in explanation.successors:
         # The successor satisfies phi
         self.assertTrue(succ.state <= phi)
         # The action is effectively possible
         self.assertTrue(act <= fsm.get_inputs_between_states(
                                              explanation.state, succ.state))
         # Accumulate states and actions
         acts = acts | act
         states = states | succ.state
     
     # The actions are effectively all the possible ones
     self.assertEqual((fsm.protocol(agents) &
                       explanation.state).forsome(fsm.bddEnc.statesCube).
                       forsome(ngamma_cube) &
                      fsm.bddEnc.statesMask,
                      acts.forsome(ngamma_cube) & fsm.bddEnc.statesMask)
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
Example #4
0
def ceu(fsm, agents, phi, psi):
    """
    Return the set of states of fsm satisfying <agents>[phi U 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
    """
    # phi = phi & fsm.bddEnc.statesInputsMask
    # psi = psi & fsm.bddEnc.statesInputsMask

    if len(fsm.fairness_constraints) == 0:
        return fp(lambda Z: psi | (phi & fsm.pre_strat(Z, agents)), BDD.false(fsm.bddEnc.DDmanager))
    else:
        nfair = nfair_gamma_states(fsm, agents)

        def inner(Z):
            res = psi
            for f in fsm.fairness_constraints:
                nf = ~f  # & fsm.bddEnc.statesMask
                res = res | fsm.pre_strat(
                    fp(
                        lambda Y: (phi | psi | nfair) & (Z | nf) & (psi | fsm.pre_strat(Y, agents)),
                        BDD.true(fsm.bddEnc.DDmanager),
                    ),
                    agents,
                )
            return (psi | phi | nfair) & res

        return fp(inner, BDD.false(fsm.bddEnc.DDmanager))
Example #5
0
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))
Example #6
0
def nfair_gamma_states(fsm, agents):
    """
    Return the set of states in which agents cann avoid fair paths.
    
    fsm -- the model
    agents -- a list of agents names
    """
    # NFair_Gamma = not([Gamma] G True) = <Gamma> F False
    agents = frozenset(agents)
    if agents not in __nfair_gamma_states:
        if len(fsm.fairness_constraints) == 0:
            __nfair_gamma_states[agents] = 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
                    res = res | fsm.pre_strat(
                        fp(lambda Y: (Z | nf) & fsm.pre_strat(Y, agents), BDD.true(fsm.bddEnc.DDmanager)), agents
                    )
                return res

            __nfair_gamma_states[agents] = fp(inner, BDD.false(fsm.bddEnc.DDmanager))
    return __nfair_gamma_states[agents]
Example #7
0
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)
Example #8
0
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 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
Example #10
0
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))
Example #11
0
    def test_get_false(self):
        (fsm, enc, manager) = self.init_model()

        false = BDD.false(manager)
        self.assertIsNotNone(false)
        self.assertTrue(false.is_false())
        self.assertFalse(false.is_true())
        self.assertTrue(false.isnot_true())
        self.assertFalse(false.isnot_false())
        self.assertTrue(false.isnot_true())

        false = BDD.false()
        self.assertIsNotNone(false)
        self.assertTrue(false.is_false())
        self.assertFalse(false.is_true())
        self.assertTrue(false.isnot_true())
        self.assertFalse(false.isnot_false())
        self.assertTrue(false.isnot_true())

        false = BDD.false()
        self.assertIsNotNone(false)
        self.assertTrue(false.is_false())
        self.assertFalse(false.is_true())
        self.assertTrue(false.isnot_true())
        self.assertFalse(false.isnot_false())
        self.assertTrue(false.isnot_true())
Example #12
0
 def check_cex(self, fsm, explanation, agents, phi):
     """Check that the explanation is correct."""
     # Get the cubes
     gamma_cube = fsm.inputs_cube_for_agents(agents)
     ngamma_cube = fsm.bddEnc.inputsCube - gamma_cube
     
     # The first state satisfies the spec
     self.assertTrue(explanation.state <= cex(fsm, agents, phi))
     acts = BDD.false(fsm.bddEnc.DDmanager)
     states = BDD.false(fsm.bddEnc.DDmanager)
     for (act, succ) in explanation.successors:
         ag_action = act.forsome(ngamma_cube)
         # The successor satisfies phi
         self.assertTrue(succ.state <= phi)
         # The action is effectively possible
         self.assertTrue(act <= fsm.get_inputs_between_states(
                                              explanation.state, succ.state))
         # Accumulate states and actions
         acts = acts | act
         states = states | succ.state
     
     # The reached states are effectively the reachable states
     # through the action
     self.assertTrue(states <= fsm.post(explanation.state, ag_action))
     self.assertTrue(states >= fsm.post(explanation.state, ag_action)
                                                     & fsm.bddEnc.statesMask)
                                                     
     # The actions are effectively all the possible actions completing ag_act
     self.assertTrue(acts <= ag_action)
     self.assertTrue(acts >= ag_action & 
                   fsm.get_inputs_between_states(explanation.state, states) &
                   fsm.bddEnc.inputsMask)
Example #13
0
 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)
Example #14
0
def ceu(fsm, agents, phi, psi, strat=None):
    """
    Return the set of states of strat satisfying <agents>[phi U 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 len(fsm.fairness_constraints) == 0:
        return fp(lambda Z : psi | (phi & fsm.pre_strat(Z, agents, strat)),
                  BDD.false(fsm.bddEnc.DDmanager))
    else:
        nfair = nfair_gamma(fsm, agents, strat)
        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
        return fp(inner, BDD.false(fsm.bddEnc.DDmanager))
Example #15
0
    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)
Example #16
0
def ceu(fsm, agents, phi, psi):
    """
    Return the set of states of fsm satisfying <agents>[phi U 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
    """
    #phi = phi & fsm.bddEnc.statesInputsMask
    #psi = psi & fsm.bddEnc.statesInputsMask
    
    if len(fsm.fairness_constraints) == 0:
        return fp(lambda Z : psi | (phi & fsm.pre_strat(Z, agents)),
                  BDD.false(fsm.bddEnc.DDmanager))
    else:
        nfair = nfair_gamma_states(fsm, agents)
        def inner(Z):
            res = psi
            for f in fsm.fairness_constraints:
                nf = ~f #& fsm.bddEnc.statesMask
                res = res | fsm.pre_strat(fp(lambda Y :
                                             (phi | psi | nfair) &
                                              (Z | nf) &
                                              (psi | fsm.pre_strat(Y, agents)),
                                              BDD.true(fsm.bddEnc.DDmanager)),
                                              agents)
            return (psi | phi | nfair) & res
        return fp(inner, BDD.false(fsm.bddEnc.DDmanager))
Example #17
0
def nfair_gamma_states(fsm, agents):
    """
    Return the set of states in which agents cann avoid fair paths.
    
    fsm -- the model
    agents -- a list of agents names
    """
    # NFair_Gamma = not([Gamma] G True) = <Gamma> F False
    agents = frozenset(agents)
    if agents not in __nfair_gamma_states:
        if len(fsm.fairness_constraints) == 0:
            __nfair_gamma_states[agents] = 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
                    res = res | fsm.pre_strat(fp(lambda Y :
                                                 (Z | nf) &
                                                 fsm.pre_strat(Y, agents),
                                                BDD.true(fsm.bddEnc.DDmanager)),
                                              agents)
                return res
            __nfair_gamma_states[agents] = fp(inner, 
                                              BDD.false(fsm.bddEnc.DDmanager))
    return __nfair_gamma_states[agents]
Example #18
0
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))
Example #19
0
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))
Example #20
0
 def test_get_false(self):
     (fsm, enc, manager) = self.init_model()
     
     false = BDD.false(manager)
     self.assertIsNotNone(false)
     self.assertTrue(false.is_false())
     self.assertFalse(false.is_true())
     self.assertTrue(false.isnot_true())
     self.assertFalse(false.isnot_false())
     self.assertTrue(false.isnot_true())
     
     false = BDD.false()
     self.assertIsNotNone(false)
     self.assertTrue(false.is_false())
     self.assertFalse(false.is_true())
     self.assertTrue(false.isnot_true())
     self.assertFalse(false.isnot_false())
     self.assertTrue(false.isnot_true())
     
     false = BDD.false()
     self.assertIsNotNone(false)
     self.assertTrue(false.is_false())
     self.assertFalse(false.is_true())
     self.assertTrue(false.isnot_true())
     self.assertFalse(false.isnot_false())
     self.assertTrue(false.isnot_true())
Example #21
0
def nfair_ce_moves(mas, agents, moves):
    """
    mas -- a multi-agent system;
    agents -- a subset of agents of mas;
    moves -- a closed set of moves for agents.
    """
    # If there are no fairness constraints, there are no nfair states.
    if not mas.fairness_constraints:
        return BDD.false(mas)
    
    else:
        def inner(Z):
            res = BDD.false(mas)
            for fc in mas.fairness_constraints:
                fc = fc.forsome(mas.bddEnc.inputsCube)
                nfc = ~fc & mas.bddEnc.statesMask
                nfc_moves = nfc & mas.protocol(agents) & moves
                m = stay_ce_moves(mas,
                                  agents,
                                  Z | nfc_moves,
                                  BDD.false(mas),
                                  moves)
                res |= pre_ce_moves(mas, agents, m, moves)
            return res
        return fixpoint(inner, BDD.false(mas))
def _nfair(mas, formula, agents):
    """
    Return the set of states in which the given agents cannot avoid a fair path
    by using the strategy encoded in these states.
    """
    jump = mas.transitions[formula]["jump"]
    equiv = mas.transitions[formula]["equiv"]
    follow = mas.transitions[formula]["follow"]

    if not mas.fairness_constraints:
        return BDD.false(mas)

    else:
        # nfair =
        # mu Z. \/_fc []_group_follow(nu Y. (Z \/ ~fc) /\ []_group_follow(Y))
        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

        res = fixpoint(inner, BDD.false(mas))
        return res
 def check_cex(self, fsm, explanation, agents, phi):
     """Check that the explanation is correct."""
     # Get the cubes
     gamma_cube = fsm.inputs_cube_for_agents(agents)
     ngamma_cube = fsm.bddEnc.inputsCube - gamma_cube
     
     # The first state satisfies the spec
     self.assertTrue(explanation.state <= cex(fsm, agents, phi))
     acts = BDD.false(fsm.bddEnc.DDmanager)
     states = BDD.false(fsm.bddEnc.DDmanager)
     for (act, succ) in explanation.successors:
         ag_action = act.forsome(ngamma_cube)
         # The successor satisfies phi
         self.assertTrue(succ.state <= phi)
         # The action is effectively possible
         self.assertTrue(act <= fsm.get_inputs_between_states(
                                              explanation.state, succ.state))
         # Accumulate states and actions
         acts = acts | act
         states = states | succ.state
     
     # The reached states are effectively the reachable states
     # through the action
     self.assertTrue(states <= fsm.post(explanation.state, ag_action))
     self.assertTrue(states >= fsm.post(explanation.state, ag_action)
                                                     & fsm.bddEnc.statesMask)
                                                     
     # The actions are effectively all the possible actions completing ag_act
     self.assertTrue(acts <= ag_action)
     self.assertTrue(acts >= ag_action & 
                   fsm.get_inputs_between_states(explanation.state, states) &
                   fsm.bddEnc.inputsMask)
 def check_cax(self, fsm, explanation, agents, phi):
     """Check that the explanation is correct."""
     # Get the cubes
     gamma_cube = fsm.inputs_cube_for_agents(agents)
     ngamma_cube = fsm.bddEnc.inputsCube - gamma_cube
     
     # The first state satisfies the spec
     self.assertTrue(explanation.state <= ~cex(fsm, agents, ~phi))
     acts = BDD.false(fsm.bddEnc.DDmanager)
     states = BDD.false(fsm.bddEnc.DDmanager)
     for (act, succ) in explanation.successors:
         # The successor satisfies phi
         self.assertTrue(succ.state <= phi)
         # The action is effectively possible
         self.assertTrue(act <= fsm.get_inputs_between_states(
                                              explanation.state, succ.state))
         # Accumulate states and actions
         acts = acts | act
         states = states | succ.state
     
     # The actions are effectively all the possible ones
     self.assertEqual((fsm.protocol(agents) &
                       explanation.state).forsome(fsm.bddEnc.statesCube).
                       forsome(ngamma_cube) &
                      fsm.bddEnc.statesMask,
                      acts.forsome(ngamma_cube) & fsm.bddEnc.statesMask)
Example #25
0
 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
Example #26
0
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
Example #27
0
 def inner(Z):
     res = BDD.false(mas)
     for fc in mas.fairness_constraints:
         fc = fc.forsome(mas.bddEnc.inputsCube)
         nfc = ~fc & mas.bddEnc.statesMask
         states = stay_ce(mas, agents, Z | nfc, BDD.false(mas), moves)
         res |= pre_ce(mas, agents, states, moves)
     return res
Example #28
0
 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):
    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
Example #30
0
 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 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))
Example #33
0
def eval_strat_FSF(fsm, spec):
    """
    Return the BDD representing the set of states of fsm satisfying spec.
    spec is a strategic operator <G> pi.
    
    Implement a variant of the algorithm that
    filters, splits and then filters.
    
    fsm -- a MAS representing the system;
    spec -- an AST-based ATLK specification with a top strategic operator.
    
    """
    
    if type(spec) is CAX:
        # [g] X p = ~<g> X ~p
        newspec = CEX(spec.group, Not(spec.child))
        return ~eval_strat_FSF(fsm, newspec)
        
    elif type(spec) is CAG:
        # [g] G p = ~<g> F ~p
        newspec = CEF(spec.group, Not(spec.child))
        return ~eval_strat_FSF(fsm, newspec)
        
    elif type(spec) is CAU:
        # [g][p U q] = ~<g>[ ~q W ~p & ~q ]
        newspec = CEW(spec.group,
                      Not(spec.right),
                      And(Not(spec.left), Not(spec.right)))
        return ~eval_strat_FSF(fsm, newspec)
        
    elif type(spec) is CAF:
        # [g] F p = ~<g> G ~p
        newspec = CEG(spec.group, Not(spec.child))
        return ~eval_strat_FSF(fsm, newspec)
        
    elif type(spec) is CAW:
        # [g][p W q] = ~<g>[~q U ~p & ~q]
        newspec = CEU(spec.group,
                      Not(spec.right),
                      And(Not(spec.left), Not(spec.right)))
        return ~eval_strat_FSF(fsm, newspec)
        
        
    sat = BDD.false(fsm.bddEnc.DDmanager)
    agents = {atom.value for atom in spec.group}
    
    # First filtering
    winning = filter_strat(fsm, spec, variant="FSF")
    
    if winning.is_false(): # no state/inputs pairs are winning => return false
        return winning
    
    return split_eval(fsm, spec, BDD.false(fsm.bddEnc.DDmanager),
                      winning)
Example #34
0
    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))
Example #35
0
 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))
Example #36
0
 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)
Example #37
0
    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)
Example #38
0
 def test_pre(self):
     fsm = self.model()
     trans = fsm.trans
     
     true = BDD.true()
     false = BDD.false()
     p = eval_simple_expression(fsm, "p")
     q = eval_simple_expression(fsm, "q")
     a = eval_simple_expression(fsm, "a")
     
     self.assertEqual(trans.pre(p & q), false)
     self.assertEqual(trans.pre(p & ~q, inputs=a), p & ~q)
Example #39
0
def filter_strat(fsm, spec, strat=None, variant="SF"):
    """
    Returns the subset SA of strat (or the whole system if strat is None),
    state/action pairs of fsm, such that there is a strategy to satisfy spec
    in fsm.
    
    fsm -- a MAS representing the system;
    spec -- an AST-based ATLK specification with a top strategic operator;
            the operator is CEX, CEG, CEF, CEU or CEW.
    strat -- the subset of the system to consider.
    variant -- the variant of the algorithm to evaluate strategic operators;
               must be
               * "SF" for the standard way: splitting in uniform strategies then
                 filtering winning states,
               * "FS" for the alternating way: filtering winning states, then
                 splitting one conflicting equivalence class, then recurse
               * "FSF" for the filter-split-filter way: filtering winning states
                 then splitting all remaining actions into uniform strategies,
                 then filtering final winning states.
                 
    If variant is not in {"SF", "FS", "FSF"}, the standard "SF" way is used.
    """

    sat = BDD.false(fsm.bddEnc.DDmanager)
    agents = {atom.value for atom in spec.group}

    # Filtering
    if type(spec) is CEX:
        winning = cex_si(fsm, agents, evalATLK(fsm,
                                               spec.child,
                                               variant=variant), strat)

    elif type(spec) is CEG:
        winning = ceg_si(fsm, agents, evalATLK(fsm,
                                               spec.child,
                                               variant=variant), strat)

    elif type(spec) is CEU:
        winning = ceu_si(fsm, agents, evalATLK(fsm, spec.left,
                                               variant=variant),
                         evalATLK(fsm, spec.right, variant=variant), strat)

    elif type(spec) is CEF:
        # <g> F p = <g>[true U p]
        winning = ceu_si(fsm, agents, BDD.true(fsm.bddEnc.DDmanager),
                         evalATLK(fsm, spec.child, variant=variant), strat)

    elif type(spec) is CEW:
        winning = cew_si(fsm, agents, evalATLK(fsm, spec.left,
                                               variant=variant),
                         evalATLK(fsm, spec.right, variant=variant), strat)

    return winning & fsm.bddEnc.statesInputsMask & fsm.protocol(agents)
Example #40
0
    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)
Example #41
0
 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)
Example #42
0
 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)
Example #43
0
 def test_count_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")
     
     self.assertEqual(fsm.count_states_inputs(a), 4)
     self.assertEqual(fsm.count_states_inputs(p & ~a), 2)
     self.assertEqual(fsm.count_states_inputs(true), 8)
     self.assertEqual(fsm.count_states_inputs(false), 0)
Example #44
0
 def inner(Z):
     res = BDD.false(mas)
     for fc in mas.fairness_constraints:
         fc = fc.forsome(mas.bddEnc.inputsCube)
         nfc = ~fc & mas.bddEnc.statesMask
         nfc_moves = nfc & mas.protocol(agents) & moves
         m = stay_ce_moves(mas,
                           agents,
                           Z | nfc_moves,
                           BDD.false(mas),
                           moves)
         res |= pre_ce_moves(mas, agents, m, moves)
     return res
Example #45
0
 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)
Example #46
0
    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)
Example #47
0
 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)
Example #48
0
 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())
Example #49
0
 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)
Example #50
0
 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)
Example #51
0
 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)
Example #52
0
 def test_count_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")
     
     self.assertEqual(fsm.count_inputs(a), 1)
     self.assertEqual(fsm.count_inputs(~a), 1)
     self.assertEqual(fsm.count_inputs(true), 2)
     self.assertEqual(fsm.count_inputs(false), 0)
     self.assertEqual(fsm.count_inputs(p & q & a), 0) # WHY ?
Example #53
0
def filter_strat(fsm, spec, strat=None, variant="SF"):
    """
    Returns the subset SA of strat (or the whole system if strat is None),
    state/action pairs of fsm, such that there is a strategy to satisfy spec
    in fsm.
    
    fsm -- a MAS representing the system;
    spec -- an AST-based ATLK specification with a top strategic operator;
            the operator is CEX, CEG, CEF, CEU or CEW.
    strat -- the subset of the system to consider.
    variant -- the variant of the algorithm to evaluate strategic operators;
               must be
               * "SF" for the standard way: splitting in uniform strategies then
                 filtering winning states,
               * "FS" for the alternating way: filtering winning states, then
                 splitting one conflicting equivalence class, then recurse
               * "FSF" for the filter-split-filter way: filtering winning states
                 then splitting all remaining actions into uniform strategies,
                 then filtering final winning states.
                 
    If variant is not in {"SF", "FS", "FSF"}, the standard "SF" way is used.
    """
    
    sat = BDD.false(fsm.bddEnc.DDmanager)
    agents = {atom.value for atom in spec.group}
    
    # Filtering
    if type(spec) is CEX:
        winning = cex_si(fsm, agents,
                         evalATLK(fsm, spec.child, variant=variant), strat)

    elif type(spec) is CEG:
        winning = ceg_si(fsm, agents, evalATLK(fsm, spec.child, variant=variant), strat)

    elif type(spec) is CEU:
        winning = ceu_si(fsm, agents, evalATLK(fsm, spec.left, variant=variant),
                         evalATLK(fsm, spec.right, variant=variant), strat)

    elif type(spec) is CEF:
        # <g> F p = <g>[true U p]
        winning = ceu_si(fsm, agents, BDD.true(fsm.bddEnc.DDmanager),
                         evalATLK(fsm, spec.child, variant=variant), strat)

    elif type(spec) is CEW:
       winning = cew_si(fsm, agents, evalATLK(fsm, spec.left, variant=variant),
                        evalATLK(fsm, spec.right, variant=variant), strat)
    
    
    return winning & fsm.bddEnc.statesInputsMask & fsm.protocol(agents)
Example #54
0
 def test_true_false_sub(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 - true == false)
     self.assertTrue(false - false == false)
     self.assertTrue(init - true == false)
     self.assertTrue(init - false == init)
     self.assertTrue(true - init == ~init)
     self.assertTrue(false - init == false)
Example #55
0
 def test_pick_one_inputs_error(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")
     
     with self.assertRaises(NuSMVBddPickingError):
         i = fsm.pick_one_inputs(false)
         
     # This does not raise an error since "p" contains all the inputs
     # Thus "i" is any inputs
     i = fsm.pick_one_inputs(p)
Example #56
0
 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)
Example #57
0
    def test_pick_one_state_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")

        si = fsm.pick_one_state_inputs(a & p)
        self.assertTrue(false < si <= a & p < true)
        self.assertTrue(si.isnot_false())
        self.assertTrue((si == (a & p & q)) | (si == (a & p & ~q)))
        si = fsm.pick_one_state_inputs(true)
        self.assertTrue(false < si < true)
Example #58
0
 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)