Пример #1
0
def _make_init(internal_init, win, aut):
    """Return initial conditions for implementation.

    Depending on `aut.qinit`,
    synthesize the initial condition `aut.env_init`
    using the winning states `win`.

    @param internal_init: initial condition for
        internal variables.
    """
    qinit = aut.qinit
    # impl qinit = '\A \A'  # we synthesize `env_init` below
    env_init = aut.init['env']
    new_sys_init = aut.init['sys'] & internal_init & win
    # synthesize initial predicate
    if qinit in ('\A \A', '\A \E', '\E \E'):
        new_env_init = env_init & new_sys_init
    elif qinit == '\E \A':
        env_bound = aut.exist(aut.varlist['sys'], env_init)
        u = env_init & new_sys_init
        u |= ~ env_bound
        sys_bound = aut.forall(aut.varlist['env'], u)
        new_env_init = env_bound & sys_bound
    else:
        raise ValueError(
            'unknown `qinit` value "{qinit}"'.format(
                qinit=qinit))
    assert new_env_init != aut.false
    assert new_sys_init != aut.false
    assert is_state_predicate(new_env_init)
    assert is_state_predicate(new_sys_init)
    aut.init['impl_env'] = new_env_init
    aut.init['impl_sys'] = new_sys_init
Пример #2
0
def _make_init(internal_init, win, aut):
    """Return initial conditions for implementation.

    Depending on `aut.qinit`,
    synthesize the initial condition `aut.env_init`
    using the winning states `win`.

    @param internal_init: initial condition for
        internal variables.
    """
    qinit = aut.qinit
    # impl qinit = '\A \A'  # we synthesize `env_init` below
    env_init = aut.init['env']
    new_sys_init = aut.init['sys'] & internal_init & win
    # synthesize initial predicate
    if qinit in ('\A \A', '\A \E', '\E \E'):
        new_env_init = env_init & new_sys_init
    elif qinit == '\E \A':
        env_bound = aut.exist(aut.varlist['sys'], env_init)
        u = env_init & new_sys_init
        u |= ~env_bound
        sys_bound = aut.forall(aut.varlist['env'], u)
        new_env_init = env_bound & sys_bound
    else:
        raise ValueError('unknown `qinit` value "{qinit}"'.format(qinit=qinit))
    assert new_env_init != aut.false
    assert new_sys_init != aut.false
    assert is_state_predicate(new_env_init)
    assert is_state_predicate(new_sys_init)
    aut.init['impl_env'] = new_env_init
    aut.init['impl_sys'] = new_sys_init
Пример #3
0
def solve_rabin_game(aut, rank=1):
    """Return winning set and iterants for Rabin(1) game.

    @param aut: compiled game with <>[] & []<> winning
    @type aut: `temporal.Automaton`
    """
    assert rank == 1, 'only rank 1 supported for now'
    assert aut.bdd.vars or not aut.vars, (
        'first call `Automaton.build`')
    # TODO: can these assertions be removed elegantly ?
    assert len(aut.win['<>[]']) > 0
    assert len(aut.win['[]<>']) > 0
    aut.build()
    z = aut.false
    zold = None
    zk = list()
    yki = list()
    xkijr = list()
    while z != zold:
        zold = z
        xijr = list()
        yi = list()
        for hold in aut.win['<>[]']:
            y, xjr = _cycle_inside(zold, hold, aut)
            z |= y
            xijr.append(xjr)
            yi.append(y)
        zk.append(z)
        yki.append(yi)
        xkijr.append(xijr)
    assert is_state_predicate(z), z.support
    return zk, yki, xkijr
Пример #4
0
def solve_rabin_game(aut, rank=1):
    """Return winning set and iterants for Rabin(1) game.

    @param aut: compiled game with <>[] & []<> winning
    @type aut: `temporal.Automaton`
    """
    assert rank == 1, 'only rank 1 supported for now'
    assert aut.bdd.vars or not aut.vars, (
        'first call `Automaton.build`')
    # TODO: can these assertions be removed elegantly ?
    assert len(aut.win['<>[]']) > 0
    assert len(aut.win['[]<>']) > 0
    aut.build()
    z = aut.false
    zold = None
    zk = list()
    yki = list()
    xkijr = list()
    while z != zold:
        zold = z
        xijr = list()
        yi = list()
        for hold in aut.win['<>[]']:
            y, xjr = _cycle_inside(zold, hold, aut)
            z |= y
            xijr.append(xjr)
            yi.append(y)
        zk.append(z)
        yki.append(yi)
        xkijr.append(xijr)
    assert is_state_predicate(z), z.support
    return zk, yki, xkijr
Пример #5
0
def _assert_is_win(d):
    if isinstance(d, list):
        for u in d:
            assert prm.is_state_predicate(u), u
            return
    assert isinstance(d, dict), d
    for _, v in d.items():
        _assert_is_win(v)
Пример #6
0
def test_is_state_predicate():
    fol = setup()
    s = "x = -3  /\  ~ y"
    u = fol.add_expr(s)
    assert prm.is_state_predicate(u)
    assert not prm.is_primed_state_predicate(u, fol)
    assert not prm.is_proper_action(u)
    s = "x' = -3  /\  ~ y'"
    u = fol.add_expr(s)
    assert not prm.is_state_predicate(u)
    assert prm.is_primed_state_predicate(u, fol)
    assert not prm.is_proper_action(u)
    s = "x = -3  /\  ~ y'"
    u = fol.add_expr(s)
    assert not prm.is_state_predicate(u)
    assert not prm.is_primed_state_predicate(u, fol)
    assert prm.is_proper_action(u)
Пример #7
0
def _assert_is_win(d):
    if isinstance(d, list):
        for u in d:
            assert prm.is_state_predicate(u), u
            return
    assert isinstance(d, dict), d
    for _, v in d.items():
        _assert_is_win(v)
Пример #8
0
def trap(env_action, sys_action, safe, aut, unless=None):
    """Return subset of `safe` with contolled exit.

    @param unless: if `None`, then returned controlled invariant
        subset of `safe`. Otherwise, this defines an allowed set.
    @rtype: BDD node
    """
    logger.info('++ cinv')
    assert is_state_predicate(safe), aut.support(safe)
    q = aut.true  # if `unless is not None`,
    # then `q = safe` is wrong
    qold = None
    while q != qold:
        qold = q
        pre = step(env_action, sys_action, q, aut)
        q = safe & pre
        if unless is not None:
            q |= unless
    assert is_state_predicate(q), aut.support(q)
    logger.info('-- cinv')
    return q
Пример #9
0
def attractor(env_action, sys_action, target, aut, inside=None):
    """Return attractor for `target`.

    Keyword args as `step`.

    @param inside: remain in this set
    """
    logger.info('++ attractor')
    assert is_state_predicate(target), aut.support(target)
    # ancestors
    q = target
    qold = None
    while q != qold:
        qold = q
        pred = step(env_action, sys_action, q, aut)
        q |= pred
        if inside is not None:
            q &= inside
    assert is_state_predicate(q), aut.support(q)
    logger.info('-- attractor')
    return q
Пример #10
0
def trap(env_action, sys_action, safe, aut,
         unless=None):
    """Return subset of `safe` with contolled exit.

    @param unless: if `None`, then returned controlled invariant
        subset of `safe`. Otherwise, this defines an allowed set.
    @rtype: BDD node
    """
    logger.info('++ cinv')
    assert is_state_predicate(safe), aut.support(safe)
    q = aut.true  # if `unless is not None`,
                  # then `q = safe` is wrong
    qold = None
    while q != qold:
        qold = q
        pre = step(env_action, sys_action, q, aut)
        q = safe & pre
        if unless is not None:
            q |= unless
    assert is_state_predicate(q), aut.support(q)
    logger.info('-- cinv')
    return q
Пример #11
0
def attractor(env_action, sys_action, target, aut,
              inside=None):
    """Return attractor for `target`.

    Keyword args as `step`.

    @param inside: remain in this set
    """
    logger.info('++ attractor')
    assert is_state_predicate(target), aut.support(target)
    # ancestors
    q = target
    qold = None
    while q != qold:
        qold = q
        pred = step(env_action, sys_action, q, aut)
        q |= pred
        if inside is not None:
            q &= inside
    assert is_state_predicate(q), aut.support(q)
    logger.info('-- attractor')
    return q
Пример #12
0
def print_nodes(u, dvars, bdd, care_set=None, care_bits=None):
    """Enumerate first-order models of a set.

    A set of nodes is defined over unprimed variables.

    @param dvars: table of unprimed variables
    @type bdd: `BDD`
    """
    assert scope.is_state_predicate(u), u.support
    if u == bdd.false:
        print('empty set')
        return
    if care_bits is not None:
        assert scope.support_issubset(u, care_bits, bdd), (support, care_bits)
    _print_enumeration(u, bdd, dvars, care_set, care_bits)
Пример #13
0
def _assert_invariant(components, aut, moore=True):
    """Assert invariant about `aut.varlists` and predicates.

    - varlists of `components` are disjoint
    - `aut.init` and `aut.win` contain state predicates

    If `moore=True`, then assert that `aut.action` are actions
    of `components`.
    """
    varlists = {k: v for k, v in aut.varlist.items() if k in components}
    actions = {k: v for k, v in aut.actions.items() if k in components}
    assert prm.pairwise_disjoint(varlists), varlists
    for u in aut.init.values():
        assert prm.is_state_predicate(u)
    _assert_is_win(aut.win)
    if not moore:
        return
    for component, action in actions.items():
        assert prm.is_action_of_player(action, component, aut)
Пример #14
0
def do_it_yourself():
    """Compute states *from* where we can reach a goal."""
    aut, goal, action = spec()
    # Compute the least fixpoint,
    # so the states from where we can reach the `goal`
    # with one or more steps, or we are already there.
    vrs = aut.varlist['sys']
    primed_vrs = stx.prime_vars(vrs)
    r = aut.false
    rold = None
    # for sure != r, thus at least one iteration
    assert r != rold
    while r != rold:
        rold = r  # memo
        target = aut.replace_with_primed(vrs, r)
        pre = aut.exist(primed_vrs, action & target)
        r |= goal | pre
    assert prm.is_state_predicate(r)
    print_expr(r, aut)
Пример #15
0
def _assert_invariant(components, aut, moore=True):
    """Assert invariant about `aut.varlists` and predicates.

    - varlists of `components` are disjoint
    - `aut.init` and `aut.win` contain state predicates

    If `moore=True`, then assert that `aut.action` are actions
    of `components`.
    """
    varlists = {k: v for k, v in aut.varlist.items()
                if k in components}
    actions = {k: v for k, v in aut.actions.items()
               if k in components}
    assert prm.pairwise_disjoint(varlists), varlists
    for u in aut.init.values():
        assert prm.is_state_predicate(u)
    _assert_is_win(aut.win)
    if not moore:
        return
    for component, action in actions.items():
        assert prm.is_action_of_player(action, component, aut)
Пример #16
0
def solve_streett_game(aut, rank=1):
    r"""Return winning set and iterants for Streett(1) game.

    The returned value takes into account actions and
    liveness, not initial conditions (i.e., it is the
    fixpoint before reasoning about initial conditions).

    Expects "env" and "sys" players. Writes:

      - `aut.varlist["env'"]`
      - `aut.varlist["sys'"]`

    @param aut: compiled game with <>[] \/ []<> winning
    @type aut: `temporal.Automaton`
    """
    assert rank == 1, 'only rank 1 supported for now'
    assert aut.bdd.vars or not aut.vars, (
        'first call `Automaton.build`')
    assert len(aut.win['<>[]']) > 0
    assert len(aut.win['[]<>']) > 0
    env_action = aut.action['env']
    sys_action = aut.action['sys']
    aut.build()
    z = aut.true
    zold = None
    while z != zold:
        zold = z
        cox_z = fx.step(env_action, sys_action, z, aut)
        xijk = list()
        yij = list()
        for goal in aut.win['[]<>']:
            goal &= cox_z
            y, yj, xjk = _attractor_under_assumptions(goal, aut)
            z &= y
            xijk.append(xjk)
            yij.append(yj)
    assert is_state_predicate(z), z.support
    return z, yij, xijk
Пример #17
0
def solve_streett_game(aut, rank=1):
    r"""Return winning set and iterants for Streett(1) game.

    The returned value takes into account actions and
    liveness, not initial conditions (i.e., it is the
    fixpoint before reasoning about initial conditions).

    Expects "env" and "sys" players. Writes:

      - `aut.varlist["env'"]`
      - `aut.varlist["sys'"]`

    @param aut: compiled game with <>[] \/ []<> winning
    @type aut: `temporal.Automaton`
    """
    assert rank == 1, 'only rank 1 supported for now'
    assert aut.bdd.vars or not aut.vars, (
        'first call `Automaton.build`')
    assert len(aut.win['<>[]']) > 0
    assert len(aut.win['[]<>']) > 0
    env_action = aut.action['env']
    sys_action = aut.action['sys']
    aut.build()
    z = aut.true
    zold = None
    while z != zold:
        zold = z
        cox_z = fx.step(env_action, sys_action, z, aut)
        xijk = list()
        yij = list()
        for goal in aut.win['[]<>']:
            goal &= cox_z
            y, yj, xjk = _attractor_under_assumptions(goal, aut)
            z &= y
            xijk.append(xjk)
            yij.append(yj)
    assert is_state_predicate(z), z.support
    return z, yij, xijk
Пример #18
0
def _make_init(internal_init, win, aut):
    """Return initial conditions for implementation.

    Depending on `aut.qinit`,
    synthesize the initial condition `aut.init['impl']`
    using the winning states `win`.

    The cases are:

    - `\A \A`:  `InternalInit`
    - `\E \E`:  `InternalInit /\ Win /\ SysInit`
    - `\A \E`:

      - `plus_one is True`:
        ```
        /\ SysInit /\ (EnvInit => Win)
        /\ InternalInit
        ```

      - `plus_one is False`:
        ```
        /\ EnvInit => (SysInit /\ Win)
        /\ InternalInit
        ```

    - `\E \A`:

      - `plus_one is True`:
        ```
        /\ \A EnvVars:  SysInit /\ (EnvInit => Win)
        /\ InternalInit
        ```

      - `plus_one is False`:
        ```
        /\ \A EnvVars:  EnvInit => (SysInit /\ Win)
        /\ InternalInit
        ```

    where `InternalInit` is the initial condition for internal variables.

    @param internal_init: initial condition for
        internal variables.
    """
    sys_init = aut.init['sys']
    env_init = aut.init['env']
    env_vars = aut.varlist['env']
    qinit = aut.qinit
    plus_one = aut.plus_one
    # In `omega.games.enumeration` both of these reduce
    # to `sys_init & win` over those states that are
    # enumerated as initial, because only states that
    # satisfy `env_init` are enumerated--assuming
    # `env_init` is independent of sys vars.
    if plus_one:
        form = sys_init & (win | ~ env_init)
    else:
        form = (sys_init & win) | ~ env_init
    assert is_state_predicate(form)
    if qinit == '\A \A':
        # shared-state, env picks initial state
        init = aut.true
    elif qinit == '\E \E':
        # shared-state, sys picks initial state
        init = win & sys_init
    elif qinit == '\A \E':
        # disjoint-state
        init = form
    elif qinit == '\E \A':
        # disjoint-state
        init = aut.forall(env_vars, form)
    else:
        raise ValueError(
            'unknown `qinit` value "{q}"'.format(q=qinit))
    assert init != aut.false
    assert is_state_predicate(init)
    aut.init['impl'] = init & internal_init