tl: implement suffix operator normal form
* spot/tl/Makefile.am: New sonf files * spot/tl/sonf.cc, spot/tl/sonf.hh: Here. * python/spot/impl.i: include sonf.hh header * doc/spot.bib: add entry for the SONF paper * tests/Makefile.am: new python tests * tests/python/formulas.ipynb: show sample usage * tests/python/sonf.py: test automata equivalence before/after SONF * NEWS: mention the change
This commit is contained in:
parent
c7201e4776
commit
c71691659b
9 changed files with 348 additions and 0 deletions
|
|
@ -445,6 +445,7 @@ TESTS_python = \
|
|||
python/setxor.py \
|
||||
python/simplacc.py \
|
||||
python/simstate.py \
|
||||
python/sonf.py \
|
||||
python/split.py \
|
||||
python/streett_totgba.py \
|
||||
python/streett_totgba2.py \
|
||||
|
|
|
|||
|
|
@ -976,6 +976,62 @@
|
|||
"print(ap) # print as a string\n",
|
||||
"display(ap) # LaTeX-style, for notebooks"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Converting to Suffix Operator Normal Form:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 27,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/latex": [
|
||||
"$\\mathsf{G} (\\{x^{\\star}\\}\\mathrel{\\Box\\kern-1.7pt\\raise.4pt\\hbox{$\\mathord{\\rightarrow}$}} \\mathsf{F} a)$"
|
||||
],
|
||||
"text/plain": [
|
||||
"spot.formula(\"G({x[*]}[]-> Fa)\")"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/latex": [
|
||||
"$\\mathsf{G} \\mathit{sonf\\_}_{0} \\land \\mathsf{G} (\\lnot \\mathit{sonf\\_}_{1} \\lor \\mathsf{F} a) \\land \\mathsf{G} (\\lnot \\mathit{sonf\\_}_{0} \\lor (\\{x^{\\star}\\}\\mathrel{\\Box\\kern-1.7pt\\raise.4pt\\hbox{$\\mathord{\\rightarrow}$}} \\mathit{sonf\\_}_{1}))$"
|
||||
],
|
||||
"text/plain": [
|
||||
"spot.formula(\"Gsonf_0 & G(!sonf_1 | Fa) & G(!sonf_0 | ({x[*]}[]-> sonf_1))\")"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"('sonf_0', 'sonf_1')"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"f = spot.formula('G({x*} []-> Fa)')\n",
|
||||
"display(f)\n",
|
||||
"\n",
|
||||
"# In addition to the formula, returns a list of newly introduced APs\n",
|
||||
"f, aps = spot.suffix_operator_normal_form(f, 'sonf_')\n",
|
||||
"display(f)\n",
|
||||
"display(aps)"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
|
|
|
|||
41
tests/python/sonf.py
Normal file
41
tests/python/sonf.py
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
# -*- mode: python; coding: utf-8 -*-
|
||||
# Copyright (C) 2020 Laboratoire de Recherche et Développement de l'Epita
|
||||
# (LRDE).
|
||||
#
|
||||
# This file is part of Spot, a model checking library.
|
||||
#
|
||||
# Spot is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
# License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import spot
|
||||
|
||||
formulas = """\
|
||||
{x[*]}[]-> F({y[*]}<>-> GFz)
|
||||
<>(({{p12}[*0..3]}[]-> ((p9) || (!(p17)))) V ((true) U (p17)))
|
||||
{{true} || {[*0]}}[]-> (false)
|
||||
{{p14} & {{p0}[*]}}[]-> (p11)
|
||||
{{{!{p6}} -> {!{p3}}}[*]}[]-> ((p3)V((p3) || ((X((false))) && ((p2)V(p18)))))
|
||||
"""
|
||||
|
||||
for f1 in formulas.splitlines():
|
||||
f1 = spot.formula(f1)
|
||||
a1 = spot.translate(f1)
|
||||
|
||||
f2, aps = spot.suffix_operator_normal_form(f1, 'sonf_')
|
||||
a2 = spot.translate(f2)
|
||||
rm = spot.remove_ap()
|
||||
for ap in aps:
|
||||
rm.add_ap(ap)
|
||||
a2 = rm.strip(a2)
|
||||
|
||||
assert(spot.are_equivalent(a1, a2))
|
||||
Loading…
Add table
Add a link
Reference in a new issue