fixed inline context + added tests for inline context
This commit is contained in:
parent
f7f322148e
commit
7aed260d5d
3 changed files with 38 additions and 13 deletions
11
stl/ast.py
11
stl/ast.py
|
|
@ -78,6 +78,17 @@ class AST(object):
|
||||||
def atomic_predicates(self):
|
def atomic_predicates(self):
|
||||||
return set(AP_lens(self).Each().collect())
|
return set(AP_lens(self).Each().collect())
|
||||||
|
|
||||||
|
def inline_context(self, context):
|
||||||
|
phi, phi2 = self, None
|
||||||
|
|
||||||
|
def update(aps):
|
||||||
|
return tuple(context.get(ap, ap) for ap in aps)
|
||||||
|
|
||||||
|
while phi2 != phi:
|
||||||
|
phi2, phi = phi, AP_lens(phi).modify(update)
|
||||||
|
# TODO: this is hack to flatten the AST. Fix!
|
||||||
|
return phi
|
||||||
|
|
||||||
|
|
||||||
class _Top(AST):
|
class _Top(AST):
|
||||||
__slots__ = ()
|
__slots__ = ()
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,16 @@ from stl.hypothesis import SignalTemporalLogicStrategy
|
||||||
from hypothesis import given
|
from hypothesis import given
|
||||||
|
|
||||||
|
|
||||||
|
CONTEXT = {
|
||||||
|
stl.parse('AP1'): stl.parse('F(x > 4)'),
|
||||||
|
stl.parse('AP2'): stl.parse('(AP1) U (AP1)'),
|
||||||
|
stl.parse('AP3'): stl.parse('y < 4'),
|
||||||
|
stl.parse('AP4'): stl.parse('y < 3'),
|
||||||
|
stl.parse('AP5'): stl.parse('y + x > 4'),
|
||||||
|
}
|
||||||
|
APS = set(CONTEXT.keys())
|
||||||
|
|
||||||
|
|
||||||
@given(SignalTemporalLogicStrategy)
|
@given(SignalTemporalLogicStrategy)
|
||||||
def test_f_neg_or_canonical_form(phi):
|
def test_f_neg_or_canonical_form(phi):
|
||||||
phi2 = stl.utils.f_neg_or_canonical_form(phi)
|
phi2 = stl.utils.f_neg_or_canonical_form(phi)
|
||||||
|
|
@ -11,3 +21,19 @@ def test_f_neg_or_canonical_form(phi):
|
||||||
assert phi2 == phi3
|
assert phi2 == phi3
|
||||||
assert not any(
|
assert not any(
|
||||||
isinstance(x, (stl.ast.G, stl.ast.And)) for x in phi2.walk())
|
isinstance(x, (stl.ast.G, stl.ast.And)) for x in phi2.walk())
|
||||||
|
|
||||||
|
|
||||||
|
def test_inline_context_rigid():
|
||||||
|
phi = stl.parse('G(AP1)')
|
||||||
|
phi2 = phi.inline_context(CONTEXT)
|
||||||
|
assert phi2 == stl.parse('G(F(x > 4))')
|
||||||
|
|
||||||
|
phi = stl.parse('G(AP2)')
|
||||||
|
phi2 = phi.inline_context(CONTEXT)
|
||||||
|
assert phi2 == stl.parse('G((F(x > 4)) U (F(x > 4)))')
|
||||||
|
|
||||||
|
|
||||||
|
@given(SignalTemporalLogicStrategy)
|
||||||
|
def test_inline_context(phi):
|
||||||
|
phi2 = phi.inline_context(CONTEXT)
|
||||||
|
assert not (APS & phi2.atomic_predicates)
|
||||||
|
|
|
||||||
14
stl/utils.py
14
stl/utils.py
|
|
@ -6,7 +6,7 @@ from lenses import bind
|
||||||
|
|
||||||
import stl.ast
|
import stl.ast
|
||||||
from stl.ast import (And, F, G, Interval, LinEq, Neg,
|
from stl.ast import (And, F, G, Interval, LinEq, Neg,
|
||||||
Or, AP_lens, Next, Until, AtomicPred,
|
Or, Next, Until, AtomicPred,
|
||||||
_Top, _Bot)
|
_Top, _Bot)
|
||||||
from stl.types import STL
|
from stl.types import STL
|
||||||
|
|
||||||
|
|
@ -50,18 +50,6 @@ def linear_stl_lipschitz(phi):
|
||||||
return float(max(map(_lineq_lipschitz, phi.lineqs)))
|
return float(max(map(_lineq_lipschitz, phi.lineqs)))
|
||||||
|
|
||||||
|
|
||||||
def inline_context(phi, context):
|
|
||||||
phi2 = None
|
|
||||||
|
|
||||||
def update(ap):
|
|
||||||
return context.get(ap, ap)
|
|
||||||
|
|
||||||
while phi2 != phi:
|
|
||||||
phi2, phi = phi, AP_lens(phi).modify(update)
|
|
||||||
# TODO: this is hack to flatten the AST. Fix!
|
|
||||||
return stl.parse(str(phi))
|
|
||||||
|
|
||||||
|
|
||||||
op_lookup = {
|
op_lookup = {
|
||||||
">": op.gt,
|
">": op.gt,
|
||||||
">=": op.ge,
|
">=": op.ge,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue