reimplement evaluation using discrete-signals library

This commit is contained in:
Marcell Vazquez-Chanlatte 2018-09-24 00:55:43 -07:00
parent cfbdabf517
commit dd6bd4b6be
12 changed files with 241 additions and 447 deletions

View file

@ -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)