diff --git a/NEWS b/NEWS index 1a309583c..92a77acb6 100644 --- a/NEWS +++ b/NEWS @@ -49,10 +49,13 @@ New in spot 1.99.4a (not yet released) * The Debian package is now compiled for all Python3 versions supported by Debian, not just the default one. * Automata now have get_name()/set_name() methods. + * spot.postprocess(aut, *options), or aut.postprocess(*options) + simplify the use of the spot.postprocessor object. (Just like we + have spot.translate() on top of spot.translator().) Bugs fixed: - * Work around some strange weird exception raised when using the + * Work around some weird exception raised when using the randltlgenerator under Python 3.5. * Recognize "nullptr" formulas as None in Python. * Fix compilation of bench/stutter/ @@ -61,7 +64,7 @@ New in spot 1.99.4a (not yet released) * "randaut -Q0 1" used to segfault. * "ltlgrind -F FILENAME/COL" did not preserve other CSV columns. * "ltlgrind --help" did not document FORMAT. - * unabbreviate could easily use forbidden operators + * unabbreviate could easily use forbidden operators. New in spot 1.99.4 (2015-10-01) diff --git a/wrap/python/spot.py b/wrap/python/spot.py index 2641c6bf7..e7a8be5c5 100644 --- a/wrap/python/spot.py +++ b/wrap/python/spot.py @@ -373,25 +373,7 @@ def automaton(filename): raise RuntimeError("Failed to read automaton from {}".format(filename)) -def translate(formula, *args): - """Translate a formula into an automaton. - - Keep in mind that pref expresses just a preference that may not be - satisfied. - - The optional arguments should be strings among the following: - - at most one in 'TGBA', 'BA', or 'Monitor' - (type of automaton to build) - - at most one in 'Small', 'Deterministic', 'Any' - (preferred characteristics of the produced automaton) - - at most one in 'Low', 'Medium', 'High' - (optimization level) - - any combination of 'Complete', 'Unambiguous', and - 'StateBasedAcceptance' (or 'SBAcc' for short) - - The default corresponds to 'tgba', 'small' and 'high'. - """ - +def _postproc_translate_options(obj, default_type, *args): type_ = None pref_ = None optm_ = None @@ -404,6 +386,8 @@ def translate(formula, *args): if type_ is not None and type_ != val: raise ValueError("type cannot be both {} and {}" .format(type_, val)) + elif val == 'generic': + type_ = postprocessor.Generic elif val == 'tgba': type_ = postprocessor.TGBA elif val == 'ba': @@ -452,6 +436,7 @@ def translate(formula, *args): 'tgba': type_set, 'ba': type_set, 'monitor': type_set, + 'generic': type_set, 'small': pref_set, 'deterministic': pref_set, 'any': pref_set, @@ -488,26 +473,77 @@ def translate(formula, *args): .format(arg, str(compat))) if type_ is None: - type_ = postprocessor.TGBA + type_ = default_type if pref_ is None: pref_ = postprocessor.Small if optm_ is None: optm_ = postprocessor.High + obj.set_type(type_) + obj.set_pref(pref_ | comp_ | unam_ | sbac_) + obj.set_level(optm_) + + +def translate(formula, *args): + """Translate a formula into an automaton. + + Keep in mind that 'Deterministic' expresses just a preference that + may not be satisfied. + + The optional arguments should be strings among the following: + - at most one in 'TGBA', 'BA', or 'Monitor' + (type of automaton to build) + - at most one in 'Small', 'Deterministic', 'Any' + (preferred characteristics of the produced automaton) + - at most one in 'Low', 'Medium', 'High' + (optimization level) + - any combination of 'Complete', 'Unambiguous', and + 'StateBasedAcceptance' (or 'SBAcc' for short) + + The default corresponds to 'tgba', 'small' and 'high'. + """ + a = translator(_bdd_dict) + _postproc_translate_options(a, postprocessor.TGBA, *args) if type(formula) == str: formula = parse_formula(formula) - - a = translator(_bdd_dict) - a.set_type(type_) - a.set_pref(pref_ | comp_ | unam_ | sbac_) - a.set_level(optm_) - return a.run(formula) formula.translate = translate +def postprocess(automaton, *args): + """Post process an automaton. + + This applies a number of simlification algorithms, depending on + the options supplied. Keep in mind that 'Deterministic' expresses + just a preference that may not be satisfied if the input is + not already 'Deterministic'. + + The optional arguments should be strings among the following: + - at most one in 'Generic', 'TGBA', 'BA', or 'Monitor' + (type of automaton to build) + - at most one in 'Small', 'Deterministic', 'Any' + (preferred characteristics of the produced automaton) + - at most one in 'Low', 'Medium', 'High' + (optimization level) + - any combination of 'Complete' and 'StateBasedAcceptance' + (or 'SBAcc' for short) + + The default corresponds to 'generic', 'small' and 'high'. + """ + p = postprocessor() + if type(automaton) == str: + automaton = globals()['automaton'](automaton) + _postproc_translate_options(p, postprocessor.Generic, *args) + return p.run(automaton) + + +twa.postprocess = postprocess +twa.scc_filter = scc_filter +twa.scc_filter_states = scc_filter_states + + # Wrapper around a formula iterator to which we add some methods of formula # (using _addfilter and _addmap), so that we can write things like # formulas.simplify().is_X_free(). diff --git a/wrap/python/tests/automata.ipynb b/wrap/python/tests/automata.ipynb index 4617f3847..80d4f1167 100644 --- a/wrap/python/tests/automata.ipynb +++ b/wrap/python/tests/automata.ipynb @@ -17,7 +17,8 @@ "pygments_lexer": "ipython3", "version": "3.4.3+" }, - "name": "" + "name": "", + "signature": "sha256:d67ef646828999fe2beb805f3bb74087bbb30e12354c11fdfbe0f28c23bd7e5f" }, "nbformat": 3, "nbformat_minor": 0, @@ -28,6 +29,7 @@ "cell_type": "code", "collapsed": false, "input": [ + "from IPython.display import display\n", "import spot\n", "spot.setup()" ], @@ -176,7 +178,7 @@ "\n" ], "text": [ - " *' at 0x7f2e58013ea0> >" + " *' at 0x7f48d053f5d0> >" ] } ], @@ -315,7 +317,7 @@ "" ], "text": [ - "" + "" ] } ], @@ -468,7 +470,7 @@ "" ], "text": [ - "" + "" ] } ], @@ -568,7 +570,7 @@ "\n" ], "text": [ - " *' at 0x7f2e4afe6720> >" + " *' at 0x7f48d05238d0> >" ] } ], @@ -638,7 +640,7 @@ "\n" ], "text": [ - " *' at 0x7f2e4afe6870> >" + " *' at 0x7f48d05237e0> >" ] } ], @@ -714,7 +716,7 @@ "\n" ], "text": [ - " *' at 0x7f2e4afe6600> >" + " *' at 0x7f48d0523750> >" ] } ], @@ -837,7 +839,7 @@ "" ], "text": [ - "" + "" ] } ], @@ -1027,7 +1029,7 @@ "" ], "text": [ - "" + "" ] } ], @@ -1174,7 +1176,7 @@ "\n" ], "text": [ - " *' at 0x7f2e4afe6180> >" + " *' at 0x7f48d0523ab0> >" ] } ], @@ -1275,7 +1277,7 @@ "\n" ], "text": [ - " *' at 0x7f2e4afe6330> >" + " *' at 0x7f48d0523870> >" ] } ], @@ -1393,7 +1395,7 @@ "\n" ], "text": [ - " *' at 0x7f2e4afe66c0> >" + " *' at 0x7f48d05237b0> >" ] } ], @@ -1492,7 +1494,7 @@ "\n" ], "text": [ - " *' at 0x7f2e4afe6de0> >" + " *' at 0x7f48d04c2120> >" ] } ], @@ -1962,7 +1964,7 @@ "\n" ], "text": [ - " *' at 0x7f2e4afe6d20> >" + " *' at 0x7f48d0523f30> >" ] } ], @@ -2039,15 +2041,399 @@ "collapsed": false, "input": [ "a = spot.automaton('example1.aut')\n", - "spot.remove_fin(a)" + "display(a.show('.a'))\n", + "display(spot.remove_fin(a).show('.a'))\n", + "display(a.postprocess('TGBA', 'complete').show('.a'))\n", + "display(a.postprocess('BA'))" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, - "output_type": "pyout", - "prompt_number": 19, + "output_type": "display_data", + "svg": [ + "\n", + "\n", + "G\n", + "\n", + "(Fin(\n", + "\u2776\n", + ") & Fin(\n", + "\u2778\n", + ") & Inf(\n", + "\u24ff\n", + ")) | (Inf(\n", + "\u2777\n", + ")&Inf(\n", + "\u2778\n", + ")) | Inf(\n", + "\u2776\n", + ")\n", + "\n", + "\n", + "0\n", + "\n", + "0\n", + "\n", + "\n", + "I->0\n", + "\n", + "\n", + "\n", + "\n", + "0->0\n", + "\n", + "\n", + "1\n", + "\u2778\n", + "\n", + "\n", + "1\n", + "\n", + "1\n", + "\n", + "\n", + "0->1\n", + "\n", + "\n", + "a\n", + "\u2776\n", + "\u2778\n", + "\n", + "\n", + "2\n", + "\n", + "2\n", + "\n", + "\n", + "0->2\n", + "\n", + "\n", + "!a\n", + "\u24ff\n", + "\u2778\n", + "\n", + "\n", + "1->0\n", + "\n", + "\n", + "b\n", + "\u2778\n", + "\n", + "\n", + "1->1\n", + "\n", + "\n", + "a & b\n", + "\u24ff\n", + "\u2778\n", + "\n", + "\n", + "1->2\n", + "\n", + "\n", + "!a & b\n", + "\u2777\n", + "\u2778\n", + "\n", + "\n", + "2->0\n", + "\n", + "\n", + "!b\n", + "\n", + "\n", + "2->1\n", + "\n", + "\n", + "a & !b\n", + "\u24ff\n", + "\n", + "\n", + "2->2\n", + "\n", + "\n", + "!a & !b\n", + "\u24ff\n", + "\n", + "\n", + "" + ], + "text": [ + "" + ] + }, + { + "metadata": {}, + "output_type": "display_data", + "svg": [ + "\n", + "\n", + "G\n", + "\n", + "Inf(\n", + "\u24ff\n", + ") | Inf(\n", + "\u2776\n", + ") | (Inf(\n", + "\u2777\n", + ")&Inf(\n", + "\u2778\n", + "))\n", + "\n", + "\n", + "0\n", + "\n", + "0\n", + "\n", + "\n", + "I->0\n", + "\n", + "\n", + "\n", + "\n", + "0->0\n", + "\n", + "\n", + "1\n", + "\u2778\n", + "\n", + "\n", + "1\n", + "\n", + "1\n", + "\n", + "\n", + "0->1\n", + "\n", + "\n", + "a\n", + "\u2776\n", + "\u2778\n", + "\n", + "\n", + "2\n", + "\n", + "2\n", + "\n", + "\n", + "0->2\n", + "\n", + "\n", + "!a\n", + "\u2778\n", + "\n", + "\n", + "1->0\n", + "\n", + "\n", + "b\n", + "\u2778\n", + "\n", + "\n", + "1->1\n", + "\n", + "\n", + "a & b\n", + "\u2778\n", + "\n", + "\n", + "1->2\n", + "\n", + "\n", + "!a & b\n", + "\u2777\n", + "\u2778\n", + "\n", + "\n", + "2->0\n", + "\n", + "\n", + "!b\n", + "\n", + "\n", + "2->1\n", + "\n", + "\n", + "a & !b\n", + "\n", + "\n", + "2->2\n", + "\n", + "\n", + "!a & !b\n", + "\n", + "\n", + "3\n", + "\n", + "3\n", + "\n", + "\n", + "2->3\n", + "\n", + "\n", + "!a & !b\n", + "\n", + "\n", + "3->3\n", + "\n", + "\n", + "!a & !b\n", + "\u24ff\n", + "\n", + "\n", + "" + ], + "text": [ + "" + ] + }, + { + "metadata": {}, + "output_type": "display_data", + "svg": [ + "\n", + "\n", + "G\n", + "\n", + "Inf(\n", + "\u24ff\n", + ")\n", + "\n", + "\n", + "1\n", + "\n", + "1\n", + "\n", + "\n", + "I->1\n", + "\n", + "\n", + "\n", + "\n", + "1->1\n", + "\n", + "\n", + "1\n", + "\n", + "\n", + "2\n", + "\n", + "2\n", + "\n", + "\n", + "1->2\n", + "\n", + "\n", + "a\n", + "\u24ff\n", + "\n", + "\n", + "3\n", + "\n", + "3\n", + "\n", + "\n", + "1->3\n", + "\n", + "\n", + "!a\n", + "\n", + "\n", + "0\n", + "\n", + "0\n", + "\n", + "\n", + "0->0\n", + "\n", + "\n", + "!a & !b\n", + "\u24ff\n", + "\n", + "\n", + "4\n", + "\n", + "4\n", + "\n", + "\n", + "0->4\n", + "\n", + "\n", + "a | b\n", + "\n", + "\n", + "4->4\n", + "\n", + "\n", + "1\n", + "\n", + "\n", + "2->1\n", + "\n", + "\n", + "b\n", + "\n", + "\n", + "2->4\n", + "\n", + "\n", + "!b\n", + "\n", + "\n", + "2->2\n", + "\n", + "\n", + "a & b\n", + "\n", + "\n", + "2->3\n", + "\n", + "\n", + "!a & b\n", + "\u24ff\n", + "\n", + "\n", + "3->1\n", + "\n", + "\n", + "!b\n", + "\n", + "\n", + "3->0\n", + "\n", + "\n", + "!a & !b\n", + "\n", + "\n", + "3->4\n", + "\n", + "\n", + "b\n", + "\n", + "\n", + "3->2\n", + "\n", + "\n", + "a & !b\n", + "\n", + "\n", + "3->3\n", + "\n", + "\n", + "!a & !b\n", + "\n", + "\n", + "" + ], + "text": [ + "" + ] + }, + { + "metadata": {}, + "output_type": "display_data", "svg": [ "\n", "\n", "\n", - "\n", - "\n", + "\n", + "\n", "G\n", - "\n", + "\n", "\n", - "\n", - "0\n", - "\n", - "0\n", - "\n", - "\n", - "I->0\n", - "\n", - "\n", - "\n", - "\n", - "0->0\n", - "\n", - "\n", - "1\n", - "\u2778\n", - "\n", - "\n", - "1\n", - "\n", - "1\n", - "\n", - "\n", - "0->1\n", - "\n", - "\n", - "a\n", - "\u2776\n", - "\u2778\n", - "\n", "\n", - "2\n", - "\n", - "2\n", + "2\n", + "\n", + "2\n", "\n", - "\n", - "0->2\n", - "\n", - "\n", - "!a\n", - "\u2778\n", - "\n", - "\n", - "1->0\n", - "\n", - "\n", - "b\n", - "\u2778\n", - "\n", - "\n", - "1->1\n", - "\n", - "\n", - "a & b\n", - "\u2778\n", - "\n", - "\n", - "1->2\n", - "\n", - "\n", - "!a & b\n", - "\u2777\n", - "\u2778\n", - "\n", - "\n", - "2->0\n", - "\n", - "\n", - "!b\n", - "\n", - "\n", - "2->1\n", - "\n", - "\n", - "a & !b\n", + "\n", + "I->2\n", + "\n", + "\n", "\n", "\n", - "2->2\n", - "\n", - "\n", - "!a & !b\n", + "2->2\n", + "\n", + "\n", + "1\n", + "\n", + "\n", + "0\n", + "\n", + "\n", + "0\n", + "\n", + "\n", + "2->0\n", + "\n", + "\n", + "a\n", "\n", "\n", - "3\n", - "\n", - "3\n", + "3\n", + "\n", + "3\n", "\n", "\n", - "2->3\n", - "\n", - "\n", - "!a & !b\n", + "2->3\n", + "\n", + "\n", + "!a\n", "\n", - "\n", - "3->3\n", - "\n", - "\n", - "!a & !b\n", - "\u24ff\n", + "\n", + "0->2\n", + "\n", + "\n", + "b\n", + "\n", + "\n", + "4\n", + "\n", + "4\n", + "\n", + "\n", + "0->4\n", + "\n", + "\n", + "a & b\n", + "\n", + "\n", + "5\n", + "\n", + "\n", + "5\n", + "\n", + "\n", + "0->5\n", + "\n", + "\n", + "!a & b\n", + "\n", + "\n", + "4->4\n", + "\n", + "\n", + "a & b\n", + "\n", + "\n", + "4->5\n", + "\n", + "\n", + "!a & b\n", + "\n", + "\n", + "5->2\n", + "\n", + "\n", + "!b\n", + "\n", + "\n", + "5->4\n", + "\n", + "\n", + "a & !b\n", + "\n", + "\n", + "1\n", + "\n", + "\n", + "1\n", + "\n", + "\n", + "5->1\n", + "\n", + "\n", + "!a & !b\n", + "\n", + "\n", + "5->3\n", + "\n", + "\n", + "!a & !b\n", + "\n", + "\n", + "1->1\n", + "\n", + "\n", + "!a & !b\n", + "\n", + "\n", + "3->4\n", + "\n", + "\n", + "a & !b\n", + "\n", + "\n", + "3->1\n", + "\n", + "\n", + "!a & !b\n", "\n", "\n", "\n" ], "text": [ - " *' at 0x7f2e4afe66f0> >" + " *' at 0x7f48d0523780> >" ] } ], @@ -2321,7 +2735,7 @@ "\n" ], "text": [ - " *' at 0x7f2e4afe6e70> >" + " *' at 0x7f48d05236f0> >" ] } ], @@ -2391,7 +2805,7 @@ "\n" ], "text": [ - " *' at 0x7f2e4afe6660> >" + " *' at 0x7f48d0523510> >" ] } ],