Beispiel #1
0
def test_zero_dynamics():
    'test a system with zero dynamic (only should process one frame)'

    ha = HybridAutomaton()

    # with time and affine variable
    mode = ha.new_mode('mode')
    mode.set_dynamics([[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]])

    # initial set
    init_lpi = lputil.from_box([(-5, -5), (0, 1), (0, 0), (1, 1)], mode)
    init_list = [StateSet(init_lpi, mode)]

    # settings
    settings = HylaaSettings(math.pi/4, 20*math.pi)
    settings.stdout = HylaaSettings.STDOUT_VERBOSE
    settings.plot.plot_mode = PlotSettings.PLOT_NONE
    
    core = Core(ha, settings)

    core.setup(init_list)
    core.do_step() # pop
    core.do_step() # propagate and remove

    assert core.aggdag.get_cur_state() is None, "cur state should be none, since mode dynamics were zero"
Beispiel #2
0
def test_redundant_inv_transition():
    'test removing of redundant invariants with a transition'

    ha = HybridAutomaton()

    mode1 = ha.new_mode('mode1')
 
    # dynamics: x' = 1, y' = 1, a' = 0
    mode1.set_dynamics([[0, 0, 1], [0, 0, 1], [0, 0, 0]])

    # invariant: x <= 2.5
    mode1.set_invariant([[1, 0, 0]], [2.5])

    mode2 = ha.new_mode('mode2')
    mode2.set_dynamics([[0, 0, 0], [0, 0, 0], [0, 0, 0]])

    ha.new_transition(mode1, mode2).set_guard([[-1, 0, 0]], [-2.5]) # x >= 2.5

    # initial set has x0 = [0, 1]
    init_lpi = lputil.from_box([(0, 1), (0, 1), (1, 1)], mode1)
    init_list = [StateSet(init_lpi, mode1)]

    # settings, step size = 0.1
    settings = HylaaSettings(0.1, 5.0)
    settings.stdout = HylaaSettings.STDOUT_DEBUG
    settings.plot.plot_mode = PlotSettings.PLOT_NONE

    core = Core(ha, settings)
    core.setup(init_list)

    for _ in range(20):
        core.do_step()

    assert core.result.last_cur_state.lpi.get_num_rows() == 3 + 2*3 + 1 # 3 for basis matrix, 2*3 for init constraints

    assert len(core.aggdag.waiting_list) > 2

    core.plotman.run_to_completion()
Beispiel #3
0
def test_agg_ha():
    'test aggregation with the harmonic oscillator dynamics'

    ha = HybridAutomaton('Deaggregation Example')

    m1 = ha.new_mode('green')
    m1.set_dynamics([[0, 1], [-1, 0]])

    m2 = ha.new_mode('cyan')
    m2.set_dynamics([[0, 0, 0], [0, 0, -2], [0, 0, 0]])

    t1 = ha.new_transition(m1, m2)
    t1.set_guard_true()
    reset_mat = [[1, 0], [0, 1], [0, 0]]
    t1.set_reset(reset_mat, [[0], [0], [1]], [[1], [-1]], [1, -1]) # create 3rd variable with a0 = 1

    mode = ha.modes['green']
    init_lpi = lputil.from_box([(-5, -4), (-0.5, 0.5)], mode)
    
    init_list = [StateSet(init_lpi, mode)]

    step = math.pi/4
    settings = HylaaSettings(step, 2*step)
    settings.process_urgent_guards = True
    settings.plot.plot_mode = PlotSettings.PLOT_NONE
    settings.stdout = HylaaSettings.STDOUT_DEBUG

    core = Core(ha, settings)
    core.setup(init_list)

    core.do_step() # pop
    #xs, ys = zip(*core.cur_state.verts(core.plotman))
    #plt.plot(xs, ys, 'k-')
    
    core.do_step() # 0
    #xs, ys = zip(*core.cur_state.verts(core.plotman))
    #plt.plot(xs, ys, 'k-')

    core.do_step() # 1
    #xs, ys = zip(*core.cur_state.verts(core.plotman))
    #plt.plot(xs, ys, 'k-')
    
    core.do_step() # 2
    assert len(core.aggdag.waiting_list) > 1

    #for state in core.waiting_list:
    #    xs, ys = zip(*state.verts(core.plotman))
    #    plt.plot(xs, ys, 'k-')
    
    core.do_step() # pop
    assert not core.aggdag.waiting_list

    lpi = core.aggdag.get_cur_state().lpi

    # 3 constraints from basis matrix
    # 2 aggregation directions from premode arnoldi, +1 from null space
    # + 2 more aggregation directions from box (3rd is omited since it's exactly the same as null space direction)

    #print(lpi)
    #xs, ys = zip(*core.cur_state.verts(core.plotman))
    #plt.plot(xs, ys, 'r--')
    #plt.show()

    assert lpi.get_num_rows() == 3 + 2 * (5)
    assert lputil.is_point_in_lpi((-5, 2, 1), lpi)
Beispiel #4
0
def test_inputs_reset():
    'test a system with both inputs and a reset'

    # 2-d system with one input
    # x' = x, y' = u, u \in [1, 1]
    # x0 = 1, y0 = 0
    # inv1: y <= 2.5
    
    # guard: y >= 2.5
    # reset: x := 1, y += 2 [should go from (e^3, 3.0) -> (1, 5.0)]

    # mode2:
    # x' = 2x, y' = Bu, u \in [1, 2], B = 2
    # (1, 5.0) -> (e^2, [7, 9]) -> (e^4, [9, 13])

    # mode2 -> error y >= 13

    ha = HybridAutomaton()
    m1 = ha.new_mode('m1')
    m1.set_dynamics([[1, 0], [0, 0]])
    m1.set_inputs([[0], [1]], [[1], [-1]], [1, -1], allow_constants=True)
    m1.set_invariant([[0, 1]], [2.5])

    m2 = ha.new_mode('m2')
    m2.set_dynamics([[2, 0], [0, 0]])
    m2.set_inputs([[0], [2]], [[1], [-1]], [2, -1])

    error = ha.new_mode('error')

    t1 = ha.new_transition(m1, m2)
    t1.set_guard([[0, -1]], [-2.5]) # y >= 2.5
    reset_mat = [[0, 0], [0, 1]]
    min_mat = np.identity(2)
    min_cons = [[1, 0], [-1, 0], [0, 1], [0, -1]]
    min_rhs = [1, -1, 2, -2]
    t1.set_reset(reset_mat, min_mat, min_cons, min_rhs)

    t2 = ha.new_transition(m2, error)
    t2.set_guard([0, -1], [-13]) # y >= 13

    init_box = [[1, 1], [0, 0]]
    lpi = lputil.from_box(init_box, m1)

    settings = HylaaSettings(1.0, 10.0)
    settings.stdout = HylaaSettings.STDOUT_VERBOSE
    settings.plot.store_plot_result = True
    settings.plot.plot_mode = PlotSettings.PLOT_NONE

    core = Core(ha, settings)
    init_list = [StateSet(lpi, m1)]
    core.setup(init_list)

    core.do_step() # pop
    core.do_step() # continuous_post() to time 1

    lpi = core.result.last_cur_state.lpi

    assert lpi.get_names() == ['m0_i0', 'm0_i1', 'm0_c0', 'm0_c1', 'm0_ti0', 'm0_ti1', 'm0_I0']

    assert_verts_is_box(lpplot.get_verts(lpi), [[math.exp(1), math.exp(1)], [1, 1]])

    core.do_step() # continuous_post() to time 2
    assert_verts_is_box(lpplot.get_verts(core.result.last_cur_state.lpi), [[math.exp(2), math.exp(2)], [2, 2]])

    core.do_step() # continuous_post() to time 3
    assert_verts_is_box(lpplot.get_verts(core.result.last_cur_state.lpi), [[math.exp(3), math.exp(3)], [3, 3]])

    core.do_step() # trim to invariant
    assert core.aggdag.get_cur_state() is None
    assert len(core.aggdag.waiting_list) == 1

    core.run_to_completion()

    result = core.result

    # reset: x := 1, y += 2 [should go from (e^3, 3.0) -> (1, 5.0)]
    # (1, 5.0) -> (e^2, [7, 9]) -> (e^4, [9, 13])
    polys2 = [obj[0] for obj in result.plot_data.mode_to_obj_list[0]['m2']]
    assert_verts_is_box(polys2[0], [[1, 1], [5, 5]])
    assert_verts_is_box(polys2[1], [[math.exp(2), math.exp(2)], [7, 9]])
    assert_verts_is_box(polys2[2], [[math.exp(4), math.exp(4)], [9, 13]])
    assert len(polys2) == 3

    # check counterexamples
    assert len(result.counterexample) == 2
    
    c1 = result.counterexample[0]
    assert c1.mode == m1
    assert c1.outgoing_transition == t1
    assert np.allclose(c1.start, [1, 0])
    assert np.allclose(c1.end, [math.exp(3), 3])
    assert len(c1.reset_minkowski_vars) == 2
    assert abs(c1.reset_minkowski_vars[0] - 1) < 1e-9
    assert abs(c1.reset_minkowski_vars[1] - 2) < 1e-9

    assert len(c1.inputs) == 3
    for i in c1.inputs:
        assert len(i) == 1
        assert abs(i[0] - 1) < 1e-9

    c2 = result.counterexample[1]
    assert c2.mode == m2
    assert c2.outgoing_transition == t2
    assert np.allclose(c2.start, [1, 5])
    assert np.allclose(c2.end, [math.exp(4), 13])
    assert not c2.reset_minkowski_vars
    assert len(c2.inputs) == 2

    for i in c2.inputs:
        assert len(i) == 1
        assert abs(i[0] - 2) < 1e-9
def fail_deagg_counterexample():
    'test that aggregation with a counterexample'
    # init: x0, y0 \in [0, 1], step = 1.0
    #
    # m1 dynamics: x' == 1, y' == 0,
    # m1 invariant: x <= 3
    # m1 -> m2 guard: True
    # m2 dynamics: x' == 0, y' == 1
    # m2 -> error: y >= 3

    ha = HybridAutomaton()

    # mode one: x' = 1, y' = 0, a' = 0
    m1 = ha.new_mode('m1')
    m1.set_dynamics([[0, 0, 1], [0, 0, 0], [0, 0, 0]])

    # mode two: x' = 0, y' = 1, a' = 0
    m2 = ha.new_mode('m2')
    m2.set_dynamics([[0, 0, 0], [0, 0, 1], [0, 0, 0]])

    # invariant: x <= 3.0
    m1.set_invariant([[1, 0, 0]], [3.0])

    # guard: True
    trans1 = ha.new_transition(m1, m2, 'trans1')
    trans1.set_guard_true()

    error = ha.new_mode('error')
    trans2 = ha.new_transition(m2, error, 'trans2')
    trans2.set_guard([[0, -1, 0]], [-3])  # y >= 3

    # initial set has x0 = [0, 1], t = [0, 1], a = 1
    init_lpi = lputil.from_box([(0, 1), (0, 1), (1, 1)], m1)
    init_list = [StateSet(init_lpi, m1)]

    # settings, step size = 1.0
    settings = HylaaSettings(1.0, 10.0)
    settings.stdout = HylaaSettings.STDOUT_VERBOSE
    settings.plot.plot_mode = PlotSettings.PLOT_NONE
    settings.aggregation.deaggregation = True

    core = Core(ha, settings)

    core.setup(init_list)

    core.do_step()  # pop

    assert core.aggdag.cur_node is not None

    for _ in range(5):  # 4 + 1 step to leave invariant
        core.do_step()  # continuous post in m1

    core.do_step()  # pop

    # at this point, the state should be aggregated, but we should maintain one concrete state that's feasible
    cur_node = core.aggdag.cur_node
    assert cur_node.aggregated_state == core.aggdag.get_cur_state()

    assert cur_node.concrete_state is not None

    assert len(core.aggdag.roots) == 1
    root = core.aggdag.roots[0]

    assert root.op_list
    assert isinstance(
        root.op_list[0],
        OpTransition) and root.op_list[0].step == 1  # transition from x=[1, 2]
    assert isinstance(
        root.op_list[1],
        OpTransition) and root.op_list[1].step == 2  # transition from x=[2, 3]
    assert isinstance(
        root.op_list[2],
        OpTransition) and root.op_list[2].step == 3  # transition from x=[3, 4]
    assert isinstance(
        root.op_list[3],
        OpTransition) and root.op_list[3].step == 4  # transition from x=[4, 5]

    for s in range(4):
        assert root.op_list[s].transition == trans1 and root.op_list[
            s].poststate.is_concrete

    assert isinstance(root.op_list[4], OpInvIntersect)
    op4 = root.op_list[4]
    assert op4.step == 5 and op4.node == root and op4.i_index == 0 and not op4.is_stronger

    assert isinstance(
        root.op_list[5],
        OpTransition) and root.op_list[5].step == 5  # transition from x=[4, 4]

    assert isinstance(root.op_list[6], OpInvIntersect)
    op6 = root.op_list[6]
    assert op6.step == 6 and op6.node == root and op6.i_index == 0 and op6.is_stronger

    assert len(root.op_list) == 7

    core.run_to_completion()

    assert root.op_list[0].child_node == cur_node
    assert root.op_list[3].child_node == cur_node