def test_slice():
    sig1 = signal(DATA1, start=0, end=4, tag='x')
    sig2 = sig1[-float('inf'):float('inf')][0:4]
    assert sig1 == sig2

    assert sig1[1:2] == signal(DATA1, start=1, end=2, tag='x')
    assert len(sig1[1:2].values()) == 1
def test_make_signal():
    sig1 = signal(DATA1, start=0, end=4, tag='x')
    sig2 = signal(DATA1, start=1, end=2, tag='x')
    assert sig1 | sig2 == sig1

    assert set(fn.pluck(0, DATA1)) == set(sig1.times())
    assert set(fn.pluck(0, DATA1)) > set(sig2.times())
    assert len(sig2.times()) == 1
    assert set(fn.pluck(1, DATA1)) == {v['x'] for v in sig1.values()}
def to_signal(ts_mapping) -> DiscreteSignal:
    if isinstance(ts_mapping, DiscreteSignal):
        return ts_mapping

    start = min(fn.pluck(0, fn.cat(ts_mapping.values())))
    signals = (signal(v, start, OO, tag=k) for k, v in ts_mapping.items())
    return reduce(op.or_, signals)
Example #4
0
def test_eval_with_signal():
    spec = mtl.parse('F(above_three)')

    raw_data = signal([(0, 1), (1, 2), (2, 3)], start=0, end=10, tag='a')
    processed = raw_data.map(lambda val: val['a'] > 3, tag="above_three")

    assert not spec(processed, quantitative=False)
    assert spec(processed, quantitative=True) == 0
def test_retag():
    sig1 = signal(DATA1, start=0, end=4, tag='x')
    assert sig1 == sig1.retag({'w': 'n'})

    sig2 = sig1.retag({'x': 'y'})
    assert sig2.tags == {'y'}

    assert sig2.retag({'y': 'x'}) == sig1
    def _eval(x):
        tmp = f(x)
        assert b >= a
        if b > a:
            if a < b < OO:
                if a != 0:
                    return signal(_rolling(tmp, 0, b - a),
                                  tmp.start,
                                  tmp.end - b if b < tmp.end else tmp.end,
                                  tag=phi) << a
                else:
                    return signal(_rolling(tmp, a, b),
                                  tmp.start,
                                  tmp.end - b if b < tmp.end else tmp.end,
                                  tag=phi)
            else:
                return signal(_rolling_inf(tmp),
                              tmp.start,
                              tmp.end - b if b < tmp.end else tmp.end,
                              tag=phi)
            return tmp.rolling(a, b).map(_min, tag=phi)

        return tmp.retag({phi.arg: phi})
def test_rolling():
    sig1 = signal(DATA1, start=0, end=4, tag='x')
    sig2 = sig1.rolling(0, 3)
    assert {v['x'] for v in sig1.values()} == set(sig2[0]['x'])

    sig3 = sig1.rolling(0, 2)
    assert {v['x'] for v in sig1[:2].values()} == set(sig3[0]['x'])

    sig4 = sig1.rolling(0, 1)
    assert {v['x'] for v in sig1[:1].values()} == set(sig4[0]['x'])

    sig5 = sig1.rolling(-1.1, 1.1)
    assert {v['x'] for v in sig1.values()} == set(sig5[1.1]['x'])
    assert {v['x'] for v in sig1[2:].values()} == set(sig5[3.1]['x'])
def test_par_compose():
    sig1 = signal(DATA1, start=0, end=4, tag='x')
    assert sig1 | sig1 == sig1

    sig2 = sig1 | sig1 >> 0.5
    assert len(sig2.values()) == 2*len(sig1.values())

    sig3 = sig1 | sig1 >> 1
    assert len(sig3.values()) == len(sig1.values())+1

    sig4 = sig1.map(lambda v: -v['x'], tag='y')
    sig5 = (sig1 | sig4).map(lambda v: sum(v.values()), tag='z')
    assert len(sig5.times()) == len(sig1.times())
    assert all(v['z'] == 0 for v in sig5.values())
def test_append():
    sig1 = signal(DATA1, start=0, end=4, tag='x')
    sig2 = sig1 @ sig1
    assert len(sig2.values()) == 2*len(sig1.values())
    assert sig1.start == sig2.start
    assert sig2.end == 2*sig1.end
Example #10
0
def test_time_shifts():
    sig1 = signal(DATA1, start=0, end=4, tag='x')
    assert (sig1 << 2) == (sig1 >> -2)
    assert (sig1 << 2) >> 2 == sig1
Example #11
0
 def TOP(self):
     return signal([(0, self.const_true)], start=-OO, end=OO, tag=ast.TOP)
Example #12
0
def test_repr():
    out = repr(signal(DATA1, start=0, end=4, tag='x'))
    assert out == "start, end: [0, 4)\n" \
        "data: [(0, {'x': 1}), (1, {'x': 1.1}), (2, {'x': 3})]"
Example #13
0
def test_transform():
    sig1 = signal(DATA1, start=0, end=4, tag='x')
    assert sig1.transform(lambda v: v) == sig1
    assert sig1.transform(lambda v: {'y': v['x']}) \
        == sig1.retag({'x': 'y'})
def const_trace(x):
    return signal([(0, x)], start=0, end=oo)
Example #15
0
 def BOT(self):
     return signal([(0, self.const_false)], start=-OO, end=OO, tag=ast.BOT)
Example #16
0
def test_filter():
    sig1 = signal(DATA1, start=0, end=4, tag='x')
    sig2 = sig1.filter(lambda v: v['x'] > 2)
    assert len(sig2.items()) == 1
    assert sig2[2]['x'] == 3
 def _eval(x):
     sig = dense_compose(f1(x), f2(x), init=logic.const_false)
     sig = sig | interp_all(sig, x.start)
     data = apply_implies(phi.arg1, phi.arg2, sig, logic)
     return signal(data, x.start, x.end, tag=phi)
Example #18
0
def to_signal(ts_mapping):
    start = min(fn.pluck(0, fn.cat(ts_mapping.values())))
    assert start >= 0
    signals = (signal(v, start, OO, tag=k) for k, v in ts_mapping.items())
    return reduce(op.or_, signals)
def eval_mtl_constant_number(phi, dt, logic):
    return lambda _: signal([(0, phi)], start=-OO, end=OO, tag=phi)
 def _eval(x):
     sig = dense_compose(f1(x), f2(x), init=-OO)
     data = apply_weak_until(phi.arg1, phi.arg2, sig)
     return signal(data, x.start, OO, tag=phi)
# TODO: figure out how to deduplicate this with robustness
# - Abstract as working on distributive lattice

import operator as op
from collections import defaultdict
from functools import reduce, singledispatch

import funcy as fn
from discrete_signals import signal, DiscreteSignal

from mtl import ast

OO = float('inf')
CONST_FALSE = signal([(0, -1)], start=-OO, end=OO, tag=ast.BOT)
CONST_TRUE = signal([(0, 1)], start=-OO, end=OO, tag=ast.TOP)


def to_signal(ts_mapping) -> DiscreteSignal:
    if isinstance(ts_mapping, DiscreteSignal):
        return ts_mapping

    start = min(fn.pluck(0, fn.cat(ts_mapping.values())))
    signals = (signal(v, start, OO, tag=k) for k, v in ts_mapping.items())
    return reduce(op.or_, signals)


def interp(sig, t, tag=None):
    # TODO: return function that interpolates the whole signal.
    sig = sig.project({tag})
    idx = max(sig.data.bisect_right(t) - 1, 0)
    key = sig.data.keys()[idx]
def interp_all(sig, t, end=OO):
    v = fn.map(lambda u: signal([(t, interp(sig, t, u))], t, end, u), sig.tags)
    return reduce(op.__or__, v)
def eval_mtl(phi, dt, logic):
    return lambda _: signal([(0, phi)], start=-OO, end=OO, tag=phi)
Example #24
0
def test_project():
    sig1 = signal(DATA1, start=0, end=4, tag='x')
    sig2 = signal(DATA1, start=0, end=4, tag='y')
    assert (sig1 | sig2).project('x') == sig1
Example #25
0
 def _eval(x):
     sig = dense_compose(f1(x), f2(x), init=-OO)
     sig = sig | interp_all(sig, x.start, OO)  # Force valuation at start
     data = apply_weak_until(phi.arg1, phi.arg2, sig)
     return signal(data, x.start, OO, tag=phi)