Example #1
0
 def setUp(self):
     self.f_un = GRSpec(env_vars="x", sys_vars="y",
                        env_init="x", env_prog="x",
                        sys_init="y",sys_safety=["y -> X(!y)","!y -> X(y)"],
                        sys_prog="y && x")
     self.dcounter = GRSpec(sys_vars={"y": (0,5)}, sys_init=["y=0"],
                            sys_prog=["y=0", "y=5"])
Example #2
0
 def setUp(self):
     self.check_realizable = lambda x: slugs.synthesize(x) is not None
     self.synthesize = slugs.synthesize
     self.f_un = GRSpec(env_vars="x",
                        sys_vars="y",
                        env_init="x",
                        env_prog="x",
                        sys_init="y",
                        sys_safety=["y -> X(!y)", "!y -> X(y)"],
                        sys_prog="y && x",
                        moore=False,
                        plus_one=False,
                        qinit='\A \E')
     self.f = GRSpec(
         env_vars="x",
         sys_vars="y",
         env_init="x",
         env_prog="x",
         sys_init="y",
         sys_prog=["y & x", "!y"],
         moore=False,
         plus_one=False,
     )
     self.dcounter = GRSpec(sys_vars={"y": (0, 5)},
                            sys_init=["y=0"],
                            sys_prog=["y=0", "y=5"],
                            moore=False,
                            plus_one=False,
                            qinit='\A \E')
Example #3
0
 def setUp(self):
     self.f = GRSpec(env_vars={"x"}, sys_vars={"y"},
                     env_init=["x"], sys_safety=["y"],
                     env_prog=["!x", "x"], sys_prog=["y&&!x"])
     self.triv = GRSpec(env_vars=["x"], sys_vars=["y"],
                        env_init=["x && !x"])
     self.empty = GRSpec()
Example #4
0
 def setUp(self):
     self.f_un = GRSpec(
         env_vars="x", sys_vars="y",
         env_init="x", env_prog="x",
         sys_init="y", sys_safety=["y -> X(!y)", "!y -> X(y)"],
         sys_prog="y && x")
     self.dcounter = GRSpec(sys_vars={"y": (0, 5)}, sys_init=["y=0"],
                            sys_prog=["y=0", "y=5"])
Example #5
0
    def test_or(self):
        g = GRSpec(env_vars={"z"}, env_prog=["!z"])
        h = self.f | g
        assert len(h.env_vars) == 2 and h.env_vars.has_key("z")
        assert len(h.env_prog) == len(self.f.env_prog)+1 and "!z" in h.env_prog

        # Domain mismatch on system variable y
        g.sys_vars = {"y": (0,5)}
        nt.assert_raises(ValueError, self.f.__or__, g)

        # Domain mismatch on environment variable x
        g.sys_vars = dict()
        g.env_vars["x"] = (0,3)
        nt.assert_raises(ValueError, self.f.__or__, g)
Example #6
0
def eventually_to_gr1(p, aux='aux'):
    """Convert C{<> p} to GR(1).

    GR(1) form::

        !(aux) &&
        [](aux -> X aux) &&
        []<>(aux) &&

        []( (!p && !aux) -> X!(aux) )

    @type p: str

    @param aux: name to use for auxiliary variable
    @type aux: str

    @rtype: L{GRSpec}
    """
    a = aux
    a0 = a

    p = _paren(p)
    a = _paren(a)

    v = tx.check_var_name_conflict(p, a0)

    sys_vars = v | {a0}
    sys_init = {'!(' + a + ')'}
    sys_safe = {'(!' + p + ' && !' + a + ') -> X !' + a, a + ' -> X ' + a}
    sys_prog = {a}

    return GRSpec(sys_vars=sys_vars,
                  sys_init=sys_init,
                  sys_safety=sys_safe,
                  sys_prog=sys_prog)
Example #7
0
class GRSpec_test:
    def setUp(self):
        self.f = GRSpec(env_vars={"x"}, sys_vars={"y"},
                        env_init=["x"], sys_safety=["y"],
                        env_prog=["!x", "x"], sys_prog=["y&&!x"])
        self.triv = GRSpec(env_vars=["x"], sys_vars=["y"],
                           env_init=["x && !x"])
        self.empty = GRSpec()

    def tearDown(self):
        self.f = None

    def test_sym_to_prop(self):
        original_env_vars = copy.copy(self.f.env_vars)
        original_sys_vars = copy.copy(self.f.sys_vars)
        self.f.sym_to_prop({"x":"bar", "y":"uber||cat"})
        assert self.f.env_vars == original_env_vars and self.f.sys_vars == original_sys_vars
        assert self.f.env_prog == ["!(bar)", "(bar)"] and self.f.sys_prog == ["(uber||cat)&&!(bar)"]

    def test_or(self):
        g = GRSpec(env_vars={"z"}, env_prog=["!z"])
        h = self.f | g
        assert len(h.env_vars) == 2 and h.env_vars.has_key("z")
        assert len(h.env_prog) == len(self.f.env_prog)+1 and "!z" in h.env_prog

        # Domain mismatch on system variable y
        g.sys_vars = {"y": (0,5)}
        nt.assert_raises(ValueError, self.f.__or__, g)

        # Domain mismatch on environment variable x
        g.sys_vars = dict()
        g.env_vars["x"] = (0,3)
        nt.assert_raises(ValueError, self.f.__or__, g)

    def test_to_canon(self):
        # Fragile!
        assert self.f.to_canon() == "((x) && []<>(!x) && []<>(x)) -> ([](y) && []<>(y&&!x))"
        # N.B., for self.triv, to_canon() returns a formula missing
        # the assumption part not because it detected that the
        # assumption is false, but rather the guarantee is empty (and
        # thus interpreted as being "True").
        assert self.triv.to_canon() == "True"
        assert self.empty.to_canon() == "True"

    def test_init(self):
        assert len(self.f.env_vars) == 1 and len(self.f.sys_vars) == 1
        assert self.f.env_vars["x"] == "boolean" and self.f.sys_vars["y"] == "boolean"
Example #8
0
 def setUp(self):
     self.f_un = GRSpec(env_vars="x",
                        sys_vars="y",
                        env_init="x",
                        env_prog="x",
                        sys_init="y",
                        sys_safety=["y -> X(!y)", "!y -> X(y)"],
                        sys_prog="y && x",
                        moore=False,
                        plus_one=False,
                        qinit='\A \E')
     self.dcounter = GRSpec(sys_vars={"y": (0, 5)},
                            sys_init=["y=0"],
                            sys_prog=["y=0", "y=5"],
                            moore=False,
                            plus_one=False,
                            qinit='\A \E')
 def setUp(self):
     self.check_realizable = jtlv.check_realizable
     self.synthesize = jtlv.synthesize
     self.f_un = GRSpec(env_vars="x",
                        sys_vars="y",
                        env_init="x",
                        env_prog="x",
                        sys_init="y",
                        sys_safety=["y -> X(!y)", "!y -> X(y)"],
                        sys_prog="y && x")
     self.f = GRSpec(env_vars="x",
                     sys_vars="y",
                     env_init="x",
                     env_prog="x",
                     sys_init="y",
                     sys_prog=["y & x", "!y"])
     self.dcounter = GRSpec(sys_vars={"y": (0, 5)},
                            sys_init=["y=0"],
                            sys_prog=["y=0", "y=5"])
def hash_question_mark_test():
    specs = GRSpec(env_vars={'w': ['low', 'medium', 'high']},
                   sys_vars={'a': (0, 2)},
                   env_init=['w="low"'],
                   env_safety=['(a=1) -> ((w="low") || (w="medium"))'],
                   env_prog=['(w="high")'],
                   sys_init=['a=2'],
                   sys_safety=['a=2'],
                   sys_prog=['a=2'])
    with nt.assert_raises(ValueError):
        jtlv.synthesize(specs)
Example #11
0
class basic_test:
    def setUp(self):
        self.f_un = GRSpec(env_vars="x", sys_vars="y",
                           env_init="x", env_prog="x",
                           sys_init="y",sys_safety=["y -> X(!y)","!y -> X(y)"],
                           sys_prog="y && x")
        self.dcounter = GRSpec(sys_vars={"y": (0,5)}, sys_init=["y=0"],
                               sys_prog=["y=0", "y=5"])

    def tearDown(self):
        self.f_un = None
        self.dcounter = None

    def test_check_syntax(self):
        assert gr1cint.check_syntax(REFERENCE_SPECFILE)
        assert not gr1cint.check_syntax("foo")

    def test_to_gr1c(self):
        assert gr1cint.check_syntax(self.f_un.to_gr1c() )
        assert gr1cint.check_syntax(self.dcounter.to_gr1c() )

    def test_check_realizable(self):
        assert not gr1cint.check_realizable(self.f_un)
        self.f_un.sys_safety = []
        assert gr1cint.check_realizable(self.f_un)
        assert gr1cint.check_realizable(self.dcounter)
        
    def test_synthesize(self):
        self.f_un.sys_safety = []  # Make it realizable
        mach = gr1cint.synthesize(self.f_un)
        assert mach is not None
        assert len(mach.inputs) == 1 and mach.inputs.has_key("x")
        assert len(mach.outputs) == 1 and mach.outputs.has_key("y")

        mach = gr1cint.synthesize(self.dcounter)
        assert mach is not None
        assert len(mach.inputs) == 0
        assert len(mach.outputs) == 1 and mach.outputs.has_key("y")
        assert len(mach.states) == 3
Example #12
0
def stability_to_gr1(p, aux='aux'):
    """Convert C{<>[] p} to GR(1).

    Warning: This conversion is sound, but not complete.
    See p.2, U{[E10]
    <https://tulip-control.sourceforge.io/doc/bibliography.html#e10>}

    GR(1) form::

        !(aux) &&
        [](aux -> X aux) &&
        []<>(aux) &&

        [](aux -> p)

    @type p: str

    @param aux: name to use for auxiliary variable
    @type aux: str

    @rtype: L{GRSpec}
    """
    logging.warning(
        'Conversion of stability (<>[]p) to GR(1)' +
        'is sound, but NOT complete.'
    )

    a = aux
    a0 = a

    p = _paren(p)
    a = _paren(a)

    v = tx.check_var_name_conflict(p, a0)

    sys_vars = v | {a0}
    sys_init = {'!' + a}
    sys_safe = {a + ' -> ' + p,
                a + ' -> X ' + a}
    sys_prog = {a}

    return GRSpec(sys_vars=sys_vars, sys_init=sys_init,
                  sys_safety=sys_safe, sys_prog=sys_prog)
Example #13
0
def until_to_gr1(p, q, aux='aux'):
    """Convert C{p U q} to GR(1).

    GR(1) form::

        (!q -> !aux) &&
        [](q -> aux)
        [](aux -> X aux) &&
        []<>(aux) &&

        []( (!aux && X(!q) ) -> X!(aux) ) &&
        [](!aux -> p)

    @type p: str

    @param aux: name to use for auxiliary variable
    @type aux: str

    @rtype: L{GRSpec}
    """
    a = aux
    a0 = a

    p = _paren(p)
    q = _paren(q)
    a = _paren(a)

    s = p + ' && ' + q
    v = tx.check_var_name_conflict(s, a0)

    sys_vars = v | {a0}
    sys_init = {'!' + q + ' -> !' + a}
    sys_safe = {
        q + ' -> ' + a, '( (X !' + q + ') && !' + a + ') -> X !' + a,
        a + ' -> X ' + a, '(!' + a + ') -> ' + p
    }
    sys_prog = {a}

    return GRSpec(sys_vars=sys_vars,
                  sys_init=sys_init,
                  sys_safety=sys_safe,
                  sys_prog=sys_prog)
Example #14
0
def response_to_gr1(p, q, aux='aux'):
    """Convert C{[](p -> <> q)} to GR(1).

    GR(1) form::

        []<>(aux) &&

        []( (p && !q) -> X ! aux) &&
        []( (! aux && !q) -> X ! aux)

    @type p: str

    @type q: str

    @param aux: name to use for auxiliary variable
    @type aux: str

    @rtype: L{GRSpec}
    """
    a = aux
    a0 = a

    p = _paren(p)
    q = _paren(q)
    a = _paren(a)

    s = p + ' -> <> ' + q
    v = tx.check_var_name_conflict(s, a0)

    sys_vars = v | {a0}
    # sys_init = {a}
    sys_safe = {
        '(' + p + ' && !' + q + ') -> X !' + a,
        '(!' + a + ' && !' + q + ') -> X !' + a
    }
    sys_prog = {a}

    return GRSpec(
        sys_vars=sys_vars,  # sys_init=sys_init,
        sys_safety=sys_safe,
        sys_prog=sys_prog)
Example #15
0
def str_to_grspec(f):
    """Return `GRSpec` from LTL formula `f` as `str`.

    Formula `f` must be in the form:

      A -> G

    where each of A, G is a conjunction of terms: `B`, `[]C`, `[]<>B`.
    For more details on `B, C`, see [split_gr1].

    @type f: `str`
    @rtype: [GRSpec]
    """
    t = parser.parse(f)
    assert t.operator == '->'
    env, sys = t.operands
    d = {'assume': split_gr1(env), 'assert': split_gr1(sys)}
    return GRSpec(env_init=d['assume']['init'],
                  env_safety=d['assume']['G'],
                  env_prog=d['assume']['GF'],
                  sys_init=d['assert']['init'],
                  sys_safety=d['assert']['G'],
                  sys_prog=d['assert']['GF'])
Example #16
0
def load():
    with open(LTL_SPEC, 'r') as f:
        d = json.load(f)
    f = lambda x: ' \n '.join(s for s in x)
    env_init = f(d['env_init'])
    sys_init = f(d['sys_init'])
    env_safety = f(d['env_safety'])
    sys_safety = f(d['sys_safety'])
    env_prog = f(d['env_prog'])
    sys_prog = f(d['sys_prog'])
    dvars = d['vars']
    # restore tuples
    for var, d in dvars.iteritems():
        if d['type'] != 'int':
            continue
        d['dom'] = tuple(d['dom'])
    gr1 = GRSpec(variables=dvars,
                 env_init=[env_init],
                 sys_init=[sys_init],
                 env_safety=[env_safety],
                 sys_safety=[sys_safety],
                 env_prog=[env_prog],
                 sys_prog=[sys_prog])
    return gr1, vartypes
Example #17
0
def synth_init_illegal_test(init_option):
    with pytest.raises(ValueError):
        spc = GRSpec(moore=False, plus_one=False, qinit=init_option)
        gr1c.synthesize(spc)
Example #18
0
def realiz_init_illegal_test(init_option):
    with pytest.raises(ValueError):
        spc = GRSpec(moore=False, plus_one=False, qinit=init_option)
        gr1c.check_realizable(spc)
Example #19
0
def realiz_init_illegal_check(init_option):
    spc = GRSpec(moore=False, plus_one=False, qinit=init_option)
    gr1c.check_realizable(spc)
Example #20
0
def synth_init_illegal_check(init_option):
    spc = GRSpec(moore=False, plus_one=False, qinit=init_option)
    gr1c.synthesize(spc)
Example #21
0
class basic_test:
    def setUp(self):
        self.f_un = GRSpec(env_vars="x", sys_vars="y",
                           env_init="x", env_prog="x",
                           sys_init="y",sys_safety=["y -> X(!y)","!y -> X(y)"],
                           sys_prog="y && x")
        self.dcounter = GRSpec(sys_vars={"y": (0,5)}, sys_init=["y=0"],
                               sys_prog=["y=0", "y=5"])

    def tearDown(self):
        self.f_un = None
        self.dcounter = None

    def test_check_syntax(self):
        assert gr1cint.check_syntax(REFERENCE_SPECFILE)
        assert not gr1cint.check_syntax("foo")

    def test_to_gr1c(self):
        assert gr1cint.check_syntax(self.f_un.to_gr1c() )
        assert gr1cint.check_syntax(self.dcounter.to_gr1c() )

    def test_check_realizable(self):
        assert not gr1cint.check_realizable(self.f_un,
                                            init_option="ALL_ENV_EXIST_SYS_INIT")
        self.f_un.sys_safety = []
        assert gr1cint.check_realizable(self.f_un,
                                        init_option="ALL_ENV_EXIST_SYS_INIT")
        assert gr1cint.check_realizable(self.f_un,
                                        init_option="ALL_INIT")

        assert gr1cint.check_realizable(self.dcounter,
                                        init_option="ALL_ENV_EXIST_SYS_INIT")
        self.dcounter.sys_init = []
        assert gr1cint.check_realizable(self.dcounter,
                                        init_option="ALL_INIT")

    def test_synthesize(self):
        self.f_un.sys_safety = []  # Make it realizable
        mach = gr1cint.synthesize(self.f_un,
                                  init_option="ALL_ENV_EXIST_SYS_INIT")
        assert mach is not None
        assert len(mach.inputs) == 1 and mach.inputs.has_key("x")
        assert len(mach.outputs) == 1 and mach.outputs.has_key("y")

        mach = gr1cint.synthesize(self.dcounter,
                                  init_option="ALL_ENV_EXIST_SYS_INIT")
        assert mach is not None
        assert len(mach.inputs) == 0
        assert len(mach.outputs) == 1 and mach.outputs.has_key("y")
        assert len(mach.states) == 3

        # In the notation of gr1c SYSINIT: True;, so the strategy must
        # account for every initial state, i.e., for y=0, y=1, y=2, ...
        self.dcounter.sys_init = []
        mach = gr1cint.synthesize(self.dcounter,
                                  init_option="ALL_INIT")
        assert mach is not None
        print mach
        assert len(mach.inputs) == 0
        assert len(mach.outputs) == 1 and mach.outputs.has_key("y")
        assert len(mach.states) == 7
Example #22
0
def realiz_init_illegal_check(init_option):
    spc = GRSpec()
    gr1c.check_realizable(spc, init_option=init_option)
Example #23
0
def synth_init_illegal_check(init_option):
    spc = GRSpec()
    gr1c.synthesize(spc, init_option=init_option)
Example #24
0
def load_aut_xml(x, namespace=DEFAULT_NAMESPACE):
    """Return strategy constructed from output of gr1c.

    @param x: a string or an instance of
        xml.etree.ElementTree._ElementInterface

    @type spec0: L{GRSpec}
    @param spec0: GR(1) specification with which to interpret the
        output of gr1c while constructing a MealyMachine, or None if
        the output from gr1c should be used as is.  Note that spec0
        may differ from the specification in the given tulipcon XML
        string x.  If you are unsure what to do, try setting spec0 to
        whatever L{gr1cint.synthesize} was invoked with.

    @return: if a strategy is given in the XML string, return it as
        C{networkx.DiGraph}. Else, return (L{GRSpec}, C{None}), where
        the first element is the specification as read from the XML string.
    """
    if not isinstance(x, str) and not isinstance(x, ET._ElementInterface):
        raise TypeError("tag to be parsed must be given " +
            "as a string or ElementTree._ElementInterface.")

    if isinstance(x, str):
        elem = ET.fromstring(x)
    else:
        elem = x

    if (namespace is None) or (len(namespace) == 0):
        ns_prefix = ""
    else:
        ns_prefix = "{"+namespace+"}"

    if elem.tag != ns_prefix+"tulipcon":
        raise TypeError("root tag should be tulipcon.")
    if ("version" not in elem.attrib.keys()):
        raise ValueError("unversioned tulipcon XML string.")
    if int(elem.attrib["version"]) != 1:
        raise ValueError("unsupported tulipcon XML version: "+
            str(elem.attrib["version"]))

    # Extract discrete variables and LTL specification
    (tag_name, env_vardict, env_vars) = _untagdict(elem.find(
        ns_prefix+"env_vars"), get_order=True)
    (tag_name, sys_vardict, sys_vars) = _untagdict(elem.find(
        ns_prefix+"sys_vars"), get_order=True)

    env_vars = _parse_vars(env_vars, env_vardict)
    sys_vars = _parse_vars(sys_vars, sys_vardict)

    s_elem = elem.find(ns_prefix+"spec")
    spec = GRSpec(env_vars=env_vars, sys_vars=sys_vars)
    for spec_tag in ["env_init", "env_safety", "env_prog",
                     "sys_init", "sys_safety", "sys_prog"]:
        if s_elem.find(ns_prefix+spec_tag) is None:
            raise ValueError("invalid specification in tulipcon XML string.")
        (tag_name, li) = _untaglist(s_elem.find(ns_prefix+spec_tag),
                                    cast_f=str, namespace=namespace)
        li = [v.replace("&lt;", "<") for v in li]
        li = [v.replace("&gt;", ">") for v in li]
        li = [v.replace("&amp;", "&") for v in li]
        setattr(spec, spec_tag, li)

    aut_elem = elem.find(ns_prefix+"aut")
    if aut_elem is None or (
        (aut_elem.text is None) and len(aut_elem.getchildren()) == 0):
        mach = None
        return (spec, mach)

    # Assume version 1 of tulipcon XML
    if aut_elem.attrib["type"] != "basic":
        raise ValueError("Automaton class only recognizes type \"basic\".")
    node_list = aut_elem.findall(ns_prefix+"node")
    id_list = []  # For more convenient searching, and to catch redundancy
    A = nx.DiGraph()
    A.env_vars = env_vars
    A.sys_vars = sys_vars
    for node in node_list:
        this_id = int(node.find(ns_prefix+"id").text)
        #this_name = node.find(ns_prefix+"anno").text  # Assume version 1
        (tag_name, this_name_list) = _untaglist(node.find(ns_prefix+"anno"),
                                                cast_f=int)
        if len(this_name_list) == 2:
            (mode, rgrad) = this_name_list
        else:
            (mode, rgrad) = (-1, -1)
        (tag_name, this_child_list) = _untaglist(
            node.find(ns_prefix+"child_list"),
            cast_f=int
        )
        if tag_name != ns_prefix+"child_list":
            # This really should never happen and may not even be
            # worth checking.
            raise ValueError("failure of consistency check " +
                "while processing aut XML string.")
        (tag_name, this_state) = _untagdict(node.find(ns_prefix+"state"),
                                            cast_f_values=int,
                                            namespace=namespace)

        if tag_name != ns_prefix+"state":
            raise ValueError("failure of consistency check " +
                "while processing aut XML string.")
        if this_id in id_list:
            logger.warn("duplicate nodes found: "+str(this_id)+"; ignoring...")
            continue
        id_list.append(this_id)

        logger.info('loaded from gr1c result:\n\t' +str(this_state) )

        A.add_node(this_id, state=copy.copy(this_state),
                   mode=mode, rgrad=rgrad)
        for next_node in this_child_list:
            A.add_edge(this_id, next_node)
    return A