From d271dfd5923bb2f84e2af4b2bb230d691238b3ba Mon Sep 17 00:00:00 2001 From: Alexandre Duret-Lutz Date: Fri, 29 Jul 2016 16:09:54 +0200 Subject: [PATCH] python: make it possible to modify edges during iteration Reported by Laurent Xu. * python/spot/impl.i: Fix the iterator to return pointers instead of references. Because references are ultimately copied. * tests/python/automata.ipynb: Add test cases. * NEWS: Mention it. --- NEWS | 3 + python/spot/impl.i | 10 +- tests/python/automata.ipynb | 234 +++++++++++++++++++++++++++++++----- 3 files changed, 215 insertions(+), 32 deletions(-) diff --git a/NEWS b/NEWS index 31b6ee7a8..4e8084d4e 100644 --- a/NEWS +++ b/NEWS @@ -165,6 +165,9 @@ New in spot 2.0.3a (not yet released) * Bindings for randomize() were added. + * Iterating over edges via "aut.out(s)" or "aut.edges()" + now allows modifying the edge fields. + * Under IPython the spot.ltsmin module now offers a %%pml magic to define promela models, compile them with spins, and dynamically load them. This is diff --git a/python/spot/impl.i b/python/spot/impl.i index 18044f8db..b4eda4b25 100644 --- a/python/spot/impl.i +++ b/python/spot/impl.i @@ -163,14 +163,16 @@ using namespace spot; %} -// Swig come with iterators that implement a decrement method. -// This is not supported in our "successor" iterators. +// Swig come with iterators that implement a decrement method. This +// is not supported in our "successor" iterators. Also we want +// iterators to return pointers so that data can be modified during +// iteration. %fragment("ForwardIterator_T","header",fragment="SwigPyIterator_T") { namespace swig { template::value_type, + typename std::iterator_traits::pointer, typename FromOper = from_oper > class ForwardIterator_T : public SwigPyIterator_T { @@ -191,7 +193,7 @@ namespace swig if (base::current == end) { throw stop_iteration(); } else { - return from(static_cast(*(base::current))); + return from(static_cast(&*(base::current))); } } diff --git a/tests/python/automata.ipynb b/tests/python/automata.ipynb index e470761ee..392c35953 100644 --- a/tests/python/automata.ipynb +++ b/tests/python/automata.ipynb @@ -18,7 +18,7 @@ "version": "3.4.3+" }, "name": "", - "signature": "sha256:29d335e40a65f0ca04a3b2b07bfcbf92f794407b413644546d957487dcbf4bb1" + "signature": "sha256:91af67353e0a35fefd672b53bd005af28720c0c7a8dfc922ce70fa8f3ef6a42e" }, "nbformat": 3, "nbformat_minor": 0, @@ -178,7 +178,7 @@ "\n" ], "text": [ - " *' at 0x7f09a8369240> >" + " *' at 0x7f5fc0c24900> >" ] } ], @@ -317,7 +317,7 @@ "" ], "text": [ - "" + "" ] } ], @@ -470,7 +470,7 @@ "" ], "text": [ - "" + "" ] } ], @@ -570,7 +570,7 @@ "\n" ], "text": [ - " *' at 0x7f09a8323fc0> >" + " *' at 0x7f5fc866e1b0> >" ] } ], @@ -640,7 +640,7 @@ "\n" ], "text": [ - " *' at 0x7f09a8323e70> >" + " *' at 0x7f5fc866e060> >" ] } ], @@ -716,7 +716,7 @@ "\n" ], "text": [ - " *' at 0x7f09a8323f00> >" + " *' at 0x7f5fc866e0f0> >" ] } ], @@ -839,7 +839,7 @@ "" ], "text": [ - "" + "" ] } ], @@ -1029,7 +1029,7 @@ "" ], "text": [ - "" + "" ] } ], @@ -1176,7 +1176,7 @@ "\n" ], "text": [ - " *' at 0x7f09a8323f30> >" + " *' at 0x7f5fc866e300> >" ] } ], @@ -1277,7 +1277,7 @@ "\n" ], "text": [ - " *' at 0x7f098bff3210> >" + " *' at 0x7f5fc866e2d0> >" ] } ], @@ -1395,7 +1395,7 @@ "\n" ], "text": [ - " *' at 0x7f098bff3240> >" + " *' at 0x7f5fc866e120> >" ] } ], @@ -1494,7 +1494,7 @@ "\n" ], "text": [ - " *' at 0x7f098bff3270> >" + " *' at 0x7f5fc866e330> >" ] } ], @@ -1964,7 +1964,7 @@ "\n" ], "text": [ - " *' at 0x7f09a8323ed0> >" + " *' at 0x7f5fc866e2a0> >" ] } ], @@ -2161,7 +2161,7 @@ "" ], "text": [ - "" + "" ] }, { @@ -2286,7 +2286,7 @@ "" ], "text": [ - "" + "" ] }, { @@ -2428,7 +2428,7 @@ "" ], "text": [ - "" + "" ] }, { @@ -2579,7 +2579,7 @@ "\n" ], "text": [ - " *' at 0x7f098bff33f0> >" + " *' at 0x7f5fc0b98ae0> >" ] } ], @@ -2735,7 +2735,7 @@ "\n" ], "text": [ - " *' at 0x7f09a8323c60> >" + " *' at 0x7f5fc0b98fc0> >" ] } ], @@ -2805,7 +2805,7 @@ "\n" ], "text": [ - " *' at 0x7f098bff31b0> >" + " *' at 0x7f5fc0b98ae0> >" ] } ], @@ -2877,7 +2877,7 @@ "" ], "text": [ - "" + "" ] }, { @@ -2930,7 +2930,7 @@ "" ], "text": [ - "" + "" ] }, { @@ -3042,7 +3042,7 @@ "" ], "text": [ - "" + "" ] }, { @@ -3154,7 +3154,7 @@ "" ], "text": [ - "" + "" ] } ], @@ -3232,7 +3232,7 @@ "\n" ], "text": [ - " *' at 0x7f09a82ac5d0> >" + " *' at 0x7f5fc866e390> >" ] }, { @@ -3315,7 +3315,7 @@ "" ], "text": [ - "" + "" ] } ], @@ -3332,7 +3332,7 @@ "cell_type": "code", "collapsed": false, "input": [ - "spot.translate('FGa', 'generic', 'deterministic')" + "aut = spot.translate('FGa', 'generic', 'deterministic'); aut" ], "language": "python", "metadata": {}, @@ -3400,11 +3400,189 @@ "\n" ], "text": [ - " *' at 0x7f09a82ac480> >" + " *' at 0x7f5fc85824e0> >" ] } ], "prompt_number": 26 + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Adding an automatic proposition to all edges" + ] + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "import buddy\n", + "b = buddy.bdd_ithvar(aut.register_ap('b'))\n", + "for e in aut.edges():\n", + " e.cond &= b\n", + "aut" + ], + "language": "python", + "metadata": {}, + "outputs": [ + { + "metadata": {}, + "output_type": "pyout", + "prompt_number": 27, + "svg": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "G\n", + "\n", + "\n", + "\n", + "0\n", + "\n", + "0\n", + "\n", + "\n", + "I->0\n", + "\n", + "\n", + "\n", + "\n", + "0->0\n", + "\n", + "\n", + "!a & b\n", + "\n", + "\n", + "1\n", + "\n", + "1\n", + "\n", + "\n", + "0->1\n", + "\n", + "\n", + "a & b\n", + "\u2776\n", + "\n", + "\n", + "1->0\n", + "\n", + "\n", + "!a & b\n", + "\u24ff\n", + "\n", + "\n", + "1->1\n", + "\n", + "\n", + "a & b\n", + "\u2776\n", + "\n", + "\n", + "\n" + ], + "text": [ + " *' at 0x7f5fc85824e0> >" + ] + } + ], + "prompt_number": 27 + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Adding an atomic proposition to the edge between 0 and 1:" + ] + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "c = buddy.bdd_ithvar(aut.register_ap('c'))\n", + "for e in aut.out(0):\n", + " if e.dst == 1:\n", + " e.cond &= c\n", + "aut" + ], + "language": "python", + "metadata": {}, + "outputs": [ + { + "metadata": {}, + "output_type": "pyout", + "prompt_number": 28, + "svg": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "G\n", + "\n", + "\n", + "\n", + "0\n", + "\n", + "0\n", + "\n", + "\n", + "I->0\n", + "\n", + "\n", + "\n", + "\n", + "0->0\n", + "\n", + "\n", + "!a & b\n", + "\n", + "\n", + "1\n", + "\n", + "1\n", + "\n", + "\n", + "0->1\n", + "\n", + "\n", + "a & b & c\n", + "\u2776\n", + "\n", + "\n", + "1->0\n", + "\n", + "\n", + "!a & b\n", + "\u24ff\n", + "\n", + "\n", + "1->1\n", + "\n", + "\n", + "a & b\n", + "\u2776\n", + "\n", + "\n", + "\n" + ], + "text": [ + " *' at 0x7f5fc85824e0> >" + ] + } + ], + "prompt_number": 28 } ], "metadata": {} -- GitLab