Exemple #1
0
def setup():
    """
    Initialize binary circuit manager
    """
    mgr = BDD()
    mgr.configure(reordering=False)
    """
    Declare spaces and types
    """
    # Declare continuous state spaces
    pspace = DynamicCover(-2, 2)
    anglespace = DynamicCover(-np.pi, np.pi, periodic=True)
    # Declare discrete control spaces
    vspace = EmbeddedGrid(2, vmax / 2, vmax)
    angaccspace = EmbeddedGrid(3, -1.5, 1.5)
    """
    Declare interfaces
    """
    dubins_x = Interface(mgr, {
        'x': pspace,
        'theta': anglespace,
        'v': vspace
    }, {'xnext': pspace})
    dubins_y = Interface(mgr, {
        'y': pspace,
        'theta': anglespace,
        'v': vspace
    }, {'ynext': pspace})
    dubins_theta = Interface(mgr, {
        'theta': anglespace,
        'v': vspace,
        'omega': angaccspace
    }, {'thetanext': anglespace})

    return mgr, dubins_x, dubins_y, dubins_theta
Exemple #2
0
def test_composite_module_topology():

    mgr = BDD()

    x = DynamicCover(0, 10)

    m1 = Interface(mgr, {'a': x}, {'b': x, 'i': x})
    m2 = Interface(mgr, {'i': x, 'j': x}, {'k': x})

    m12 = CompositeInterface((m1, m2))
    assert m12.sorted_mods() == ((m1, ), (m2, ))
    assert set(m12.outputs) == {'k', 'b', 'i'}
    assert set(m12.inputs) == {'a', 'j'}
    assert set(m12.latent) == {'i'}

    m3 = Interface(mgr, {'k': x, 'b': x}, {})

    m123 = CompositeInterface([m1, m2, m3])
    assert m123.sorted_mods() == ((m1, ), (m2, ), (m3, ))
    assert set(m123.outputs) == {'b', 'i', 'k'}
    assert set(m123.inputs) == {'a', 'j'}
    assert set(m123.vars) == {'a', 'j', 'b', 'i', 'k'}

    # Renaming
    m123renamed = m123.renamed(b='r', a='q')
    assert set(m123renamed.outputs) == {'r', 'i', 'k'}
    assert set(m123renamed.inputs) == {'q', 'j'}
Exemple #3
0
def test_series_comp():

    mgr = BDD()

    inputs = {
        'x': DynamicCover(0, 4),
        'y': DynamicCover(0, 4),
    }
    output = {'z': DynamicCover(0, 4)}

    h = Interface(mgr, inputs, output)
    g = ('j', 'y') >> h >> ('z', 'r')
    precision = {'j': 4, 'x': 3, 'r': 3}
    g = g.io_refined({
        'j': (.75, 2.5),
        'x': (2.5, 3.8),
        'r': (2.1, 3.1)
    },
                     nbits=precision)

    h = ('r', 'x') >> h
    h = h.io_refined({
        'r': (1.3, 3.8),
        'y': (1.0, 2.0),
        'z': (.9, 3.1)
    },
                     nbits={
                         'r': 3,
                         'y': 3,
                         'z': 4
                     })
    assert (g >> h) == g.composed_with(h)
    assert (g >> h) == h.composed_with(g)
    assert (g >> h).nonblock() != mgr.false
    assert (g >> h).count_nb(bits=10) == approx(28)  # 7 * 2 * 2
Exemple #4
0
def test_dynamic_regular():
    mgr = BDD()
    x = DynamicCover(-2.0, 2.0)
    assert x.pt2index(-2.0, 3) == 0
    assert x.pt2index(
        2.0, 3
    ) == 8  # TODO: 3 bits = 0-7 but need to return 8 b/c of the right/left align detection
    assert x.pt2index(1.99, 3) == 7
    assert x.pt2index(-1, 1) == 0

    assert x.pt2box(-.1, 3) == (approx(-.5), approx(0))
    assert x.pt2box(.6, 3) == (approx(.5), approx(1.0))
    assert x.pt2box(.6, nbits=4) == (approx(.5), approx(.75))
    assert x.pt2box(.6, nbits=2) == (approx(0), approx(1.0))
    assert x.pt2box(.6, nbits=1) == (approx(0), approx(2.0))

    # No bits yields the entire interval
    assert x.pt2box(1, 0) == (approx(-2), approx(2))

    with raises(OutOfDomainError):
        x.pt2bv(3, 1)

    # Inner approximation tests
    assert set(x.box2bvs((.4, .6), 2, innerapprox=True)) == set([])
    assert set(x.box2bvs((-.4, 1.6), 2, innerapprox=True)) == {(True, False)}
    assert set(x.box2bvs((-.3, .3), 2, innerapprox=True)) == set([])

    # Outer approximations tests
    assert set(x.box2bvs((.4, .6), 2, innerapprox=False)) == {(True, False)}
    assert set(x.box2bvs((.4, .6), 2, innerapprox=False)) == {(True, False)}
    assert set(x.box2bvs((.99, 1.01), 2, innerapprox=False)) == {(True, False),
                                                                 (True, True)}

    # Some numerical sensitivity tests
    assert x.box2indexwindow((-1.0, 1.0), 2, innerapprox=True) == (1, 2)
    assert x.box2indexwindow((-1.0, 1.0 - .00001), 2,
                             innerapprox=True) == (1, 1)
    assert x.box2indexwindow((-1.0 - .00001, 1.0 + .00001),
                             2,
                             innerapprox=True) == (1, 2)
    assert x.box2indexwindow((-1.0 - .00001, 1.0 + .00001),
                             2,
                             innerapprox=False) == (0, 3)

    # BDD creation
    assert x.conc2pred(mgr, "x", (.4, .6), 1, True) == mgr.false
    args = [mgr, "x", (.4, .6), 1, True]
    args = [mgr, "x", (-.34, .65), 4, True]
    assert x.box2indexwindow(*args[2:]) == (7, 9)

    pspace = DynamicCover(-2, 2)
    assert pspace.box2indexwindow((0, .8), 6, False) == (32, 44)

    # Over and under approximations of boxes that align exactly with the grid are the same
    assert pspace.conc2pred(mgr, 'x', (-1, 1), 4,
                            innerapprox=False) == pspace.conc2pred(
                                mgr, 'x', (-1, 1), 4, innerapprox=True)
    assert pspace.conc2pred(mgr, 'x', (-1.5, 1.5), 4,
                            innerapprox=False) == pspace.conc2pred(
                                mgr, 'x', (-1.5, 1.5), 4, innerapprox=True)
Exemple #5
0
def test_embedded_grid():
    x = EmbeddedGrid(21, 10, 50)
    assert x.num_bits == 5
    assert x.pt2index(24) == 7  # (24-10)/2
    assert x.pt2index(22.9, snap=True) == 6
    assert x.pt2index(25.1, snap=True) == 8

    mgr = BDD()
    assert (mgr.count(x.abs_space(mgr, 'x'), 5)) == 21

    with raises(ValueError):
        x.pt2index(23)
    with raises(ValueError):
        EmbeddedGrid(0, 40, 50)
    with raises(ValueError):
        EmbeddedGrid(3, 50, 40)
    with raises(ValueError):
        EmbeddedGrid(1, 40, 50)

    # Snapping to nearest from out of range
    assert x.pt2index(9, snap=True) == 0
    assert x.pt2index(60, snap=True) == 20

    EmbeddedGrid(1, 10, 10)
Exemple #6
0
def test_mixed_module():

    from redax.module import Interface
    from redax.spaces import DynamicCover, FixedCover

    mgr = BDD()
    inputs = {
        'x': DynamicCover(0, 16),
        'y': FixedCover(-10, 10, 10),
        'theta': DynamicCover(-np.pi, np.pi, periodic=True),
        'v': FixedCover(0, 5, 5),
        'omega': FixedCover(-2, 2, 4)
    }
    outputs = {
        'xnext': DynamicCover(0, 4),
        'ynext': FixedCover(-10, 10, 10),
        'thetanext': DynamicCover(-np.pi, np.pi, periodic=True)
    }

    dubins = Interface(mgr, inputs, outputs)

    # Underspecified input-output
    with raises(AssertionError):
        dubins.io_refined(
            {
                'v': (3.6, 3.7),
                'theta': (6, -6),
                'y': (2, 3),
                'ynext': (2.1, 3.1)
            },
            nbits={'theta': 3})

    # Test that fixed covers yield correct space cardinality
    assert mgr.count(dubins.inspace(),
                     4 + 4 + 4 + 3 + 2) == 16 * 10 * 16 * 5 * 4
    assert mgr.count(dubins.outspace(), 2 + 4 + 4) == 4 * 10 * 16
Exemple #7
0
def test_module_composition():
    mgr = BDD()

    x = DynamicCover(0, 10)

    m1 = Interface(mgr, {'a': x}, {'b': x, 'c': x})
    m2 = Interface(mgr, {'i': x, 'j': x}, {'k': x})

    m12 = (m1 >> m2.renamed(i='c'))
    assert set(m12.inputs) == set(['a', 'j'])
    assert set(m12.outputs) == set(['c', 'b', 'k'])
    assert m12 == m2.renamed(i='c').composed_with(m1)
    assert m12 == (('c', 'i') >> m2).composed_with(m1)

    # Renaming is left associative
    assert m12 == m1 >> (('c', 'i') >> m2)
    assert m12 != (m1 >> ('c', 'i')) >> m2
    assert m12 == ((m1.renamed(c='i') >> m2)).renamed(i='c')
    assert m12 == ((m1 >> ('c', 'i') >> m2)).renamed(i='c')
    assert m12 == m1.renamed(c='i').composed_with(m2).renamed(i='c')
    assert m12 == m1.renamed(c='i').composed_with(m2) >> ('i', 'c')
Exemple #8
0
def test_embeddedgrid_module():

    mgr = BDD()
    inputs = {'x': EmbeddedGrid(4, 0, 3)}
    outputs = {'y': EmbeddedGrid(8, 4, 11)}

    m = Interface(mgr, inputs, outputs)

    mgr.declare("x_0", "x_1", "y_0", "y_1", "y_2")
    x0 = mgr.var("x_0")
    x1 = mgr.var("x_1")
    y0 = mgr.var("y_0")
    y1 = mgr.var("y_1")
    y2 = mgr.var("y_2")
    assert m.io_refined({
        'x': 2,
        'y': 4
    }).pred == (x0 & ~x1) & (~(x0 & ~x1) | (~y0 & ~y1 & ~y2))

    assert len(mgr.vars) > 0
Exemple #9
0
def test_discrete():

    mgr = BDD()
    x = DiscreteSet(5)
    x.conc2pred(mgr, 'x', 2)  # Declares variables x_0, x_1, x_2 in manager

    mgr.declare("x_0", "x_1", "x_2")

    x0 = mgr.var("x_0")
    x1 = mgr.var("x_1")
    x2 = mgr.var("x_2")

    assert x.conc2pred(mgr, 'x', 2) == ~x0 & x1 & ~x2
    assert x.abs_space(mgr, 'x') == (x0 & ~x1 & ~x2) | ~x0

    with raises(AssertionError):
        x.conc2pred(mgr, 'x', -1)
Exemple #10
0
def test_sinks():

    mgr = BDD()
    x = DynamicCover(0, 10)

    x1 = x.conc2pred(mgr, 'x', [1, 4], 5, innerapprox=True)
    x2 = x.conc2pred(mgr, 'x', [5, 8], 5, innerapprox=True)
    x3 = x.conc2pred(mgr, 'x', [0.0001, 5.001], 5, innerapprox=False)
    x4 = x.conc2pred(mgr, 'x', [4.9999, 9.999], 5, innerapprox=False)

    m1 = Interface(mgr, {'x': x}, {}, assum=x1)
    m2 = Interface(mgr, {'x': x}, {}, assum=x2)
    m3 = Interface(mgr, {'x': x}, {}, assum=x3)
    m4 = Interface(mgr, {'x': x}, {}, assum=x4)

    assert (m1 * m2).assum == mgr.false
    assert (m1 + m2).assum != mgr.false
    assert (m3 + m4).assum == mgr.true

    assert (m3 + m1) == m3
    assert (m3 * m1) == m1

    assert (m4 * m1) <= m4
Exemple #11
0
def test_refinement_and_coarsening():

    mgr = BDD()

    def conc(x):
        return -3 * x

    x = DynamicCover(-10, 10)
    y = DynamicCover(20, 20)

    linmod = Interface(mgr, {'x': x}, {'y': y})

    width = 15

    for _ in range(50):
        # Generate random input windows
        f_width = {'x': np.random.rand() * width}
        f_left = {'x': -10 + np.random.rand() * (20 - f_width['x'])}
        f_right = {k: f_width[k] + f_left[k] for k in f_width}
        iobox = {k: (f_left[k], f_right[k]) for k in f_width}

        # Generate output overapproximation
        ur = conc(**f_left)
        ll = conc(**f_right)
        iobox['y'] = (ll, ur)

        # Refine and check abstract relation
        newmod = linmod.io_refined(iobox, nbits={'x': 8, 'y': 8})
        assert linmod <= newmod
        linmod = newmod

        # Check abstract relation relative to coarsened module
        assert linmod.coarsened(x=5, y=5) <= linmod
        assert linmod.coarsened(x=5) <= linmod
        assert linmod.coarsened(y=5) <= linmod
        # Coarsen should do nothing because it keeps many bits
        assert linmod.coarsened({'x': 10}, y=10) == linmod
Exemple #12
0
def test_fixed_periodic():

    mgr = BDD()

    y = FixedCover(0, 10, 5, periodic=True)  # 5 bins
    assert set(y.box2bvs((3, 7), False)) == {(False, False, True),
                                             (False, True, False),
                                             (False, True, True)}
    assert set(y.box2bvs((3, 7), True)) == {(False, True, False)}

    # Inner-outer tests
    assert set(y.box2bvs((3, 3.5), True)) == set([])
    assert set(y.box2bvs((3, 3.5), False)) == {(False, False, True)}
    assert set(y.box2bvs((3, 5), True)) == set([])

    # Wrap around tests
    assert set(y.box2bvs((9, 1), True)) == set([])
    assert set(y.box2bvs((9, 2.1), True)) == {(False, False, False)}
    assert set(y.box2bvs((9, 2.1), False)) == {(True, False, False),
                                               (False, False, False),
                                               (False, False, True)}

    z = FixedCover(0, 10, 5, periodic=True)
    mgr.declare("z_0", "z_1", "z_2")
    assert y == z
    assert z.box2indexwindow((9.9, .1), innerapprox=True) is None
    assert z.box2indexwindow((1.9, 2.1), innerapprox=True) is None
    assert z.box2indexwindow((9.9, .1), innerapprox=False) == (4, 0)
    assert z.box2indexwindow((4.4, 4.3), innerapprox=False) == (3, 2)
    assert z.box2indexwindow((9.9, 9.8), innerapprox=False) == (0, 4)
    z0 = mgr.var("z_0")
    z1 = mgr.var("z_1")
    z2 = mgr.var("z_2")
    assert z.conc2pred(mgr, 'z', (4.4, 4.3),
                       innerapprox=False) == ~z0 | (z0 & ~z1 & ~z2)
    assert z.box2indexwindow((19.9, 19.8), innerapprox=False) == (0, 4)

    # Over and under approximations of boxes that align exactly with the grid are the same
    assert z.conc2pred(mgr, 'z', (0, 4),
                       innerapprox=True) == z.conc2pred(mgr,
                                                        'z', (0, 4),
                                                        innerapprox=False)
Exemple #13
0
from pytest import approx

import numpy as np
import funcy as fn

from redax.module import Interface, CompositeInterface
from redax.spaces import DynamicCover
from redax.synthesis import ControlPre, DecompCPre, ReachGame, SafetyGame, ReachAvoidGame
from redax.visualizer import scatter2D, plot3D, plot3D_QT, pixel2D
from redax.utils.overapprox import bloatbox

from redax.predicates.dd import BDD
mgr = BDD()
mgr.configure(reordering=True)

ts = .2
k = .1
g = 9.8


def dynamics(p, v, a):
    vsign = 1 if v > 0 else -1
    return p + v * ts, v + a * ts - vsign * k * (v**2) * ts - g * ts


pspace = DynamicCover(-10, 10)
vspace = DynamicCover(-16, 16)
aspace = DynamicCover(0, 20)

# Smaller component modules
pcomp = Interface(mgr, {'p': pspace, 'v': vspace}, {'pnext': pspace})
Exemple #14
0
def test_dynamic_periodic():
    mgr = BDD()
    x = DynamicCover(0, 20, periodic=True)
    # assert x.pt2bv(11, 4) == (True, True, False, False)
    # assert x.pt2bv(19+20, 4) == (True, False, False, False)

    # Wrap around
    assert set(x.box2bvs((17, 7), 2, innerapprox=True)) == {(False, False)}
    assert set(x.box2bvs((17, 7), 2, innerapprox=False)) == {(True, False),
                                                             (False, False),
                                                             (False, True)}

    mgr.declare("x_0", "x_1", "x_2")

    x0 = mgr.var("x_0")
    x1 = mgr.var("x_1")
    x2 = mgr.var("x_2")

    assert x.conc2pred(mgr, 'x', (1, 19), 3) == mgr.true

    # assert x.conc2pred(mgr, 'x', (19,1), 3, True) == mgr.false
    assert x.conc2pred(mgr, 'x', (0, 9.9), 3, False) == ~x0
    assert x.conc2pred(mgr, 'x', (0, 9.9), 3,
                       True) == (~x0 & ~x1) | (~x0 & x1 & x2)

    assert x.box2indexwindow((.1, 19), 3, False) == (0, 7)
    assert x.box2indexwindow((.1, 19), 3, True) == (1, 6)
    assert x.box2indexwindow((19, 1), 3, True) is None
    assert x.box2indexwindow((19, 1), 3, False) == (7, 0)
    assert x.box2indexwindow((.1, 1), 3, False) == (0, 0)
    assert x.box2indexwindow((.1, 1), 3, True) is None
    assert x.box2indexwindow((1, .1), 3, True) == (1, 7)
    assert x.box2indexwindow((9.7, 29.5), 3, True) == (4, 2)
    assert x.box2indexwindow((1.80, 21.1), 1, True) == (1, 1)
    assert x.box2indexwindow((16.2, 31), 3, True) == (7, 3)

    assert x.box2indexwindow((19.9, .1), 3, innerapprox=True) is None
    assert x.box2indexwindow((2.4, 2.6), 3, innerapprox=True) is None

    # wrap around with overapproximation
    assert x.box2indexwindow((19.9, .1), 3, innerapprox=False) == (7, 0)
    assert x.box2indexwindow((39.9, 20.1), 3, innerapprox=False) == (7, 0)
    assert x.box2indexwindow((9.9, 9.8), 3, innerapprox=False) == (4, 3)
    assert x.box2indexwindow((29.9, 29.8), 3, innerapprox=False) == (4, 3)
    assert x.box2indexwindow((29.9, 9.8), 3, innerapprox=False) == (4, 3)
    assert x.box2indexwindow((19.9, 19.8), 3,
                             innerapprox=False) == (0, 7)  # total cover
    assert x.box2indexwindow((39.9, 39.8), 3,
                             innerapprox=False) == (0, 7)  # total cover

    # Over and under approximations of boxes that align exactly with the grid are the same
    assert x.conc2pred(mgr, 'x', (5, 15), 4,
                       innerapprox=True) == x.conc2pred(mgr,
                                                        'x', (5, 15),
                                                        4,
                                                        innerapprox=False)
    assert x.conc2pred(mgr, 'x', (0, 5), 4,
                       innerapprox=True) == x.conc2pred(mgr,
                                                        'x', (0, 5),
                                                        4,
                                                        innerapprox=False)
    assert x.conc2pred(mgr, 'x', (15, 5), 4,
                       innerapprox=True) == x.conc2pred(mgr,
                                                        'x', (15, 5),
                                                        4,
                                                        innerapprox=False)
    assert x.conc2pred(mgr, 'x', (0, 20), 4,
                       innerapprox=True) == x.conc2pred(mgr,
                                                        'x', (20, 40),
                                                        4,
                                                        innerapprox=False)
    """
Exemple #15
0
def setup(init=False):

    mgr = BDD()
    mgr.configure(
        reordering=False
    )  # Reordering causes too much time overhead for minimal gain.
    subsys = {}
    subsys['x'] = Interface(mgr, {
        'x': xspace,
        'vx': vxspace,
        'theta': thetaspace,
        't': thrust
    }, {'xnext': xspace})
    subsys['y'] = Interface(mgr, {
        'y': yspace,
        'vy': vyspace,
        'theta': thetaspace,
        't': thrust
    }, {'ynext': yspace})
    subsys['vx'] = Interface(
        mgr, {
            'vx': vxspace,
            'theta': thetaspace,
            'omega': omegaspace,
            't': thrust,
            's': side
        }, {'vxnext': vxspace})
    subsys['vy'] = Interface(
        mgr, {
            'vy': vyspace,
            'theta': thetaspace,
            'omega': omegaspace,
            't': thrust,
            's': side
        }, {'vynext': vyspace})
    subsys['theta'] = Interface(mgr, {
        'theta': thetaspace,
        'omega': omegaspace,
        's': side
    }, {'thetanext': thetaspace})
    subsys['omega'] = Interface(mgr, {
        'omega': omegaspace,
        's': side
    }, {'omeganext': omegaspace})

    # Coarse, but exhaustive abstraction of submodules.
    if init:
        iter_coarseness = {
            'x': {
                'x': 7,
                'vx': 5,
                'theta': 2
            },
            'y': {
                'y': 7,
                'vy': 5,
                'theta': 2
            },
            'vx': {
                'vx': 5,
                'theta': 4,
                'omega': 3
            },
            'vy': {
                'vy': 5,
                'theta': 4,
                'omega': 3
            },
            'theta': {
                'theta': 5,
                'omega': 4
            },
            'omega': {
                'omega': 4
            }
        }
        # iter_coarseness = {k: {k_: v_ + 1 for k_, v_ in v.items()} for k, v in iter_coarseness.items()}
        # iter_coarseness = sysview
        initabs_start = time.time()
        for i in states:
            print("Refining", i, "module")
            print("Iter Coarseness:", iter_coarseness[i])
            print("Recording Coarseness:",
                  {k: v
                   for k, v in sysview[i].items() if k in subsys[i].vars})
            subsys[i] = coarse_abstract(subsys[i], iter_coarseness[i],
                                        sysview[i])
            print(len(mgr), "manager nodes after first pass")
            subsys[i].check()
            print("Subsys", i, "ND ratio:", nd_ratio(subsys[i]))

            subsys[i] = coarse_abstract(subsys[i],
                                        iter_coarseness[i],
                                        sysview[i],
                                        shift_frac=0.5)
            print(len(mgr), "manager nodes after second pass")
            subsys[i].check()
            print("Subsys", i, "ND ratio:", nd_ratio(subsys[i]), "\n")

            mgr.reorder(
                order_heuristic(mgr, [
                    'x', 'y', 'vx', 'vy', 'theta', 'omega', 't', 's', 'xnext',
                    'ynext', 'vxnext', 'vynext', 'thetanext', 'omeganext'
                ]))

        print("Coarse Initial Abstraction Time (s): ",
              time.time() - initabs_start)

    return mgr, subsys
Exemple #16
0
def test_sin_sqrt_comp():
    def containszero(left, right):
        """Determine if 0 is contained in a periodic interval [left,right]. Possible that right < left."""
        # Map to interval [-pi,pi]
        left = ((left + np.pi) % (np.pi * 2)) - np.pi
        left = left - 2 * np.pi if left > np.pi else left
        right = ((right + np.pi) % (np.pi * 2)) - np.pi
        right = right - 2 * np.pi if right > np.pi else right

        if right < left:
            if left <= 0:
                return True
        else:
            if left <= 0 and right >= 0:
                return True

        return False

    def maxmincos(left, right):
        """Compute the maximum and minimum values of cos in an interval."""
        if containszero(left, right) is True:
            maxval = 1
        else:
            maxval = max([np.cos(left), np.cos(right)])

        if containszero(left + np.pi, right + np.pi) is True:
            minval = -1
        else:
            minval = min([np.cos(left), np.cos(right)])

        return (minval, maxval)

    def maxminsin(left, right):
        """Compute the maximum and minimum values of sin in an interval."""
        return maxmincos(left - np.pi / 2, right - np.pi / 2)

    mgr = BDD()

    sinout = DynamicCover(-1.2, 1.2)
    sinin = DynamicCover(-2 * np.pi, 2 * np.pi, periodic=True)

    # Sin module
    sinmod = Interface(mgr, {'sin': sinin}, {'sout': sinout})

    # Sqrt module
    sqrtout = DynamicCover(0, 1.2)
    sqrtmod = Interface(mgr, {'sout': sinout}, {'sqrt': sqrtout})

    comp = CompositeInterface([sinmod, sqrtmod])

    def random_input_gen(module: Interface, scale: float) -> dict:
        iobox = dict()
        for invar, space in module.inputs.items():
            if isinstance(space, ContinuousCover):
                width = scale * space.width()
                if space.periodic:
                    left = space.lb + np.random.rand() * space.width()
                else:
                    left = space.lb + np.random.rand() * (space.width() -
                                                          width)
                right = left + width
                iobox.update({invar: (left, right)})
        return iobox

    precision = {'sin': 9, 'sout': 9, 'sqrt': 9}

    # Learn sin module
    from redax.visualizer import scatter2D
    for i in range(200):
        iobox = random_input_gen(sinmod, scale=.01)
        out = maxminsin(iobox['sin'][0], iobox['sin'][1])
        iobox.update({'sout': (out[0], out[1])})

        # No errors should be raised
        sinmod = sinmod.io_refined(iobox, silent=False, nbits=precision)
        comp = comp.io_refined(iobox, nbits=precision)
        assert sinmod == comp.children[0]

    # Learn sqrt module
    for i in range(200):
        iobox = random_input_gen(sqrtmod, scale=.1)
        if iobox['sout'][0] < 0 or iobox['sout'][1] < 0:
            continue
        out = (math.sqrt(iobox['sout'][0]), math.sqrt(iobox['sout'][1]))
        iobox.update({'sqrt': out})
        sqrtmod = sqrtmod.io_refined(iobox, silent=True, nbits=precision)
        comp = comp.io_refined(iobox, nbits=precision)
        assert sqrtmod == comp.children[1]

    # sinroot = (sinmod >> sqrtmod).ohidden(['sout'])
    sinroot = (comp.children[0] >> comp.children[1]).ohidden(['sout'])
    assert set(sinroot.vars) == {'sin', 'sqrt'}
    assert sinroot.pred != mgr.false
    sinroot.check()
Exemple #17
0
def test_dynamic_module():
    mgr = BDD()

    inputs = {
        'x': DynamicCover(0, 16),
        'y': DynamicCover(0, 4),
    }
    output = {'z': DynamicCover(0, 4)}

    h = Interface(mgr, inputs, output)

    # Rename inputs
    assert set(h.inputs) == {'x', 'y'}
    assert set(h.outputs) == {'z'}
    g = ('j', 'x') >> h >> ('z', 'r')
    assert set(g.inputs) == {'j', 'y'}
    assert set(g.outputs) == {'r'}
    assert g == h.renamed(x='j', z='r')

    precision = {'j': 4, 'y': 3, 'r': 3}
    bittotal = sum(precision.values())

    assert g.count_io_space(bittotal) == approx(1024)
    assert g.count_io(bittotal) == approx(0)
    g = g.io_refined({
        'j': (2.9, 10.1),
        'y': (2.4, 3.8),
        'r': (2.1, 3.1)
    },
                     nbits=precision)
    assert g.count_io(bittotal) == approx(42)  # = 7 * 2 * 3

    # Adding approximately the same transitions twice does nothing due to quantization
    oldpred = g.pred
    g = g.io_refined({
        'j': (3., 10.),
        'y': (2.5, 3.8),
        'r': (2.1, 3.1)
    },
                     nbits=precision)
    assert g.pred == oldpred

    assert (g).pred.support == {
        'j_0', 'j_1', 'j_2', 'j_3', 'y_0', 'y_1', 'y_2', 'r_0', 'r_1', 'r_2'
    }
    assert (g >> ('r', 'z')).pred.support == {
        'j_0', 'j_1', 'j_2', 'j_3', 'y_0', 'y_1', 'y_2', 'z_0', 'z_1', 'z_2'
    }

    assert g.nonblock() == g.input_to_abs({
        'j': (3., 10.),
        'y': (2.5, 3.8)
    },
                                          nbits=precision)  # No inputs block
    assert g.nonblock() == (g.ohidden(g.outputs).pred)

    # Identity test for input and output renaming
    assert ((g >> ('r', 'z')) >> ('z', 'r')) == g
    assert (('j', 'w') >> (('w', 'j') >> g)) == g

    # Parallel composition
    assert set((g * h).outputs) == {'z', 'r'}
    assert set((g * h).inputs) == {'x', 'y', 'j'}

    # Series composition with disjoint I/O yields parallel composition
    assert (g >> h) == (g * h)
    assert (g >> h) == g.composed_with(h)
    assert (g >> h) == h.composed_with(g)
    assert (g * h) == h.composed_with(g)

    # Out of bounds errors
    with raises(OutOfDomainError):
        g = g.io_refined({
            'j': (3., 10.),
            'y': (2.5, 3.8),
            'r': (2.1, 4.6)
        },
                         silent=False,
                         nbits=precision)