mtl-aas/stl/fastboolean_eval.py
Marcell Vazquez-Chanlatte efcfbf7f0d refactor fastboolean_eval
2017-04-20 21:30:23 -07:00

78 lines
1.8 KiB
Python

from functools import singledispatch, reduce
from operator import and_, or_
from bitarray import bitarray
import stl.ast
from stl.boolean_eval import eval_terms, op_lookup
def pointwise_sat(stl):
f = pointwise_satf(stl)
return lambda x, t: bool(int(f(x, [t]).to01()))
@singledispatch
def pointwise_satf(stl):
raise NotImplementedError
def bool_op(stl, conjunction=False):
binop = and_ if conjunction else or_
fs = [pointwise_satf(arg) for arg in stl.args]
return lambda x, t: reduce(binop, (f(x, t) for f in fs))
@pointwise_satf.register(stl.Or)
def _(stl):
return bool_op(stl, conjunction=False)
@pointwise_satf.register(stl.And)
def _(stl):
return bool_op(stl, conjunction=True)
def get_times(x, lo, hi, tau):
return [min(tau + t2, x.index[-1]) for t2 in x[lo:hi].index]
def temporal_op(stl, lo, hi, conjunction=False):
fold = bitarray.all if conjunction else bitarray.any
f = pointwise_satf(stl.arg)
def sat_comp(x,t):
return bitarray([fold(f(x, get_times(x, lo, hi, tau))) for tau in t])
return sat_comp
@pointwise_satf.register(stl.F)
def _(stl):
lo, hi = stl.interval
return temporal_op(stl, lo, hi, conjunction=False)
@pointwise_satf.register(stl.G)
def _(stl):
lo, hi = stl.interval
return temporal_op(stl, lo, hi, conjunction=True)
@pointwise_satf.register(stl.Neg)
def _(stl):
return lambda x,t: ~pointwise_satf(stl.arg)(x, t)
@pointwise_satf.register(stl.AtomicPred)
def _(stl):
def sat_comp(x, t):
sat = bitarray()
[sat.append(x[str(stl.id)][tau]) for tau in t]
return sat
return sat_comp
@pointwise_satf.register(stl.LinEq)
def _(stl):
op = op_lookup[stl.op]
def sat_comp(x, t):
sat = bitarray()
[sat.append(op(eval_terms(stl, x, tau), stl.const)) for tau in t]
return sat
return sat_comp