python: implement formula.__format__

Fixes #105.

* src/bin/common_trans.cc (quote_shell_string): Move ...
* src/misc/escape.cc, src/misc/escape.hh (quote_shell_string):
... here.
* wrap/python/spot_impl.i: Wrap escape.hh.
* wrap/python/spot.py: Implement formula.__format__.
* wrap/python/tests/ltlsimple.py: Test it.
* NEWS, doc/org/tut01.org, wrap/python/tests/formulas.ipynb: Document
it.
This commit is contained in:
Alexandre Duret-Lutz 2015-10-03 11:20:02 +02:00
parent 20bb171904
commit 5bfd0267e7
9 changed files with 364 additions and 67 deletions

View file

@ -1,7 +1,23 @@
{
"metadata": {
"name": "",
"signature": "sha256:049261ec6b13505007796a9e9d1d8279783233b9b1eb8f9b8e5727070a38db7a"
"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.4.3+"
},
"name": ""
},
"nbformat": 3,
"nbformat_minor": 0,
@ -172,6 +188,100 @@
],
"prompt_number": 6
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Formulas output via `format()` can also use some convenient shorthand to select the syntax:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"print(\"\"\"\\\n",
"Spin: {0:s}\n",
"Spin+parentheses: {0:sp}\n",
"Spot (default): {0}\n",
"Spot+shell quotes: {0:q}\n",
"LBT, right aligned: {0:l:~>40}\"\"\".format(f))"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"Spin: p1 U (p2 V (p3 && !p4))\n",
"Spin+parentheses: (p1) U ((p2) V ((p3) && (!(p4))))\n",
"Spot (default): p1 U (p2 R (p3 & !p4))\n",
"Spot+shell quotes: 'p1 U (p2 R (p3 & !p4))'\n",
"LBT, right aligned: ~~~~~~~~~~~~~~~~~~~~~U p1 V p2 & p3 ! p4\n"
]
}
],
"prompt_number": 7
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The specifiers that can be used with `format` are documented as follows:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"help(spot.formula.__format__)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"Help on function _formula_format in module spot:\n",
"\n",
"_formula_format(self, spec)\n",
" Format the formula according to spec.\n",
" \n",
" 'spec' should be a list of letters that select\n",
" how the formula should be formatted.\n",
" \n",
" Use one of the following letters to select the syntax:\n",
" \n",
" - 'f': use Spot's syntax (default)\n",
" - '8': use Spot's syntax in UTF-8 mode\n",
" - 's': use Spin's syntax\n",
" - 'l': use LBT's syntax\n",
" - 'w': use Wring's syntax\n",
" - 'x': use LaTeX output\n",
" - 'X': use self-contained LaTeX output\n",
" \n",
" Add some of those letters for additional options:\n",
" \n",
" - 'p': use full parentheses\n",
" - 'c': escape the formula for CSV output (this will\n",
" enclose the formula in double quotes, and escape\n",
" any included double quotes)\n",
" - 'h': escape the formula for HTML output\n",
" - 'd': escape double quotes and backslash,\n",
" for use in C-strings (the outermost double\n",
" quotes are *not* added)\n",
" - 'q': quote and escape for shell output, using single\n",
" quotes or double quotes depending on the contents.\n",
" \n",
" - ':spec': pass the remaining specification to the\n",
" formating function for strings.\n",
"\n"
]
}
],
"prompt_number": 8
},
{
"cell_type": "markdown",
"metadata": {},
@ -191,13 +301,13 @@
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 7,
"prompt_number": 9,
"text": [
"True"
]
}
],
"prompt_number": 7
"prompt_number": 9
},
{
"cell_type": "code",
@ -211,13 +321,13 @@
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 8,
"prompt_number": 10,
"text": [
"False"
]
}
],
"prompt_number": 8
"prompt_number": 10
},
{
"cell_type": "markdown",
@ -238,13 +348,13 @@
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 9,
"prompt_number": 11,
"text": [
"True"
]
}
],
"prompt_number": 9
"prompt_number": 11
},
{
"cell_type": "code",
@ -258,13 +368,13 @@
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 10,
"prompt_number": 12,
"text": [
"False"
]
}
],
"prompt_number": 10
"prompt_number": 12
},
{
"cell_type": "code",
@ -278,13 +388,13 @@
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 11,
"prompt_number": 13,
"text": [
"True"
]
}
],
"prompt_number": 11
"prompt_number": 13
},
{
"cell_type": "markdown",
@ -308,13 +418,13 @@
],
"metadata": {},
"output_type": "pyout",
"prompt_number": 12,
"prompt_number": 14,
"text": [
"\"a > b\" & \"proc[2]@init\" & GF_foo_"
]
}
],
"prompt_number": 12
"prompt_number": 14
},
{
"cell_type": "code",
@ -331,13 +441,13 @@
],
"metadata": {},
"output_type": "pyout",
"prompt_number": 13,
"prompt_number": 15,
"text": [
"a & b & GFc"
]
}
],
"prompt_number": 13
"prompt_number": 15
},
{
"cell_type": "code",
@ -354,13 +464,13 @@
],
"metadata": {},
"output_type": "pyout",
"prompt_number": 14,
"prompt_number": 16,
"text": [
"p0 & p1 & GFp2"
]
}
],
"prompt_number": 14
"prompt_number": 16
},
{
"cell_type": "markdown",
@ -388,7 +498,7 @@
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 15,
"prompt_number": 17,
"svg": [
"<svg height=\"260pt\" viewBox=\"0.00 0.00 269.00 260.00\" width=\"269pt\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
"<g class=\"graph\" id=\"graph0\" transform=\"scale(1 1) rotate(0) translate(4 256)\">\n",
@ -493,11 +603,11 @@
"</svg>"
],
"text": [
"<IPython.core.display.SVG at 0x7f4dfea9c710>"
"<IPython.core.display.SVG object>"
]
}
],
"prompt_number": 15
"prompt_number": 17
},
{
"cell_type": "code",
@ -514,13 +624,13 @@
],
"metadata": {},
"output_type": "pyout",
"prompt_number": 16,
"prompt_number": 18,
"text": [
"F(a & X(!a & b))"
]
}
],
"prompt_number": 16
"prompt_number": 18
},
{
"cell_type": "markdown",
@ -544,13 +654,13 @@
],
"metadata": {},
"output_type": "pyout",
"prompt_number": 17,
"prompt_number": 19,
"text": [
"F(a & ((a & (a U (!a & b)) & ((!b U !a) | (b U !a))) | (!a & (!a U (a & !a & b)) & ((!b U a) | (b U a))) | (b & (b U (!a & b & !b)) & ((!a U !b) | (a U !b))) | (!b & (!b U (!a & b)) & ((!a U b) | (a U b))) | (!a & b & (G!a | Ga) & (G!b | Gb))))"
]
}
],
"prompt_number": 17
"prompt_number": 19
},
{
"cell_type": "markdown",
@ -575,13 +685,13 @@
],
"metadata": {},
"output_type": "pyout",
"prompt_number": 18,
"prompt_number": 20,
"text": [
"(0 R !(a <-> b)) -> (1 U (a <-> b))"
]
}
],
"prompt_number": 18
"prompt_number": 20
},
{
"cell_type": "code",
@ -598,13 +708,13 @@
],
"metadata": {},
"output_type": "pyout",
"prompt_number": 19,
"prompt_number": 21,
"text": [
"(1 U ((a & b) | (!a & !b))) | !(0 R ((!a & b) | (a & !b)))"
]
}
],
"prompt_number": 19
"prompt_number": 21
}
],
"metadata": {}

View file

@ -93,3 +93,26 @@ def count_g(f):
x += 1
f.traverse(count_g)
assert x == 3
#----------------------------------------------------------------------
# The example from tut01.org
formula = spot.formula('a U b U "$strange[0]=name"')
res = """\
Default output: {f}
Spin syntax: {f:s}
(Spin syntax): {f:sp}
Default for shell: echo {f:q} | ...
LBT for shell: echo {f:lq} | ...
Default for CSV: ...,{f:c},...
Wring, centered: {f:w:~^50}""".format(f = formula)
assert res == """\
Default output: a U (b U "$strange[0]=name")
Spin syntax: a U (b U ($strange[0]=name))
(Spin syntax): (a) U ((b) U ($strange[0]=name))
Default for shell: echo 'a U (b U "$strange[0]=name")' | ...
LBT for shell: echo 'U "a" U "b" "$strange[0]=name"' | ...
Default for CSV: ...,"a U (b U ""$strange[0]=name"")",...
Wring, centered: ~~~~~(a=1) U ((b=1) U ("$strange[0]=name"=1))~~~~~"""