python: add xargs support to translate() and postprocess()
Fixes #361. * python/spot/__init__.py: Implement it. * tests/python/optionmap.py: Test it. * NEWS: Mention it.
This commit is contained in:
parent
b8e47fdc28
commit
e0958ee7c6
3 changed files with 75 additions and 8 deletions
10
NEWS
10
NEWS
|
|
@ -18,6 +18,16 @@ New in spot 2.6.3.dev (not yet released)
|
||||||
- ltlfilt learned --liveness to match formulas representing liveness
|
- ltlfilt learned --liveness to match formulas representing liveness
|
||||||
properties.
|
properties.
|
||||||
|
|
||||||
|
Python:
|
||||||
|
|
||||||
|
- spot.translate() and spot.postprocess() now take an xargs=
|
||||||
|
argument similar to the -x option of ltl2tgba and autfilt, making
|
||||||
|
it easier to fine tune these operations. For instance
|
||||||
|
ltl2tgba 'GF(a <-> XXa)' --det -x gf-guarantee=0
|
||||||
|
would be written in Python as
|
||||||
|
spot.translate('GF(a <-> XXa)', 'det', xargs='gf-guarantee=0')
|
||||||
|
(Note: those extra options are documented in the spot-x(7) man page.)
|
||||||
|
|
||||||
Library:
|
Library:
|
||||||
|
|
||||||
- The LTL parser learned syntactic sugar for nested ranges of X
|
- The LTL parser learned syntactic sugar for nested ranges of X
|
||||||
|
|
|
||||||
|
|
@ -101,6 +101,17 @@ if 'op_ff' not in globals():
|
||||||
_bdd_dict = make_bdd_dict()
|
_bdd_dict = make_bdd_dict()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
__om_init_tmp = option_map.__init__
|
||||||
|
def __om_init_new(self, str=None):
|
||||||
|
__om_init_tmp(self)
|
||||||
|
if str:
|
||||||
|
res = self.parse_options(str)
|
||||||
|
if res:
|
||||||
|
raise RuntimeError("failed to parse option at: '" + str +"'")
|
||||||
|
option_map.__init__ = __om_init_new
|
||||||
|
|
||||||
|
|
||||||
@_extend(twa, ta)
|
@_extend(twa, ta)
|
||||||
class twa:
|
class twa:
|
||||||
def _repr_svg_(self, opt=None):
|
def _repr_svg_(self, opt=None):
|
||||||
|
|
@ -688,7 +699,7 @@ def _postproc_translate_options(obj, default_type, *args):
|
||||||
obj.set_level(optm_)
|
obj.set_level(optm_)
|
||||||
|
|
||||||
|
|
||||||
def translate(formula, *args, dict=_bdd_dict):
|
def translate(formula, *args, dict=_bdd_dict, xargs=None):
|
||||||
"""Translate a formula into an automaton.
|
"""Translate a formula into an automaton.
|
||||||
|
|
||||||
Keep in mind that 'Deterministic' expresses just a preference that
|
Keep in mind that 'Deterministic' expresses just a preference that
|
||||||
|
|
@ -708,12 +719,22 @@ def translate(formula, *args, dict=_bdd_dict):
|
||||||
'Colored' (only for parity acceptance)
|
'Colored' (only for parity acceptance)
|
||||||
|
|
||||||
The default corresponds to 'tgba', 'small' and 'high'.
|
The default corresponds to 'tgba', 'small' and 'high'.
|
||||||
|
|
||||||
|
Additional options can be supplied using a `spot.option_map`, or a
|
||||||
|
string (that will be converted to `spot.option_map`), as the `xargs`
|
||||||
|
argument. This is similar to the `-x` option of command-line tools;
|
||||||
|
so check out the spot-x(7) man page for details.
|
||||||
"""
|
"""
|
||||||
a = translator(dict)
|
if type(xargs) is str:
|
||||||
|
xargs = option_map(xargs)
|
||||||
|
a = translator(dict, xargs)
|
||||||
_postproc_translate_options(a, postprocessor.TGBA, *args)
|
_postproc_translate_options(a, postprocessor.TGBA, *args)
|
||||||
if type(formula) == str:
|
if type(formula) == str:
|
||||||
formula = parse_formula(formula)
|
formula = parse_formula(formula)
|
||||||
return a.run(formula)
|
result = a.run(formula)
|
||||||
|
if xargs:
|
||||||
|
xargs.report_unused_options()
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
formula.translate = translate
|
formula.translate = translate
|
||||||
|
|
@ -732,7 +753,7 @@ _add_formula('contains')
|
||||||
_add_formula('are_equivalent', 'equivalent_to')
|
_add_formula('are_equivalent', 'equivalent_to')
|
||||||
|
|
||||||
|
|
||||||
def postprocess(automaton, *args, formula=None):
|
def postprocess(automaton, *args, formula=None, xargs=None):
|
||||||
"""Post process an automaton.
|
"""Post process an automaton.
|
||||||
|
|
||||||
This applies a number of simlification algorithms, depending on
|
This applies a number of simlification algorithms, depending on
|
||||||
|
|
@ -758,12 +779,22 @@ def postprocess(automaton, *args, formula=None):
|
||||||
If a formula denoted by this automaton is known, pass it to as the
|
If a formula denoted by this automaton is known, pass it to as the
|
||||||
optional `formula` argument; it can help some algorithms by
|
optional `formula` argument; it can help some algorithms by
|
||||||
providing an easy way to complement the automaton.
|
providing an easy way to complement the automaton.
|
||||||
|
|
||||||
|
Additional options can be supplied using a `spot.option_map`, or a
|
||||||
|
string (that will be converted to `spot.option_map`), as the `xargs`
|
||||||
|
argument. This is similar to the `-x` option of command-line tools;
|
||||||
|
so check out the spot-x(7) man page for details.
|
||||||
"""
|
"""
|
||||||
p = postprocessor()
|
if type(xargs) is str:
|
||||||
|
xargs = option_map(xargs)
|
||||||
|
p = postprocessor(xargs)
|
||||||
if type(automaton) == str:
|
if type(automaton) == str:
|
||||||
automaton = globals()['automaton'](automaton)
|
automaton = globals()['automaton'](automaton)
|
||||||
_postproc_translate_options(p, postprocessor.Generic, *args)
|
_postproc_translate_options(p, postprocessor.Generic, *args)
|
||||||
return p.run(automaton, formula)
|
result = p.run(automaton, formula)
|
||||||
|
if xargs:
|
||||||
|
xargs.report_unused_options()
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
twa.postprocess = postprocess
|
twa.postprocess = postprocess
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
# -*- mode: python; coding: utf-8 -*-
|
# -*- mode: python; coding: utf-8 -*-
|
||||||
# Copyright (C) 2010, 2012 Laboratoire de Recherche et Développement
|
# Copyright (C) 2010, 2012, 2018 Laboratoire de Recherche et Développement
|
||||||
# de l'EPITA.
|
# de l'EPITA.
|
||||||
# Copyright (C) 2005 Laboratoire d'Informatique de Paris 6 (LIP6),
|
# Copyright (C) 2005 Laboratoire d'Informatique de Paris 6 (LIP6),
|
||||||
# département Systèmes Répartis Coopératifs (SRC), Université Pierre
|
# département Systèmes Répartis Coopératifs (SRC), Université Pierre
|
||||||
|
|
@ -57,3 +57,29 @@ assert res == "opt == 1"
|
||||||
|
|
||||||
res = o.parse_options("foo=3opt == 1")
|
res = o.parse_options("foo=3opt == 1")
|
||||||
assert res == "3opt == 1"
|
assert res == "3opt == 1"
|
||||||
|
|
||||||
|
aut1 = spot.translate('GF(a <-> XXa)', 'det')
|
||||||
|
assert aut1.num_states() == 4
|
||||||
|
aut2 = spot.translate('GF(a <-> XXa)', 'det', xargs='gf-guarantee=0')
|
||||||
|
assert aut2.num_states() == 9
|
||||||
|
|
||||||
|
try:
|
||||||
|
spot.translate('GF(a <-> XXa)', 'det', xargs='foobar=1')
|
||||||
|
except RuntimeError as e:
|
||||||
|
assert "option 'foobar' was not used" in str(e)
|
||||||
|
else:
|
||||||
|
raise RuntimeError("missing exception")
|
||||||
|
|
||||||
|
try:
|
||||||
|
spot.translate('GF(a <-> XXa)').postprocess('det', xargs='gf-guarantee=0')
|
||||||
|
except RuntimeError as e:
|
||||||
|
assert "option 'gf-guarantee' was not used" in str(e)
|
||||||
|
else:
|
||||||
|
raise RuntimeError("missing exception")
|
||||||
|
|
||||||
|
try:
|
||||||
|
spot.translate('GF(a <-> XXa)').postprocess('det', xargs='gf-guarantee=x')
|
||||||
|
except RuntimeError as e:
|
||||||
|
assert "failed to parse option at: 'gf-guarantee=x'" in str(e)
|
||||||
|
else:
|
||||||
|
raise RuntimeError("missing exception")
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue