added horizon option to discretize
This commit is contained in:
parent
c1a6e18068
commit
7798fe679e
1 changed files with 27 additions and 15 deletions
32
stl/utils.py
32
stl/utils.py
|
|
@ -101,13 +101,14 @@ def implicit_validity_domain(phi, trace):
|
||||||
def require_discretizable(func):
|
def require_discretizable(func):
|
||||||
@wraps(func)
|
@wraps(func)
|
||||||
def _func(phi, dt, *args, **kwargs):
|
def _func(phi, dt, *args, **kwargs):
|
||||||
|
if 'horizon' not in kwargs:
|
||||||
assert is_discretizable(phi, dt)
|
assert is_discretizable(phi, dt)
|
||||||
return func(phi, dt, *args, **kwargs)
|
return func(phi, dt, *args, **kwargs)
|
||||||
|
|
||||||
return _func
|
return _func
|
||||||
|
|
||||||
|
|
||||||
def scope(phi, dt, *, _t=0):
|
def scope(phi, dt, *, _t=0, horizon=oo):
|
||||||
if isinstance(phi, Next):
|
if isinstance(phi, Next):
|
||||||
_t += dt
|
_t += dt
|
||||||
elif isinstance(phi, (G, F)):
|
elif isinstance(phi, (G, F)):
|
||||||
|
|
@ -115,32 +116,44 @@ def scope(phi, dt, *, _t=0):
|
||||||
elif isinstance(phi, Until):
|
elif isinstance(phi, Until):
|
||||||
_t += float('inf')
|
_t += float('inf')
|
||||||
|
|
||||||
return max((scope(c, dt, _t=_t) for c in phi.children), default=_t)
|
_scope = max((scope(c, dt, _t=_t) for c in phi.children), default=_t)
|
||||||
|
return min(_scope, horizon)
|
||||||
|
|
||||||
|
|
||||||
# Code to discretize a bounded STL formula
|
# Code to discretize a bounded STL formula
|
||||||
|
|
||||||
|
|
||||||
@require_discretizable
|
@require_discretizable
|
||||||
def discretize(phi, dt, distribute=False):
|
def discretize(phi, dt, distribute=False, *, horizon=None):
|
||||||
phi = _discretize(phi, dt)
|
if horizon is None:
|
||||||
|
horizon = oo
|
||||||
|
|
||||||
|
phi = _discretize(phi, dt, horizon)
|
||||||
return _distribute_next(phi) if distribute else phi
|
return _distribute_next(phi) if distribute else phi
|
||||||
|
|
||||||
|
|
||||||
def _discretize(phi, dt):
|
def _discretize(phi, dt, horizon):
|
||||||
if isinstance(phi, (LinEq, AtomicPred, _Top, _Bot)):
|
if isinstance(phi, (LinEq, AtomicPred, _Top, _Bot)):
|
||||||
return phi
|
return phi
|
||||||
|
|
||||||
children = tuple(_discretize(arg, dt) for arg in phi.children)
|
if not isinstance(phi, (F, G, Until)):
|
||||||
|
children = tuple(_discretize(arg, dt, horizon) for arg in phi.children)
|
||||||
if isinstance(phi, (And, Or)):
|
if isinstance(phi, (And, Or)):
|
||||||
return bind(phi).args.set(children)
|
return bind(phi).args.set(children)
|
||||||
elif isinstance(phi, (Neg, Next)):
|
elif isinstance(phi, (Neg, Next)):
|
||||||
return bind(phi).arg.set(children[0])
|
return bind(phi).arg.set(children[0])
|
||||||
|
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
elif isinstance(phi, Until):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
# Only remaining cases are G and F
|
# Only remaining cases are G and F
|
||||||
psi = children[0]
|
upper = min(phi.interval.upper, horizon)
|
||||||
l, u = round(phi.interval.lower / dt), round(phi.interval.upper / dt)
|
l, u = round(phi.interval.lower / dt), round(upper / dt)
|
||||||
psis = (next(psi, i) for i in range(l, u + 1))
|
|
||||||
|
psis = (next(_discretize(phi.arg, dt, horizon - i), i)
|
||||||
|
for i in range(l, u + 1))
|
||||||
opf = andf if isinstance(phi, G) else orf
|
opf = andf if isinstance(phi, G) else orf
|
||||||
return opf(*psis)
|
return opf(*psis)
|
||||||
|
|
||||||
|
|
@ -174,7 +187,6 @@ def is_discretizable(phi, dt):
|
||||||
_interval_discretizable(c.interval, dt) for c in phi.walk()
|
_interval_discretizable(c.interval, dt) for c in phi.walk()
|
||||||
if isinstance(c, (F, G)))
|
if isinstance(c, (F, G)))
|
||||||
|
|
||||||
|
|
||||||
# EDSL
|
# EDSL
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue