python: add a %%pml magic
Fixes #162. * python/spot/ltsmin.i: Implement the magic. * NEWS: Mention it. * tests/python/ltsmin-pml.ipynb: New file. * tests/Makefile.am, doc/org/tut.org: Add it. * tests/python/ipnbdoctest.py: Adjust.
This commit is contained in:
parent
a7e4395f9d
commit
272daf62fc
6 changed files with 564 additions and 14 deletions
5
NEWS
5
NEWS
|
|
@ -65,6 +65,11 @@ New in spot 2.0.1a (not yet released)
|
||||||
|
|
||||||
* Bindings for language_containment_checker were added.
|
* Bindings for language_containment_checker were added.
|
||||||
|
|
||||||
|
* Under IPython the spot.ltsmin modules nows offers a
|
||||||
|
%%pml magic do define promela models, compile them
|
||||||
|
with spins, and dynamically load them. This is
|
||||||
|
akin to the %%dve magic that was already supported.
|
||||||
|
|
||||||
Documentation:
|
Documentation:
|
||||||
|
|
||||||
* A new example page shows how to test the equivalence of
|
* A new example page shows how to test the equivalence of
|
||||||
|
|
|
||||||
|
|
@ -63,8 +63,8 @@ real notebooks instead.
|
||||||
- [[https://spot.lrde.epita.fr/ipynb/decompose.html][=decompose.ipynb=]] illustrates the =decompose_strength()= function
|
- [[https://spot.lrde.epita.fr/ipynb/decompose.html][=decompose.ipynb=]] illustrates the =decompose_strength()= function
|
||||||
- [[https://spot.lrde.epita.fr/ipynb/testingaut.html][=testingaut.ipynb=]] shows the steps necessary to build a testing
|
- [[https://spot.lrde.epita.fr/ipynb/testingaut.html][=testingaut.ipynb=]] shows the steps necessary to build a testing
|
||||||
automaton
|
automaton
|
||||||
- [[https://spot.lrde.epita.fr/ipynb/ltsmin-dve.html][=ltsmin-dve.ipynb=]] minimal test for loading a DiVinE model using
|
- [[https://spot.lrde.epita.fr/ipynb/ltsmin-dve.html][=ltsmin-dve.ipynb=]] loading a DiVinE model using the LTSmin interface.
|
||||||
the LTSmin interface.
|
- [[https://spot.lrde.epita.fr/ipynb/ltsmin-pml.html][=ltsmin-pml.ipynb=]] loading a Promela model using the LTSmin interface.
|
||||||
- [[https://spot.lrde.epita.fr/ipynb/word.html][=word.ipynb=]] example for the =twa_run= and =twa_word= classes.
|
- [[https://spot.lrde.epita.fr/ipynb/word.html][=word.ipynb=]] example for the =twa_run= and =twa_word= classes.
|
||||||
- [[https://spot.lrde.epita.fr/ipynb/highlighting.html][=highlighting.ipynb=]] shows how to highlight states or edges in
|
- [[https://spot.lrde.epita.fr/ipynb/highlighting.html][=highlighting.ipynb=]] shows how to highlight states or edges in
|
||||||
automata.
|
automata.
|
||||||
|
|
|
||||||
|
|
@ -106,25 +106,31 @@ class model:
|
||||||
res += '\n';
|
res += '\n';
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def require(tool):
|
def require(*tools):
|
||||||
"""
|
"""
|
||||||
Exit with status code 77 if the required tool is not installed.
|
Exit with status code 77 if the required tool is not installed.
|
||||||
|
|
||||||
This function is mostly useful in Spot test suite, where 77 is a
|
This function is mostly useful in Spot test suite, where 77 is a
|
||||||
code used to indicate that some test should be skipped.
|
code used to indicate that some test should be skipped.
|
||||||
"""
|
"""
|
||||||
if tool != "divine":
|
|
||||||
raise ValueError("unsupported argument for require(): " + tool)
|
|
||||||
import shutil
|
import shutil
|
||||||
|
for tool in tools:
|
||||||
|
if tool == "divine":
|
||||||
if shutil.which("divine") == None:
|
if shutil.which("divine") == None:
|
||||||
print("divine not available", file=sys.stderr)
|
print("divine not available", file=sys.stderr)
|
||||||
sys.exit(77)
|
sys.exit(77)
|
||||||
out = subprocess.check_output(['divine', 'compile',
|
out = subprocess.check_output(['divine', 'compile', '--help'],
|
||||||
'--help'], stderr=subprocess.STDOUT)
|
stderr=subprocess.STDOUT)
|
||||||
if b'LTSmin' not in out:
|
if b'LTSmin' not in out:
|
||||||
print("divine available but no support for LTSmin",
|
print("divine available but no support for LTSmin",
|
||||||
file=sys.stderr)
|
file=sys.stderr)
|
||||||
sys.exit(77)
|
sys.exit(77)
|
||||||
|
elif tool == "spins":
|
||||||
|
if shutil.which("spins") == None:
|
||||||
|
print("spins not available", file=sys.stderr)
|
||||||
|
sys.exit(77)
|
||||||
|
else:
|
||||||
|
raise ValueError("unsupported argument for require(): " + tool)
|
||||||
|
|
||||||
|
|
||||||
# Load IPython specific support if we can.
|
# Load IPython specific support if we can.
|
||||||
|
|
@ -166,8 +172,36 @@ try:
|
||||||
spot.aux.rm_f(t.name + '.cpp')
|
spot.aux.rm_f(t.name + '.cpp')
|
||||||
spot.aux.rm_f(t.name + '2C')
|
spot.aux.rm_f(t.name + '2C')
|
||||||
|
|
||||||
|
@magics_class
|
||||||
|
class EditPML(Magics):
|
||||||
|
|
||||||
|
@cell_magic
|
||||||
|
def pml(self, line, cell):
|
||||||
|
if not line:
|
||||||
|
raise ValueError("missing variable name for %%pml")
|
||||||
|
with tempfile.NamedTemporaryFile(dir='.', suffix='.pml') as t:
|
||||||
|
t.write(cell.encode('utf-8'))
|
||||||
|
t.flush()
|
||||||
|
|
||||||
|
try:
|
||||||
|
p = subprocess.Popen(['spins', t.name],
|
||||||
|
stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.STDOUT,
|
||||||
|
universal_newlines=True)
|
||||||
|
out = p.communicate()
|
||||||
|
if out[0]:
|
||||||
|
print(out[0], file=sys.stderr)
|
||||||
|
ret = p.wait()
|
||||||
|
if ret:
|
||||||
|
raise subprocess.CalledProcessError(ret, 'spins')
|
||||||
|
self.shell.user_ns[line] = load(t.name + '.spins')
|
||||||
|
finally:
|
||||||
|
spot.aux.rm_f(t.name + '.spins.c')
|
||||||
|
spot.aux.rm_f(t.name + '.spins')
|
||||||
|
|
||||||
ip = get_ipython()
|
ip = get_ipython()
|
||||||
ip.register_magics(EditDVE)
|
ip.register_magics(EditDVE)
|
||||||
|
ip.register_magics(EditPML)
|
||||||
|
|
||||||
except (ImportError, NameError):
|
except (ImportError, NameError):
|
||||||
pass
|
pass
|
||||||
|
|
|
||||||
|
|
@ -297,6 +297,7 @@ TESTS_ipython = \
|
||||||
python/formulas.ipynb \
|
python/formulas.ipynb \
|
||||||
python/highlighting.ipynb \
|
python/highlighting.ipynb \
|
||||||
python/ltsmin-dve.ipynb \
|
python/ltsmin-dve.ipynb \
|
||||||
|
python/ltsmin-pml.ipynb \
|
||||||
python/piperead.ipynb \
|
python/piperead.ipynb \
|
||||||
python/product.ipynb \
|
python/product.ipynb \
|
||||||
python/randaut.ipynb \
|
python/randaut.ipynb \
|
||||||
|
|
|
||||||
|
|
@ -71,6 +71,10 @@ def sanitize(s):
|
||||||
# normalize graphviz version
|
# normalize graphviz version
|
||||||
s = re.sub(r'Generated by graphviz version.*', 'VERSION', s)
|
s = re.sub(r'Generated by graphviz version.*', 'VERSION', s)
|
||||||
|
|
||||||
|
# remove Spins verbose output version
|
||||||
|
s = re.sub(r'SpinS Promela Compiler.*Compiled C model to .*pml.spins',
|
||||||
|
'SpinS output', s, flags=re.DOTALL)
|
||||||
|
|
||||||
# SVG generated by graphviz may put note at different positions
|
# SVG generated by graphviz may put note at different positions
|
||||||
# depending on the graphviz build. Let's just strip anything that
|
# depending on the graphviz build. Let's just strip anything that
|
||||||
# look like a position.
|
# look like a position.
|
||||||
|
|
|
||||||
506
tests/python/ltsmin-pml.ipynb
Normal file
506
tests/python/ltsmin-pml.ipynb
Normal file
|
|
@ -0,0 +1,506 @@
|
||||||
|
{
|
||||||
|
"metadata": {
|
||||||
|
"kernelspec": {
|
||||||
|
"display_name": "Python 3",
|
||||||
|
"language": "python",
|
||||||
|
"name": "python3"
|
||||||
|
},
|
||||||
|
"language_info": {
|
||||||
|
"codemirror_mode": {
|
||||||
|
"name": "ipython",
|
||||||
|
"version": 3
|
||||||
|
},
|
||||||
|
"file_extension": ".py",
|
||||||
|
"mimetype": "text/x-python",
|
||||||
|
"name": "python",
|
||||||
|
"nbconvert_exporter": "python",
|
||||||
|
"pygments_lexer": "ipython3",
|
||||||
|
"version": "3.5.1"
|
||||||
|
},
|
||||||
|
"name": "",
|
||||||
|
"signature": "sha256:bbe178ef6526ace33fca472e0e20c706861b6b033a70d184f5a219c60812d5b7"
|
||||||
|
},
|
||||||
|
"nbformat": 3,
|
||||||
|
"nbformat_minor": 0,
|
||||||
|
"worksheets": [
|
||||||
|
{
|
||||||
|
"cells": [
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"collapsed": false,
|
||||||
|
"input": [
|
||||||
|
"import spot\n",
|
||||||
|
"import spot.ltsmin\n",
|
||||||
|
"# The following line causes the notebook to exit with 77 if spins is not \n",
|
||||||
|
"# installed, therefore skipping this test in the test suite.\n",
|
||||||
|
"spot.ltsmin.require('spins')\n",
|
||||||
|
"spot.setup()"
|
||||||
|
],
|
||||||
|
"language": "python",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"prompt_number": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"There are two ways to load a Promela model: from a file or from a cell. \n",
|
||||||
|
"\n",
|
||||||
|
"Loading from a cell\n",
|
||||||
|
"-------------------\n",
|
||||||
|
"\n",
|
||||||
|
"Using the `%%pml` magic will save the model in a temporary file, call `spins` to compile it, load the resulting shared library, and store the result into an object whose name is passed as an argument to `%%pml`."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"collapsed": false,
|
||||||
|
"input": [
|
||||||
|
"%%pml model\n",
|
||||||
|
"active proctype P() {\n",
|
||||||
|
"int a = 0;\n",
|
||||||
|
"int b = 0;\n",
|
||||||
|
"x: if\n",
|
||||||
|
" :: d_step {a < 3 && b < 3; a = a + 1; } goto x;\n",
|
||||||
|
" :: d_step {a < 3 && b < 3; b = b + 1; } goto x;\n",
|
||||||
|
"fi;\n",
|
||||||
|
"}"
|
||||||
|
],
|
||||||
|
"language": "python",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"output_type": "stream",
|
||||||
|
"stream": "stderr",
|
||||||
|
"text": [
|
||||||
|
"SpinS Promela Compiler - version 1.0 (5-Feb-2013)\n",
|
||||||
|
"(C) University of Twente, Formal Methods and Tools group\n",
|
||||||
|
"\n",
|
||||||
|
"Start parsing tmplq2ksakk.pml...done\n",
|
||||||
|
"\n",
|
||||||
|
"Optimizing graphs...\n",
|
||||||
|
" StateMerging changed 0 states/transitions.\n",
|
||||||
|
" RemoveUselessActions changed 2 states/transitions.\n",
|
||||||
|
" RemoveUselessGotos changed 2 states/transitions.\n",
|
||||||
|
" RenumberAll changed 1 states/transitions.\n",
|
||||||
|
"Optimization done\n",
|
||||||
|
"\n",
|
||||||
|
"Generating DM information ...\n",
|
||||||
|
"Generating DM information done\n",
|
||||||
|
"\n",
|
||||||
|
"Generating guard information ...\n",
|
||||||
|
" Found 0 / 4 ( 0.0%) !MCE guards.\n",
|
||||||
|
" Found 3 / 8 ( 37.5%) !IMC guards.\n",
|
||||||
|
" Found 6 / 6 (100.0%) !NES guards.\n",
|
||||||
|
" Found 6 / 6 (100.0%) !NDS guards.\n",
|
||||||
|
" Found 6 / 6 (100.0%) !visibilities.\n",
|
||||||
|
"Generating guard information done\n",
|
||||||
|
"\n",
|
||||||
|
"Written C model to /home/adl/git/spot/tests/python/tmplq2ksakk.pml.spins.c\n",
|
||||||
|
"Compiled C model to tmplq2ksakk.pml.spins\n",
|
||||||
|
"\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"prompt_number": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"Yes, the `spins` compiler is quite verbose. Printing the resulting `model` object will show information about the variables in that model. "
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"collapsed": false,
|
||||||
|
"input": [
|
||||||
|
"model"
|
||||||
|
],
|
||||||
|
"language": "python",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"metadata": {},
|
||||||
|
"output_type": "pyout",
|
||||||
|
"prompt_number": 3,
|
||||||
|
"text": [
|
||||||
|
"ltsmin model with the following variables:\n",
|
||||||
|
" _nr_pr: int\n",
|
||||||
|
" P_0._pc: pc\n",
|
||||||
|
" P_0._pid: pid\n",
|
||||||
|
" P_0.a: int\n",
|
||||||
|
" P_0.b: int"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"prompt_number": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"To instantiate a Kripke structure, one should provide a list of atomic proposition to observe."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"collapsed": false,
|
||||||
|
"input": [
|
||||||
|
"k = model.kripke(['P_0.a < 2', 'P_0.b > 1']); k"
|
||||||
|
],
|
||||||
|
"language": "python",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"metadata": {},
|
||||||
|
"output_type": "pyout",
|
||||||
|
"prompt_number": 4,
|
||||||
|
"svg": [
|
||||||
|
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
|
||||||
|
"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
|
||||||
|
" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
|
||||||
|
"<!-- Generated by graphviz version 2.38.0 (20140413.2041)\n",
|
||||||
|
" -->\n",
|
||||||
|
"<!-- Title: G Pages: 1 -->\n",
|
||||||
|
"<svg width=\"734pt\" height=\"75pt\"\n",
|
||||||
|
" viewBox=\"0.00 0.00 734.00 75.07\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
|
||||||
|
"<g id=\"graph0\" class=\"graph\" transform=\"scale(0.239277 0.239277) rotate(0) translate(4 309.74)\">\n",
|
||||||
|
"<title>G</title>\n",
|
||||||
|
"<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-309.74 3063.57,-309.74 3063.57,4 -4,4\"/>\n",
|
||||||
|
"<!-- I -->\n",
|
||||||
|
"<!-- 0 -->\n",
|
||||||
|
"<g id=\"node2\" class=\"node\"><title>0</title>\n",
|
||||||
|
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"273.881\" cy=\"-152.87\" rx=\"236.762\" ry=\"26.7407\"/>\n",
|
||||||
|
"<text text-anchor=\"middle\" x=\"273.881\" y=\"-156.67\" font-family=\"Lato\" font-size=\"14.00\">_nr_pr=1, P_0._pc=0, P_0._pid=0, P_0.a=0, P_0.b=0</text>\n",
|
||||||
|
"<text text-anchor=\"middle\" x=\"273.881\" y=\"-141.67\" font-family=\"Lato\" font-size=\"14.00\">"P_0.a < 2" & !"P_0.b > 1" & !dead</text>\n",
|
||||||
|
"</g>\n",
|
||||||
|
"<!-- I->0 -->\n",
|
||||||
|
"<g id=\"edge1\" class=\"edge\"><title>I->0</title>\n",
|
||||||
|
"<path fill=\"none\" stroke=\"black\" d=\"M1.04952,-152.87C1.86795,-152.87 12.7769,-152.87 29.7957,-152.87\"/>\n",
|
||||||
|
"<polygon fill=\"black\" stroke=\"black\" points=\"36.8867,-152.87 29.8867,-156.02 33.3867,-152.87 29.8867,-152.87 29.8867,-152.87 29.8867,-152.87 33.3867,-152.87 29.8867,-149.72 36.8867,-152.87 36.8867,-152.87\"/>\n",
|
||||||
|
"</g>\n",
|
||||||
|
"<!-- 1 -->\n",
|
||||||
|
"<g id=\"node3\" class=\"node\"><title>1</title>\n",
|
||||||
|
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"783.642\" cy=\"-188.87\" rx=\"236.762\" ry=\"26.7407\"/>\n",
|
||||||
|
"<text text-anchor=\"middle\" x=\"783.642\" y=\"-192.67\" font-family=\"Lato\" font-size=\"14.00\">_nr_pr=1, P_0._pc=0, P_0._pid=0, P_0.a=1, P_0.b=0</text>\n",
|
||||||
|
"<text text-anchor=\"middle\" x=\"783.642\" y=\"-177.67\" font-family=\"Lato\" font-size=\"14.00\">"P_0.a < 2" & !"P_0.b > 1" & !dead</text>\n",
|
||||||
|
"</g>\n",
|
||||||
|
"<!-- 0->1 -->\n",
|
||||||
|
"<g id=\"edge2\" class=\"edge\"><title>0->1</title>\n",
|
||||||
|
"<path fill=\"none\" stroke=\"black\" d=\"M475.197,-167.072C508.083,-169.404 542.225,-171.825 575.278,-174.168\"/>\n",
|
||||||
|
"<polygon fill=\"black\" stroke=\"black\" points=\"582.314,-174.667 575.109,-177.314 578.823,-174.419 575.331,-174.172 575.331,-174.172 575.331,-174.172 578.823,-174.419 575.554,-171.03 582.314,-174.667 582.314,-174.667\"/>\n",
|
||||||
|
"</g>\n",
|
||||||
|
"<!-- 2 -->\n",
|
||||||
|
"<g id=\"node4\" class=\"node\"><title>2</title>\n",
|
||||||
|
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"783.642\" cy=\"-116.87\" rx=\"236.762\" ry=\"26.7407\"/>\n",
|
||||||
|
"<text text-anchor=\"middle\" x=\"783.642\" y=\"-120.67\" font-family=\"Lato\" font-size=\"14.00\">_nr_pr=1, P_0._pc=0, P_0._pid=0, P_0.a=0, P_0.b=1</text>\n",
|
||||||
|
"<text text-anchor=\"middle\" x=\"783.642\" y=\"-105.67\" font-family=\"Lato\" font-size=\"14.00\">"P_0.a < 2" & !"P_0.b > 1" & !dead</text>\n",
|
||||||
|
"</g>\n",
|
||||||
|
"<!-- 0->2 -->\n",
|
||||||
|
"<g id=\"edge3\" class=\"edge\"><title>0->2</title>\n",
|
||||||
|
"<path fill=\"none\" stroke=\"black\" d=\"M475.197,-138.668C508.083,-136.336 542.225,-133.915 575.278,-131.572\"/>\n",
|
||||||
|
"<polygon fill=\"black\" stroke=\"black\" points=\"582.314,-131.073 575.554,-134.71 578.823,-131.321 575.331,-131.568 575.331,-131.568 575.331,-131.568 578.823,-131.321 575.109,-128.426 582.314,-131.073 582.314,-131.073\"/>\n",
|
||||||
|
"</g>\n",
|
||||||
|
"<!-- 3 -->\n",
|
||||||
|
"<g id=\"node5\" class=\"node\"><title>3</title>\n",
|
||||||
|
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"1293.4\" cy=\"-224.87\" rx=\"236.762\" ry=\"26.7407\"/>\n",
|
||||||
|
"<text text-anchor=\"middle\" x=\"1293.4\" y=\"-228.67\" font-family=\"Lato\" font-size=\"14.00\">_nr_pr=1, P_0._pc=0, P_0._pid=0, P_0.a=2, P_0.b=0</text>\n",
|
||||||
|
"<text text-anchor=\"middle\" x=\"1293.4\" y=\"-213.67\" font-family=\"Lato\" font-size=\"14.00\">!"P_0.a < 2" & !"P_0.b > 1" & !dead</text>\n",
|
||||||
|
"</g>\n",
|
||||||
|
"<!-- 1->3 -->\n",
|
||||||
|
"<g id=\"edge4\" class=\"edge\"><title>1->3</title>\n",
|
||||||
|
"<path fill=\"none\" stroke=\"black\" d=\"M984.959,-203.072C1017.84,-205.404 1051.99,-207.825 1085.04,-210.168\"/>\n",
|
||||||
|
"<polygon fill=\"black\" stroke=\"black\" points=\"1092.08,-210.667 1084.87,-213.314 1088.58,-210.419 1085.09,-210.172 1085.09,-210.172 1085.09,-210.172 1088.58,-210.419 1085.32,-207.03 1092.08,-210.667 1092.08,-210.667\"/>\n",
|
||||||
|
"</g>\n",
|
||||||
|
"<!-- 4 -->\n",
|
||||||
|
"<g id=\"node6\" class=\"node\"><title>4</title>\n",
|
||||||
|
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"1293.4\" cy=\"-152.87\" rx=\"236.762\" ry=\"26.7407\"/>\n",
|
||||||
|
"<text text-anchor=\"middle\" x=\"1293.4\" y=\"-156.67\" font-family=\"Lato\" font-size=\"14.00\">_nr_pr=1, P_0._pc=0, P_0._pid=0, P_0.a=1, P_0.b=1</text>\n",
|
||||||
|
"<text text-anchor=\"middle\" x=\"1293.4\" y=\"-141.67\" font-family=\"Lato\" font-size=\"14.00\">"P_0.a < 2" & !"P_0.b > 1" & !dead</text>\n",
|
||||||
|
"</g>\n",
|
||||||
|
"<!-- 1->4 -->\n",
|
||||||
|
"<g id=\"edge5\" class=\"edge\"><title>1->4</title>\n",
|
||||||
|
"<path fill=\"none\" stroke=\"black\" d=\"M984.959,-174.668C1017.84,-172.336 1051.99,-169.915 1085.04,-167.572\"/>\n",
|
||||||
|
"<polygon fill=\"black\" stroke=\"black\" points=\"1092.08,-167.073 1085.32,-170.71 1088.58,-167.321 1085.09,-167.568 1085.09,-167.568 1085.09,-167.568 1088.58,-167.321 1084.87,-164.426 1092.08,-167.073 1092.08,-167.073\"/>\n",
|
||||||
|
"</g>\n",
|
||||||
|
"<!-- 2->4 -->\n",
|
||||||
|
"<g id=\"edge6\" class=\"edge\"><title>2->4</title>\n",
|
||||||
|
"<path fill=\"none\" stroke=\"black\" d=\"M984.959,-131.072C1017.84,-133.404 1051.99,-135.825 1085.04,-138.168\"/>\n",
|
||||||
|
"<polygon fill=\"black\" stroke=\"black\" points=\"1092.08,-138.667 1084.87,-141.314 1088.58,-138.419 1085.09,-138.172 1085.09,-138.172 1085.09,-138.172 1088.58,-138.419 1085.32,-135.03 1092.08,-138.667 1092.08,-138.667\"/>\n",
|
||||||
|
"</g>\n",
|
||||||
|
"<!-- 5 -->\n",
|
||||||
|
"<g id=\"node7\" class=\"node\"><title>5</title>\n",
|
||||||
|
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"1293.4\" cy=\"-80.8701\" rx=\"236.762\" ry=\"26.7407\"/>\n",
|
||||||
|
"<text text-anchor=\"middle\" x=\"1293.4\" y=\"-84.6701\" font-family=\"Lato\" font-size=\"14.00\">_nr_pr=1, P_0._pc=0, P_0._pid=0, P_0.a=0, P_0.b=2</text>\n",
|
||||||
|
"<text text-anchor=\"middle\" x=\"1293.4\" y=\"-69.6701\" font-family=\"Lato\" font-size=\"14.00\">"P_0.a < 2" & "P_0.b > 1" & !dead</text>\n",
|
||||||
|
"</g>\n",
|
||||||
|
"<!-- 2->5 -->\n",
|
||||||
|
"<g id=\"edge7\" class=\"edge\"><title>2->5</title>\n",
|
||||||
|
"<path fill=\"none\" stroke=\"black\" d=\"M984.959,-102.668C1017.84,-100.336 1051.99,-97.9155 1085.04,-95.5721\"/>\n",
|
||||||
|
"<polygon fill=\"black\" stroke=\"black\" points=\"1092.08,-95.0732 1085.32,-98.7105 1088.58,-95.3208 1085.09,-95.5684 1085.09,-95.5684 1085.09,-95.5684 1088.58,-95.3208 1084.87,-92.4263 1092.08,-95.0732 1092.08,-95.0732\"/>\n",
|
||||||
|
"</g>\n",
|
||||||
|
"<!-- 6 -->\n",
|
||||||
|
"<g id=\"node8\" class=\"node\"><title>6</title>\n",
|
||||||
|
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"1803.17\" cy=\"-260.87\" rx=\"236.762\" ry=\"26.7407\"/>\n",
|
||||||
|
"<text text-anchor=\"middle\" x=\"1803.17\" y=\"-264.67\" font-family=\"Lato\" font-size=\"14.00\">_nr_pr=1, P_0._pc=0, P_0._pid=0, P_0.a=3, P_0.b=0</text>\n",
|
||||||
|
"<text text-anchor=\"middle\" x=\"1803.17\" y=\"-249.67\" font-family=\"Lato\" font-size=\"14.00\">!"P_0.a < 2" & !"P_0.b > 1" & dead</text>\n",
|
||||||
|
"</g>\n",
|
||||||
|
"<!-- 3->6 -->\n",
|
||||||
|
"<g id=\"edge8\" class=\"edge\"><title>3->6</title>\n",
|
||||||
|
"<path fill=\"none\" stroke=\"black\" d=\"M1494.72,-239.072C1527.61,-241.404 1561.75,-243.825 1594.8,-246.168\"/>\n",
|
||||||
|
"<polygon fill=\"black\" stroke=\"black\" points=\"1601.84,-246.667 1594.63,-249.314 1598.35,-246.419 1594.85,-246.172 1594.85,-246.172 1594.85,-246.172 1598.35,-246.419 1595.08,-243.03 1601.84,-246.667 1601.84,-246.667\"/>\n",
|
||||||
|
"</g>\n",
|
||||||
|
"<!-- 7 -->\n",
|
||||||
|
"<g id=\"node9\" class=\"node\"><title>7</title>\n",
|
||||||
|
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"1803.17\" cy=\"-188.87\" rx=\"236.762\" ry=\"26.7407\"/>\n",
|
||||||
|
"<text text-anchor=\"middle\" x=\"1803.17\" y=\"-192.67\" font-family=\"Lato\" font-size=\"14.00\">_nr_pr=1, P_0._pc=0, P_0._pid=0, P_0.a=2, P_0.b=1</text>\n",
|
||||||
|
"<text text-anchor=\"middle\" x=\"1803.17\" y=\"-177.67\" font-family=\"Lato\" font-size=\"14.00\">!"P_0.a < 2" & !"P_0.b > 1" & !dead</text>\n",
|
||||||
|
"</g>\n",
|
||||||
|
"<!-- 3->7 -->\n",
|
||||||
|
"<g id=\"edge9\" class=\"edge\"><title>3->7</title>\n",
|
||||||
|
"<path fill=\"none\" stroke=\"black\" d=\"M1494.72,-210.668C1527.61,-208.336 1561.75,-205.915 1594.8,-203.572\"/>\n",
|
||||||
|
"<polygon fill=\"black\" stroke=\"black\" points=\"1601.84,-203.073 1595.08,-206.71 1598.35,-203.321 1594.85,-203.568 1594.85,-203.568 1594.85,-203.568 1598.35,-203.321 1594.63,-200.426 1601.84,-203.073 1601.84,-203.073\"/>\n",
|
||||||
|
"</g>\n",
|
||||||
|
"<!-- 4->7 -->\n",
|
||||||
|
"<g id=\"edge10\" class=\"edge\"><title>4->7</title>\n",
|
||||||
|
"<path fill=\"none\" stroke=\"black\" d=\"M1494.72,-167.072C1527.61,-169.404 1561.75,-171.825 1594.8,-174.168\"/>\n",
|
||||||
|
"<polygon fill=\"black\" stroke=\"black\" points=\"1601.84,-174.667 1594.63,-177.314 1598.35,-174.419 1594.85,-174.172 1594.85,-174.172 1594.85,-174.172 1598.35,-174.419 1595.08,-171.03 1601.84,-174.667 1601.84,-174.667\"/>\n",
|
||||||
|
"</g>\n",
|
||||||
|
"<!-- 8 -->\n",
|
||||||
|
"<g id=\"node10\" class=\"node\"><title>8</title>\n",
|
||||||
|
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"1803.17\" cy=\"-116.87\" rx=\"236.762\" ry=\"26.7407\"/>\n",
|
||||||
|
"<text text-anchor=\"middle\" x=\"1803.17\" y=\"-120.67\" font-family=\"Lato\" font-size=\"14.00\">_nr_pr=1, P_0._pc=0, P_0._pid=0, P_0.a=1, P_0.b=2</text>\n",
|
||||||
|
"<text text-anchor=\"middle\" x=\"1803.17\" y=\"-105.67\" font-family=\"Lato\" font-size=\"14.00\">"P_0.a < 2" & "P_0.b > 1" & !dead</text>\n",
|
||||||
|
"</g>\n",
|
||||||
|
"<!-- 4->8 -->\n",
|
||||||
|
"<g id=\"edge11\" class=\"edge\"><title>4->8</title>\n",
|
||||||
|
"<path fill=\"none\" stroke=\"black\" d=\"M1494.72,-138.668C1527.61,-136.336 1561.75,-133.915 1594.8,-131.572\"/>\n",
|
||||||
|
"<polygon fill=\"black\" stroke=\"black\" points=\"1601.84,-131.073 1595.08,-134.71 1598.35,-131.321 1594.85,-131.568 1594.85,-131.568 1594.85,-131.568 1598.35,-131.321 1594.63,-128.426 1601.84,-131.073 1601.84,-131.073\"/>\n",
|
||||||
|
"</g>\n",
|
||||||
|
"<!-- 5->8 -->\n",
|
||||||
|
"<g id=\"edge12\" class=\"edge\"><title>5->8</title>\n",
|
||||||
|
"<path fill=\"none\" stroke=\"black\" d=\"M1494.72,-95.0724C1527.61,-97.404 1561.75,-99.8246 1594.8,-102.168\"/>\n",
|
||||||
|
"<polygon fill=\"black\" stroke=\"black\" points=\"1601.84,-102.667 1594.63,-105.314 1598.35,-102.419 1594.85,-102.172 1594.85,-102.172 1594.85,-102.172 1598.35,-102.419 1595.08,-99.0296 1601.84,-102.667 1601.84,-102.667\"/>\n",
|
||||||
|
"</g>\n",
|
||||||
|
"<!-- 9 -->\n",
|
||||||
|
"<g id=\"node11\" class=\"node\"><title>9</title>\n",
|
||||||
|
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"1803.17\" cy=\"-26.8701\" rx=\"236.762\" ry=\"26.7407\"/>\n",
|
||||||
|
"<text text-anchor=\"middle\" x=\"1803.17\" y=\"-30.6701\" font-family=\"Lato\" font-size=\"14.00\">_nr_pr=1, P_0._pc=0, P_0._pid=0, P_0.a=0, P_0.b=3</text>\n",
|
||||||
|
"<text text-anchor=\"middle\" x=\"1803.17\" y=\"-15.6701\" font-family=\"Lato\" font-size=\"14.00\">"P_0.a < 2" & "P_0.b > 1" & dead</text>\n",
|
||||||
|
"</g>\n",
|
||||||
|
"<!-- 5->9 -->\n",
|
||||||
|
"<g id=\"edge13\" class=\"edge\"><title>5->9</title>\n",
|
||||||
|
"<path fill=\"none\" stroke=\"black\" d=\"M1467.02,-62.5128C1517.13,-57.1834 1571.96,-51.3518 1622.5,-45.9776\"/>\n",
|
||||||
|
"<polygon fill=\"black\" stroke=\"black\" points=\"1629.6,-45.2224 1622.97,-49.0951 1626.12,-45.5926 1622.64,-45.9628 1622.64,-45.9628 1622.64,-45.9628 1626.12,-45.5926 1622.3,-42.8304 1629.6,-45.2224 1629.6,-45.2224\"/>\n",
|
||||||
|
"</g>\n",
|
||||||
|
"<!-- 6->6 -->\n",
|
||||||
|
"<g id=\"edge14\" class=\"edge\"><title>6->6</title>\n",
|
||||||
|
"<path fill=\"none\" stroke=\"black\" d=\"M1709.05,-285.787C1701.35,-296.536 1732.72,-305.74 1803.17,-305.74 1857.1,-305.74 1888.13,-300.345 1896.25,-292.992\"/>\n",
|
||||||
|
"<polygon fill=\"black\" stroke=\"black\" points=\"1897.28,-285.787 1899.41,-293.16 1896.78,-289.252 1896.29,-292.717 1896.29,-292.717 1896.29,-292.717 1896.78,-289.252 1893.17,-292.275 1897.28,-285.787 1897.28,-285.787\"/>\n",
|
||||||
|
"</g>\n",
|
||||||
|
"<!-- 10 -->\n",
|
||||||
|
"<g id=\"node12\" class=\"node\"><title>10</title>\n",
|
||||||
|
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"2312.93\" cy=\"-224.87\" rx=\"236.762\" ry=\"26.7407\"/>\n",
|
||||||
|
"<text text-anchor=\"middle\" x=\"2312.93\" y=\"-228.67\" font-family=\"Lato\" font-size=\"14.00\">_nr_pr=1, P_0._pc=0, P_0._pid=0, P_0.a=3, P_0.b=1</text>\n",
|
||||||
|
"<text text-anchor=\"middle\" x=\"2312.93\" y=\"-213.67\" font-family=\"Lato\" font-size=\"14.00\">!"P_0.a < 2" & !"P_0.b > 1" & dead</text>\n",
|
||||||
|
"</g>\n",
|
||||||
|
"<!-- 7->10 -->\n",
|
||||||
|
"<g id=\"edge15\" class=\"edge\"><title>7->10</title>\n",
|
||||||
|
"<path fill=\"none\" stroke=\"black\" d=\"M2004.48,-203.072C2037.37,-205.404 2071.51,-207.825 2104.56,-210.168\"/>\n",
|
||||||
|
"<polygon fill=\"black\" stroke=\"black\" points=\"2111.6,-210.667 2104.39,-213.314 2108.11,-210.419 2104.62,-210.172 2104.62,-210.172 2104.62,-210.172 2108.11,-210.419 2104.84,-207.03 2111.6,-210.667 2111.6,-210.667\"/>\n",
|
||||||
|
"</g>\n",
|
||||||
|
"<!-- 11 -->\n",
|
||||||
|
"<g id=\"node13\" class=\"node\"><title>11</title>\n",
|
||||||
|
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"2312.93\" cy=\"-152.87\" rx=\"236.762\" ry=\"26.7407\"/>\n",
|
||||||
|
"<text text-anchor=\"middle\" x=\"2312.93\" y=\"-156.67\" font-family=\"Lato\" font-size=\"14.00\">_nr_pr=1, P_0._pc=0, P_0._pid=0, P_0.a=2, P_0.b=2</text>\n",
|
||||||
|
"<text text-anchor=\"middle\" x=\"2312.93\" y=\"-141.67\" font-family=\"Lato\" font-size=\"14.00\">!"P_0.a < 2" & "P_0.b > 1" & !dead</text>\n",
|
||||||
|
"</g>\n",
|
||||||
|
"<!-- 7->11 -->\n",
|
||||||
|
"<g id=\"edge16\" class=\"edge\"><title>7->11</title>\n",
|
||||||
|
"<path fill=\"none\" stroke=\"black\" d=\"M2004.48,-174.668C2037.37,-172.336 2071.51,-169.915 2104.56,-167.572\"/>\n",
|
||||||
|
"<polygon fill=\"black\" stroke=\"black\" points=\"2111.6,-167.073 2104.84,-170.71 2108.11,-167.321 2104.62,-167.568 2104.62,-167.568 2104.62,-167.568 2108.11,-167.321 2104.39,-164.426 2111.6,-167.073 2111.6,-167.073\"/>\n",
|
||||||
|
"</g>\n",
|
||||||
|
"<!-- 8->11 -->\n",
|
||||||
|
"<g id=\"edge17\" class=\"edge\"><title>8->11</title>\n",
|
||||||
|
"<path fill=\"none\" stroke=\"black\" d=\"M2004.48,-131.072C2037.37,-133.404 2071.51,-135.825 2104.56,-138.168\"/>\n",
|
||||||
|
"<polygon fill=\"black\" stroke=\"black\" points=\"2111.6,-138.667 2104.39,-141.314 2108.11,-138.419 2104.62,-138.172 2104.62,-138.172 2104.62,-138.172 2108.11,-138.419 2104.84,-135.03 2111.6,-138.667 2111.6,-138.667\"/>\n",
|
||||||
|
"</g>\n",
|
||||||
|
"<!-- 12 -->\n",
|
||||||
|
"<g id=\"node14\" class=\"node\"><title>12</title>\n",
|
||||||
|
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"2312.93\" cy=\"-62.8701\" rx=\"236.762\" ry=\"26.7407\"/>\n",
|
||||||
|
"<text text-anchor=\"middle\" x=\"2312.93\" y=\"-66.6701\" font-family=\"Lato\" font-size=\"14.00\">_nr_pr=1, P_0._pc=0, P_0._pid=0, P_0.a=1, P_0.b=3</text>\n",
|
||||||
|
"<text text-anchor=\"middle\" x=\"2312.93\" y=\"-51.6701\" font-family=\"Lato\" font-size=\"14.00\">"P_0.a < 2" & "P_0.b > 1" & dead</text>\n",
|
||||||
|
"</g>\n",
|
||||||
|
"<!-- 8->12 -->\n",
|
||||||
|
"<g id=\"edge18\" class=\"edge\"><title>8->12</title>\n",
|
||||||
|
"<path fill=\"none\" stroke=\"black\" d=\"M1976.78,-98.5128C2026.89,-93.1834 2081.73,-87.3518 2132.26,-81.9776\"/>\n",
|
||||||
|
"<polygon fill=\"black\" stroke=\"black\" points=\"2139.36,-81.2224 2132.73,-85.0951 2135.88,-81.5926 2132.4,-81.9628 2132.4,-81.9628 2132.4,-81.9628 2135.88,-81.5926 2132.07,-78.8304 2139.36,-81.2224 2139.36,-81.2224\"/>\n",
|
||||||
|
"</g>\n",
|
||||||
|
"<!-- 9->9 -->\n",
|
||||||
|
"<g id=\"edge19\" class=\"edge\"><title>9->9</title>\n",
|
||||||
|
"<path fill=\"none\" stroke=\"black\" d=\"M1709.05,-51.7868C1701.35,-62.5364 1732.72,-71.7401 1803.17,-71.7401 1857.1,-71.7401 1888.13,-66.3451 1896.25,-58.9918\"/>\n",
|
||||||
|
"<polygon fill=\"black\" stroke=\"black\" points=\"1897.28,-51.7868 1899.41,-59.1598 1896.78,-55.2521 1896.29,-58.7174 1896.29,-58.7174 1896.29,-58.7174 1896.78,-55.2521 1893.17,-58.2751 1897.28,-51.7868 1897.28,-51.7868\"/>\n",
|
||||||
|
"</g>\n",
|
||||||
|
"<!-- 10->10 -->\n",
|
||||||
|
"<g id=\"edge20\" class=\"edge\"><title>10->10</title>\n",
|
||||||
|
"<path fill=\"none\" stroke=\"black\" d=\"M2218.82,-249.787C2211.11,-260.536 2242.48,-269.74 2312.93,-269.74 2366.86,-269.74 2397.89,-264.345 2406.02,-256.992\"/>\n",
|
||||||
|
"<polygon fill=\"black\" stroke=\"black\" points=\"2407.04,-249.787 2409.17,-257.16 2406.55,-253.252 2406.05,-256.717 2406.05,-256.717 2406.05,-256.717 2406.55,-253.252 2402.94,-256.275 2407.04,-249.787 2407.04,-249.787\"/>\n",
|
||||||
|
"</g>\n",
|
||||||
|
"<!-- 13 -->\n",
|
||||||
|
"<g id=\"node15\" class=\"node\"><title>13</title>\n",
|
||||||
|
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"2822.69\" cy=\"-197.87\" rx=\"236.762\" ry=\"26.7407\"/>\n",
|
||||||
|
"<text text-anchor=\"middle\" x=\"2822.69\" y=\"-201.67\" font-family=\"Lato\" font-size=\"14.00\">_nr_pr=1, P_0._pc=0, P_0._pid=0, P_0.a=3, P_0.b=2</text>\n",
|
||||||
|
"<text text-anchor=\"middle\" x=\"2822.69\" y=\"-186.67\" font-family=\"Lato\" font-size=\"14.00\">!"P_0.a < 2" & "P_0.b > 1" & dead</text>\n",
|
||||||
|
"</g>\n",
|
||||||
|
"<!-- 11->13 -->\n",
|
||||||
|
"<g id=\"edge21\" class=\"edge\"><title>11->13</title>\n",
|
||||||
|
"<path fill=\"none\" stroke=\"black\" d=\"M2500.12,-169.371C2541.94,-173.078 2586.41,-177.019 2628.51,-180.75\"/>\n",
|
||||||
|
"<polygon fill=\"black\" stroke=\"black\" points=\"2635.52,-181.371 2628.27,-183.891 2632.04,-181.062 2628.55,-180.753 2628.55,-180.753 2628.55,-180.753 2632.04,-181.062 2628.83,-177.615 2635.52,-181.371 2635.52,-181.371\"/>\n",
|
||||||
|
"</g>\n",
|
||||||
|
"<!-- 14 -->\n",
|
||||||
|
"<g id=\"node16\" class=\"node\"><title>14</title>\n",
|
||||||
|
"<ellipse fill=\"#ffffaa\" stroke=\"black\" cx=\"2822.69\" cy=\"-107.87\" rx=\"236.762\" ry=\"26.7407\"/>\n",
|
||||||
|
"<text text-anchor=\"middle\" x=\"2822.69\" y=\"-111.67\" font-family=\"Lato\" font-size=\"14.00\">_nr_pr=1, P_0._pc=0, P_0._pid=0, P_0.a=2, P_0.b=3</text>\n",
|
||||||
|
"<text text-anchor=\"middle\" x=\"2822.69\" y=\"-96.6701\" font-family=\"Lato\" font-size=\"14.00\">!"P_0.a < 2" & "P_0.b > 1" & dead</text>\n",
|
||||||
|
"</g>\n",
|
||||||
|
"<!-- 11->14 -->\n",
|
||||||
|
"<g id=\"edge22\" class=\"edge\"><title>11->14</title>\n",
|
||||||
|
"<path fill=\"none\" stroke=\"black\" d=\"M2500.12,-136.369C2541.94,-132.663 2586.41,-128.721 2628.51,-124.99\"/>\n",
|
||||||
|
"<polygon fill=\"black\" stroke=\"black\" points=\"2635.52,-124.369 2628.83,-128.125 2632.04,-124.678 2628.55,-124.987 2628.55,-124.987 2628.55,-124.987 2632.04,-124.678 2628.27,-121.849 2635.52,-124.369 2635.52,-124.369\"/>\n",
|
||||||
|
"</g>\n",
|
||||||
|
"<!-- 12->12 -->\n",
|
||||||
|
"<g id=\"edge23\" class=\"edge\"><title>12->12</title>\n",
|
||||||
|
"<path fill=\"none\" stroke=\"black\" d=\"M2218.82,-87.7868C2211.11,-98.5364 2242.48,-107.74 2312.93,-107.74 2366.86,-107.74 2397.89,-102.345 2406.02,-94.9918\"/>\n",
|
||||||
|
"<polygon fill=\"black\" stroke=\"black\" points=\"2407.04,-87.7868 2409.17,-95.1598 2406.55,-91.2521 2406.05,-94.7174 2406.05,-94.7174 2406.05,-94.7174 2406.55,-91.2521 2402.94,-94.2751 2407.04,-87.7868 2407.04,-87.7868\"/>\n",
|
||||||
|
"</g>\n",
|
||||||
|
"<!-- 13->13 -->\n",
|
||||||
|
"<g id=\"edge24\" class=\"edge\"><title>13->13</title>\n",
|
||||||
|
"<path fill=\"none\" stroke=\"black\" d=\"M2728.58,-222.787C2720.87,-233.536 2752.24,-242.74 2822.69,-242.74 2876.62,-242.74 2907.65,-237.345 2915.78,-229.992\"/>\n",
|
||||||
|
"<polygon fill=\"black\" stroke=\"black\" points=\"2916.8,-222.787 2918.93,-230.16 2916.31,-226.252 2915.82,-229.717 2915.82,-229.717 2915.82,-229.717 2916.31,-226.252 2912.7,-229.275 2916.8,-222.787 2916.8,-222.787\"/>\n",
|
||||||
|
"</g>\n",
|
||||||
|
"<!-- 14->14 -->\n",
|
||||||
|
"<g id=\"edge25\" class=\"edge\"><title>14->14</title>\n",
|
||||||
|
"<path fill=\"none\" stroke=\"black\" d=\"M2728.58,-132.787C2720.87,-143.536 2752.24,-152.74 2822.69,-152.74 2876.62,-152.74 2907.65,-147.345 2915.78,-139.992\"/>\n",
|
||||||
|
"<polygon fill=\"black\" stroke=\"black\" points=\"2916.8,-132.787 2918.93,-140.16 2916.31,-136.252 2915.82,-139.717 2915.82,-139.717 2915.82,-139.717 2916.31,-136.252 2912.7,-139.275 2916.8,-132.787 2916.8,-132.787\"/>\n",
|
||||||
|
"</g>\n",
|
||||||
|
"</g>\n",
|
||||||
|
"</svg>\n"
|
||||||
|
],
|
||||||
|
"text": [
|
||||||
|
"<spot.impl.kripke; proxy of <Swig Object of type 'std::shared_ptr< spot::kripke > *' at 0x7f87ac090240> >"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"prompt_number": 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"And then from this Kripke structure you can do some model checking using the same functions as illustrated in `ltsmin-dve.ipynb`.\n",
|
||||||
|
"\n",
|
||||||
|
"Loading from a `*.pml` file\n",
|
||||||
|
"---------------------------\n",
|
||||||
|
"\n",
|
||||||
|
"Another option is to use `ltsmin.load()` to load a Promela file directly. In order for this test-case to be self-contained, we are going to write the Promela file first, but in practice you probably already have your model."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"collapsed": false,
|
||||||
|
"input": [
|
||||||
|
"!rm -rf test1.pml"
|
||||||
|
],
|
||||||
|
"language": "python",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"prompt_number": 5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"collapsed": false,
|
||||||
|
"input": [
|
||||||
|
"%%file test1.pml\n",
|
||||||
|
"active proctype P() {\n",
|
||||||
|
"int a = 0;\n",
|
||||||
|
"int b = 0;\n",
|
||||||
|
"x: if\n",
|
||||||
|
" :: d_step {a < 3 && b < 3; a = a + 1; } goto x;\n",
|
||||||
|
" :: d_step {a < 3 && b < 3; b = b + 1; } goto x;\n",
|
||||||
|
"fi;\n",
|
||||||
|
"}"
|
||||||
|
],
|
||||||
|
"language": "python",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"output_type": "stream",
|
||||||
|
"stream": "stdout",
|
||||||
|
"text": [
|
||||||
|
"Writing test1.pml\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"prompt_number": 6
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"Now load it:"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"collapsed": false,
|
||||||
|
"input": [
|
||||||
|
"model2 = spot.ltsmin.load('test1.pml')"
|
||||||
|
],
|
||||||
|
"language": "python",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"prompt_number": 7
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"collapsed": false,
|
||||||
|
"input": [
|
||||||
|
"model2"
|
||||||
|
],
|
||||||
|
"language": "python",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"metadata": {},
|
||||||
|
"output_type": "pyout",
|
||||||
|
"prompt_number": 8,
|
||||||
|
"text": [
|
||||||
|
"ltsmin model with the following variables:\n",
|
||||||
|
" _nr_pr: int\n",
|
||||||
|
" P_0._pc: pc\n",
|
||||||
|
" P_0._pid: pid\n",
|
||||||
|
" P_0.a: int\n",
|
||||||
|
" P_0.b: int"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"prompt_number": 8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"collapsed": false,
|
||||||
|
"input": [
|
||||||
|
"!rm -f test1.pml test1.pml.spins.c test1.pml.spins"
|
||||||
|
],
|
||||||
|
"language": "python",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"prompt_number": 9
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"metadata": {}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue