def test_prefix_tree():
    spec, sys = scenario_reactive()

    encoded = [
        [act(True, True), act(True, True),
         act(True, True)],
        [act(True, True), act(False, True),
         act(False, False)],
    ]

    def to_demo(encoded_trc):
        io_seq = zip(encoded_trc, sys.aigbv.simulate(encoded_trc))
        for inputs, (_, state) in io_seq:
            inputs = fn.project(inputs, sys.inputs)
            yield inputs, state

    # Technical debt where sys_actions and env_actions
    # are two different lists.
    demos = [list(zip(*to_demo(etrc))) for etrc in encoded]

    tree = prefix_tree(sys, demos)
    tree.write_dot('foo.dot')

    cspec = concretize(spec, sys, 3)
    ctrl = fit(cspec, 0.7, bv=True)
    lprob = tree.log_likelihood(ctrl, actions_only=True)
    assert lprob < 0

    assert tree.psat(cspec) == 1 / 2

    lprob2 = tree.log_likelihood(ctrl, actions_only=False)
    assert lprob2 < lprob
def test_sample_smoke():
    spec, sys = scenario_reactive()
    cspec = concretize(spec, sys, 3)
    ctrl = policy(cspec, 3)
    actions = ctrl.simulate()
    assert len(actions) == 3
    assert isinstance(cspec.accepts(actions), bool)
def test_flatten():
    spec, sys = scenario_reactive()
    cspec = concretize(spec, sys, 3)

    actions = [act(True, True), act(True, False), act(True, True)]
    bits = cspec.flatten(actions)
    assert bits == [True, True, True, False, True, True]

    assert cspec.unflatten(bits) == actions
def test_bv_policy():
    spec, mdp = scenario_reactive()
    cspec = concretize(spec, mdp, 3)
    ctrl = fit(cspec, 0.96)

    qdd = cspec._as_dfa(qdd=True)

    ctrl_bv = BVPolicy(ctrl)
    ctrl_bv.prob(qdd.start, {'a': (False, False)})
def test_nx2qdd():
    spec, sys = scenario_reactive()
    cspec = concretize(spec, sys, 3)

    graph, root, _ = spec2graph(cspec, qdd=True)

    assert nx.is_directed_acyclic_graph(graph)
    assert len(graph.nodes) == 12 + 4
    assert len(graph.edges) == 22

    for node in graph.nodes:
        assert graph.out_degree[node] <= 2
def test_policy_markov_chain():
    spec, sys = scenario_reactive()
    cspec = concretize(spec, sys, 3)

    ctrl = policy(cspec, 3)
    adj, _ = ctrl.stochastic_matrix()

    assert adj[0, 0] == 1
    assert adj[1, 1] == 1

    row_sums = adj.sum(axis=1)
    assert np.allclose(row_sums, np.ones_like(row_sums))
Beispiel #7
0
def test_preimage():
    spec, mdp = scenario_reactive()

    sys1 = mdp.aigbv >> BV.sink(1, ['c_next', '##valid'])
    sys2 = sys1 >> BV.aig2aigbv(spec.aig)

    def act(action, coin):
        return {'a': (action, ), 'c': (coin, )}

    actions = [act(True, True), act(True, False), act(True, True)]
    observations = fn.lpluck(0, sys1.simulate(actions))

    expr = preimage(observations, sys1)
    assert expr.inputs == {
        'c##time_0',
        'c##time_1',
        'c##time_2',
        'a##time_0',
        'a##time_1',
        'a##time_2',
    }

    bexpr1, manager, order = to_bdd2(sys2, horizon=3)

    def accepts(bexpr, actions):
        """Check if bexpr accepts action sequence."""
        timed_actions = {}
        for t, action in enumerate(actions):
            c, a = action['c'], action['a']
            timed_actions.update({
                f'c##time_{t}[0]': c[0],
                f'a##time_{t}[0]': a[0]
            })

        assert timed_actions.keys() == manager.vars.keys()
        tmp = manager.let(timed_actions, bexpr)
        assert tmp in (manager.true, manager.false)
        return tmp == manager.true

    assert not accepts(bexpr1, actions)

    bexpr2, _, input2var = aiger_bdd.to_bdd(expr,
                                            manager=manager,
                                            renamer=lambda _, x: x)

    assert accepts(bexpr2, actions)
    assert not accepts(~bexpr2, actions)

    bexpr3 = xor(bexpr1, bexpr2)

    assert accepts(bexpr3, actions)
def test_spec2graph():
    spec, sys = scenario_reactive()
    cspec = concretize(spec, sys, 3)

    graph, root, _ = spec2graph(cspec)

    assert nx.is_directed_acyclic_graph(graph)

    # BDD size
    assert len(graph.nodes) == 10
    assert len(graph.edges) == 16

    for node in graph.nodes:
        assert graph.out_degree[node] <= 2
def test_abstract_trace():
    spec, sys = scenario_reactive()
    cspec = concretize(spec, sys, 3)

    actions = [act(True, True), act(True, False), act(True, True)]
    trc = list(cspec.abstract_trace(actions))
    for prev, curr in fn.rest(fn.with_prev(trc)):
        if prev == curr:
            assert prev.node.level == 6
            assert prev.node == cspec.manager.false
        else:
            clvl, cdebt = curr.node.level, curr.debt
            plvl, pdebt = prev.node.level, prev.debt
            assert (clvl, -cdebt) < (plvl, -pdebt)
def test_concretize():
    spec, sys = scenario_reactive()
    cspec = concretize(spec, sys, 3)

    actions = [act(True, True), act(True, False), act(True, True)]

    assert not cspec.accepts(actions)

    cspec2 = cspec.toggle(actions)
    assert cspec2.accepts(actions)

    assert cspec2.imap == cspec.imap
    assert set(cspec.imap.keys()) == {'a'}
    assert set(cspec.emap.keys()) == {'c'}
Beispiel #11
0
def test_reweighted():
    spec, sys = scenario_reactive()

    # Hack too re-weight coinl
    sys2 = C.coin((1, 4), 'c') >> C.MDP(sys.aigbv >> BV.sink(1, ['##valid']))
    cspec2 = concretize(spec, sys2, 3)

    graph, root, _ = spec2graph(cspec2)

    assert nx.is_directed_acyclic_graph(graph)
    assert len(graph.nodes) == 12
    assert len(graph.edges) == 20

    for node in graph.nodes:
        assert graph.out_degree[node] <= 2
def test_policy():
    spec, sys = scenario_reactive()
    cspec = concretize(spec, sys, 3)

    ctrls = [policy(cspec)(3), policy(cspec, 3)]
    for i, ctrl in enumerate(ctrls):
        assert 0 <= ctrl.psat <= 1
        assert len(ctrl.ref2action_dist) == 5
        assert all(len(v) == 2 for v in ctrl.ref2action_dist.values())
        assert all(
            sum(v.values()) == pytest.approx(1)
            for v in ctrl.ref2action_dist.values())

    pctrl = policy(cspec)
    # Agent gets monotonically more optimal
    psats = [pctrl(x).psat for x in range(10)]
    assert all(x >= y for x, y in fn.with_prev(psats, 0))
def test_policy_markov_chain_psat():
    spec, sys = scenario_reactive()
    cspec = concretize(spec, sys, 3)

    adj, _ = fit(cspec, 0.7).stochastic_matrix()

    root_vec = sp.sparse.csr_matrix((adj.shape[0], 1))
    root_vec[2] = 1

    true_vec = sp.sparse.csr_matrix((adj.shape[0], 1))
    true_vec[1] = 1

    vec = root_vec.T
    for _ in range(cspec.order.horizon * cspec.order.total_bits):
        vec = vec @ adj

    assert (vec @ true_vec).todense() == pytest.approx(0.7)

    vec = true_vec
    for _ in range(cspec.order.horizon * cspec.order.total_bits):
        vec = adj @ vec

    assert (root_vec.T @ vec).todense() == pytest.approx(0.7)
def test_smoke2():
    spec, mdp = scenario_reactive()

    spec_circ = BV.aig2aigbv(spec.aig)
    mdp >>= C.circ2mdp(spec_circ)
    output = spec.output

    bdd, manager, order = to_bdd2(mdp, horizon=3, output=output)

    assert bdd.dag_size == 7

    def translate(mapping):
        return mapping

    assert bdd.count(6) == 8

    node = bdd

    assert bdd.bdd.let(translate({
        'a##time_0[0]': True,
        'c##time_0[0]': False,
        'a##time_1[0]': True,
    }), bdd) == bdd.bdd.false

    assert bdd.bdd.let(translate({
        'a##time_0[0]': True,
        'c##time_0[0]': True,
        'a##time_1[0]': False,
    }), bdd) == bdd.bdd.false

    assert node.low == bdd.bdd.false

    assert bdd.bdd.let(translate({
        'a##time_0[0]': True,
        'c##time_0[0]': True,
        'a##time_1[0]': True,
        'c##time_1[0]': True,
        'a##time_2[0]': True,
        'c##time_2[0]': True,
    }), bdd) == bdd.bdd.true

    assert bdd.bdd.let(translate({
        'a##time_0[0]': True,
        'c##time_0[0]': False,
        'a##time_1[0]': False,
        'c##time_1[0]': False,
        'a##time_2[0]': False,
        'c##time_2[0]': False,
    }), bdd) == bdd.bdd.true

    assert bdd.bdd.let(translate({
        'c##time_0[0]': False,
        'a##time_1[0]': True,
    }), bdd) == bdd.bdd.false

    assert bdd.bdd.let(translate({
        'c##time_0[0]': True,
        'a##time_1[0]': False,
    }), bdd) == bdd.bdd.false

    assert bdd.bdd.let(translate({
        'c##time_1[0]': False,
        'a##time_2[0]': True,
    }), bdd) == bdd.bdd.false

    assert bdd.bdd.let(translate({
        'c##time_1[0]': True,
        'a##time_2[0]': False,
    }), bdd) == bdd.bdd.false

    assert bdd.bdd.let(translate({
        'c##time_2[0]': False,
    }), bdd) == bdd

    assert bdd.bdd.let(translate({
        'c##time_2[0]': True,
    }), bdd) == bdd
def test_fit():
    spec, sys = scenario_reactive()
    cspec = concretize(spec, sys, 3)

    assert fit(cspec, 0.7).psat == pytest.approx(0.7)