reimplement evaluation using discrete-signals library
This commit is contained in:
parent
cfbdabf517
commit
dd6bd4b6be
12 changed files with 241 additions and 447 deletions
34
mtl/utils.py
34
mtl/utils.py
|
|
@ -2,18 +2,18 @@ import operator as op
|
|||
from functools import reduce, wraps
|
||||
from math import isfinite
|
||||
|
||||
import traces
|
||||
from discrete_signals import signal
|
||||
import numpy as np
|
||||
|
||||
import mtl.ast
|
||||
from mtl.ast import (And, F, G, Interval, Neg, Or, Next, Until,
|
||||
AtomicPred, _Top, _Bot)
|
||||
from mtl.ast import (And, G, Interval, Neg, Next, WeakUntil,
|
||||
AtomicPred, _Bot)
|
||||
|
||||
oo = float('inf')
|
||||
|
||||
|
||||
def const_trace(x):
|
||||
return traces.TimeSeries([(0, x), (oo, x)])
|
||||
return signal([(0, x)], start=0, end=oo)
|
||||
|
||||
|
||||
def require_discretizable(func):
|
||||
|
|
@ -29,9 +29,9 @@ def require_discretizable(func):
|
|||
def scope(phi, dt, *, _t=0, horizon=oo):
|
||||
if isinstance(phi, Next):
|
||||
_t += dt
|
||||
elif isinstance(phi, (G, F)):
|
||||
elif isinstance(phi, G):
|
||||
_t += phi.interval.upper
|
||||
elif isinstance(phi, Until):
|
||||
elif isinstance(phi, WeakUntil):
|
||||
_t += float('inf')
|
||||
|
||||
_scope = max((scope(c, dt, _t=_t) for c in phi.children), default=_t)
|
||||
|
|
@ -51,19 +51,19 @@ def discretize(phi, dt, distribute=False, *, horizon=None):
|
|||
|
||||
|
||||
def _discretize(phi, dt, horizon):
|
||||
if isinstance(phi, (AtomicPred, _Top, _Bot)):
|
||||
if isinstance(phi, (AtomicPred, _Bot)):
|
||||
return phi
|
||||
|
||||
if not isinstance(phi, (F, G, Until)):
|
||||
if not isinstance(phi, (G, WeakUntil)):
|
||||
children = tuple(_discretize(arg, dt, horizon) for arg in phi.children)
|
||||
if isinstance(phi, (And, Or)):
|
||||
if isinstance(phi, And):
|
||||
return phi.evolve(args=children)
|
||||
elif isinstance(phi, (Neg, Next)):
|
||||
return phi.evolve(arg=children[0])
|
||||
|
||||
raise NotImplementedError
|
||||
|
||||
elif isinstance(phi, Until):
|
||||
elif isinstance(phi, WeakUntil):
|
||||
raise NotImplementedError
|
||||
|
||||
# Only remaining cases are G and F
|
||||
|
|
@ -91,19 +91,19 @@ def _distribute_next(phi, i=0):
|
|||
|
||||
children = tuple(_distribute_next(c, i) for c in phi.children)
|
||||
|
||||
if isinstance(phi, (And, Or)):
|
||||
if isinstance(phi, And):
|
||||
return phi.evolve(args=children)
|
||||
elif isinstance(phi, (Neg, Next)):
|
||||
return phi.evolve(arg=children[0])
|
||||
|
||||
|
||||
def is_discretizable(phi, dt):
|
||||
if any(c for c in phi.walk() if isinstance(c, Until)):
|
||||
if any(c for c in phi.walk() if isinstance(c, WeakUntil)):
|
||||
return False
|
||||
|
||||
return all(
|
||||
_interval_discretizable(c.interval, dt) for c in phi.walk()
|
||||
if isinstance(c, (F, G)))
|
||||
if isinstance(c, G))
|
||||
|
||||
# EDSL
|
||||
|
||||
|
|
@ -113,7 +113,7 @@ def alw(phi, *, lo=0, hi=float('inf')):
|
|||
|
||||
|
||||
def env(phi, *, lo=0, hi=float('inf')):
|
||||
return F(Interval(lo, hi), phi)
|
||||
return ~alw(~phi, lo=lo, hi=hi)
|
||||
|
||||
|
||||
def andf(*args):
|
||||
|
|
@ -140,5 +140,9 @@ def next(phi, i=1):
|
|||
return phi >> i
|
||||
|
||||
|
||||
def until(phi, psi):
|
||||
return mtl.ast.WeakUntil(phi, psi) & env(psi)
|
||||
|
||||
|
||||
def timed_until(phi, psi, lo, hi):
|
||||
return env(psi, lo=lo, hi=hi) & alw(mtl.ast.Until(phi, psi), lo=0, hi=lo)
|
||||
return env(psi, lo=lo, hi=hi) & alw(until(phi, psi), lo=0, hi=lo)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue