org: simplify babel blocks using #+PROPERTY: header-args

This feature is in Org 9, which is already required.

* doc/org/autcross.org, doc/org/autfilt.org, doc/org/compile.org,
doc/org/concepts.org, doc/org/csv.org, doc/org/dstar2tgba.org,
doc/org/genaut.org, doc/org/genltl.org, doc/org/hierarchy.org,
doc/org/hoa.org, doc/org/ioltl.org, doc/org/ltl2tgba.org,
doc/org/ltl2tgta.org, doc/org/ltlcross.org, doc/org/ltldo.org,
doc/org/ltlfilt.org, doc/org/ltlgrind.org, doc/org/ltlsynt.org,
doc/org/oaut.org, doc/org/randaut.org, doc/org/randltl.org,
doc/org/satmin.org, doc/org/setup.org, doc/org/tools.org,
doc/org/tut01.org, doc/org/tut02.org, doc/org/tut03.org,
doc/org/tut04.org, doc/org/tut10.org, doc/org/tut11.org,
doc/org/tut12.org, doc/org/tut20.org, doc/org/tut21.org,
doc/org/tut22.org, doc/org/tut23.org, doc/org/tut24.org,
doc/org/tut30.org, doc/org/tut31.org, doc/org/tut50.org,
doc/org/upgrade2.org: Simplify SRC block setups for sh, python and
C++.  Also fix a few typos and examples along the way.
This commit is contained in:
Alexandre Duret-Lutz 2019-04-16 21:03:13 +02:00
parent 0c8e6a38a8
commit 8a96828d85
40 changed files with 2193 additions and 2281 deletions

View file

@ -3,6 +3,7 @@
#+DESCRIPTION: Spot command-line tool for cross-comparing the output of automaton processors.
#+INCLUDE: setup.org
#+HTML_LINK_UP: tools.html
#+PROPERTY: header-args:sh :results verbatim :exports both
=autcross= is a tool for cross-comparing the output of tools that
transform automata. It works similarly to [[file:ltlcross.org][=ltlcross=]] except that
@ -33,7 +34,7 @@ and will appear in the CSV file if such a file is output.
Each tool should be specified as a string that uses some of the
following character sequences:
#+BEGIN_SRC sh :results verbatim :exports results
#+BEGIN_SRC sh :exports results
autcross --help | sed -n '/character sequences:/,/^$/p' | sed '1d;$d'
#+END_SRC
#+RESULTS:
@ -55,31 +56,26 @@ Another tool that can complement automata is =ltl2dstar=, using
the syntax =ltl2dstar -B --complement-input=yes %H %O=. So to
compare the results of these two tools we could use:
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :prologue "exec 2>&1"
randaut -B -n 3 a b |
autcross 'autfilt --complement %H >%O' 'ltl2dstar --complement-input=yes -B %H %O'
#+END_SRC
#+BEGIN_SRC sh :results verbatim :exports output
randaut -B -n 3 a b |
autcross 'autfilt --complement %H >%O' 'ltl2dstar --complement-input=yes -B %H %O' 2>&1
#+END_SRC
#+RESULTS:
#+begin_example
-:1.1-45.7
Running [A0]: autfilt --complement 'lcr-i0-Nr1xZO' >'lcr-o0-urHakt'
Running [A1]: ltl2dstar -B --complement-input=yes 'lcr-i0-mmkgH7' 'lcr-o1-ABdm4L'
Running [A0]: autfilt --complement 'lcr-i0-lOYLT5' >'lcr-o0-HB5WGO'
Running [A1]: ltl2dstar --complement-input=yes -B 'lcr-i0-UIX3wx' 'lcr-o1-f8abng'
Performing sanity checks and gathering statistics...
-:46.1-92.7
Running [A0]: autfilt --complement 'lcr-i1-5kMYrq' >'lcr-o0-9kvBP4'
Running [A1]: ltl2dstar -B --complement-input=yes 'lcr-i1-lVlGfJ' 'lcr-o1-BexLFn'
Running [A0]: autfilt --complement 'lcr-i1-Eq2WdZ' >'lcr-o0-CvfJ4H'
Running [A1]: ltl2dstar --complement-input=yes -B 'lcr-i1-736tYq' 'lcr-o1-YvkfS9'
Performing sanity checks and gathering statistics...
-:93.1-137.7
Running [A0]: autfilt --complement 'lcr-i2-rjvy61' >'lcr-o0-rKKlxG'
Running [A1]: ltl2dstar -B --complement-input=yes 'lcr-i2-Musr0k' 'lcr-o1-LyAxtZ'
Running [A0]: autfilt --complement 'lcr-i2-6ahOMS' >'lcr-o0-HdynHB'
Running [A1]: ltl2dstar --complement-input=yes -B 'lcr-i2-9PcREk' 'lcr-o1-XcblC3'
Performing sanity checks and gathering statistics...
No problem detected.
@ -87,12 +83,12 @@ No problem detected.
In this example, we generate 3 random Büchi automata (because
=ltl2dstar= expects Büchi automata as input) using [[file:randaut.org][=randaut=]], and pipe
them to =autcross=. For each of those automata, =autcross= display
them to =autcross=. For each of those automata, =autcross= displays
the source location of that automaton (here =-= indicates that the
automaton is read from standard input, and this is followed by
=beginline.column-endline.colum= specifying the position of that
automaton in the input. If the automata had names, they would
be displayed as well.
automaton in the input. If the automata had names, they would be
displayed as well.
Then, each tool is called using temporary files to exchange the
automata, and the resulting automata are then compared. The last line
@ -103,7 +99,7 @@ To simplify the use of some known tools, a set of predefined
shorthands are available. Those can be listed with the
=--list-shorthands= option.
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
autcross --list-shorthands
#+END_SRC
#+RESULTS:
@ -112,9 +108,11 @@ If a COMMANDFMT does not use any %-sequence, and starts with one of
the following words, then the string on the right is appended.
autfilt %H>%O
seminator %H>%O
dstar2tgba %H>%O
ltl2dstar -B %H %O
nba2dpa <%H>%O
nba2ldpa <%H>%O
seminator %H>%O
Any {name} and directory component is skipped for the purpose of
matching those prefixes. So for instance
@ -125,7 +123,7 @@ will be changed into
What this implies is our previous example could be shortened to:
#+BEGIN_SRC sh :results silent :exports code
#+BEGIN_SRC sh :exports code
randaut -B -n 3 a b |
autcross 'autfilt --complement' 'ltl2dstar --complement-input=yes'
#+END_SRC
@ -146,31 +144,26 @@ Second, we pass a =--csv= option to =autcross= to save statistics in a
file.
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :prologue "exec 2>&1"
randaut -B -n 3 a b --name="automaton %L" |
autcross 'autfilt --complement' 'ltl2dstar --complement-input=yes' --csv=autcross.csv
#+END_SRC
#+BEGIN_SRC sh :results verbatim :exports results
randaut -B -n 3 a b --name="automaton %L" |
autcross 'autfilt --complement' 'ltl2dstar --complement-input=yes' --csv=autcross.csv 2>&1
#+END_SRC
#+RESULTS:
#+begin_example
-:1.1-46.7 automaton 0
Running [A0]: autfilt --complement 'lcr-i0-QHReWu'>'lcr-o0-0eTOmZ'
Running [A1]: ltl2dstar --complement-input=yes -B 'lcr-i0-jsoPPt' 'lcr-o1-66bQiY'
Running [A0]: autfilt --complement 'lcr-i0-YPfmR5'>'lcr-o0-Z1bT0A'
Running [A1]: ltl2dstar --complement-input=yes -B 'lcr-i0-DpL2i6' 'lcr-o1-gpYcBB'
Performing sanity checks and gathering statistics...
-:47.1-94.7 automaton 1
Running [A0]: autfilt --complement 'lcr-i1-IubpMs'>'lcr-o0-dfmYfX'
Running [A1]: ltl2dstar --complement-input=yes -B 'lcr-i1-13NXLr' 'lcr-o1-zSwXhW'
Running [A0]: autfilt --complement 'lcr-i1-mxsGU6'>'lcr-o0-fPCaeC'
Running [A1]: ltl2dstar --complement-input=yes -B 'lcr-i1-2hgYD7' 'lcr-o1-S4xM3C'
Performing sanity checks and gathering statistics...
-:95.1-140.7 automaton 2
Running [A0]: autfilt --complement 'lcr-i2-g5bDOq'>'lcr-o0-X71ilV'
Running [A1]: ltl2dstar --complement-input=yes -B 'lcr-i2-og1mUp' 'lcr-o1-QVurtU'
Running [A0]: autfilt --complement 'lcr-i2-YU1Qu8'>'lcr-o0-hwVVVD'
Running [A1]: ltl2dstar --complement-input=yes -B 'lcr-i2-MLmVq9' 'lcr-o1-edfVVE'
Performing sanity checks and gathering statistics...
No problem detected.
@ -178,17 +171,27 @@ No problem detected.
After this execution, the file =autcross.csv= contains the following:
#+BEGIN_SRC sh :results verbatim :exports results
cat autcross.csv
#+BEGIN_SRC sh :results output raw :exports results
sed 's/"//g
1a\
|-|
s/--/@@html:--@@/g
s/^/| /
s/$/ |/
s/,/|/g
' autcross.csv
#+END_SRC
#+ATTR_HTML: :class csv-table
#+RESULTS:
: "input.source","input.name","input.ap","input.states","input.edges","input.transitions","input.acc_sets","input.scc","input.nondetstates","input.nondeterministic","input.alternating","tool","exit_status","exit_code","time","output.ap","output.states","output.edges","output.transitions","output.acc_sets","output.scc","output.nondetstates","output.nondeterministic","output.alternating"
: "-:1.1-46.7","automaton 0",2,10,26,26,1,1,6,0,0,"autfilt --complement","ok",0,0.0129685,2,27,95,108,3,2,0,0,0
: "-:1.1-46.7","automaton 0",2,10,26,26,1,1,6,0,0,"ltl2dstar --complement-input=yes","ok",0,0.00202496,2,34,121,136,6,2,0,9,0
: "-:47.1-94.7","automaton 1",2,10,28,28,1,1,4,0,0,"autfilt --complement","ok",0,0.0128458,2,58,216,232,3,2,0,9,0
: "-:47.1-94.7","automaton 1",2,10,28,28,1,1,4,0,0,"ltl2dstar --complement-input=yes","ok",0,0.0026184,2,74,268,296,6,2,0,8,0
: "-:95.1-140.7","automaton 2",2,10,26,26,1,2,6,0,0,"autfilt --complement","ok",0,0.0127144,2,21,69,84,2,4,0,20,0
: "-:95.1-140.7","automaton 2",2,10,26,26,1,2,6,0,0,"ltl2dstar --complement-input=yes","ok",0,0.00180888,2,24,74,96,2,4,0,35,0
| input.source | input.name | input.ap | input.states | input.edges | input.transitions | input.acc_sets | input.scc | input.nondetstates | input.nondeterministic | input.alternating | tool | exit_status | exit_code | time | output.ap | output.states | output.edges | output.transitions | output.acc_sets | output.scc | output.nondetstates | output.nondeterministic | output.alternating |
|--------------+-------------+----------+--------------+-------------+-------------------+----------------+-----------+--------------------+------------------------+-------------------+-------------------------------------------+-------------+-----------+------------+-----------+---------------+--------------+--------------------+-----------------+------------+---------------------+-------------------------+--------------------|
| -:1.1-46.7 | automaton 0 | 2 | 10 | 26 | 26 | 1 | 1 | 6 | 1 | 0 | autfilt @@html:--@@complement | ok | 0 | 0.0217727 | 2 | 26 | 91 | 104 | 5 | 2 | 0 | 0 | 0 |
| -:1.1-46.7 | automaton 0 | 2 | 10 | 26 | 26 | 1 | 1 | 6 | 1 | 0 | ltl2dstar @@html:--@@complement-input=yes | ok | 0 | 0.00293471 | 2 | 34 | 121 | 136 | 6 | 2 | 0 | 0 | 0 |
| -:47.1-94.7 | automaton 1 | 2 | 10 | 28 | 28 | 1 | 1 | 4 | 1 | 0 | autfilt @@html:--@@complement | ok | 0 | 0.0212838 | 2 | 54 | 197 | 216 | 3 | 2 | 0 | 0 | 0 |
| -:47.1-94.7 | automaton 1 | 2 | 10 | 28 | 28 | 1 | 1 | 4 | 1 | 0 | ltl2dstar @@html:--@@complement-input=yes | ok | 0 | 0.00403921 | 2 | 74 | 268 | 296 | 6 | 2 | 0 | 0 | 0 |
| -:95.1-140.7 | automaton 2 | 2 | 10 | 26 | 26 | 1 | 2 | 6 | 1 | 0 | autfilt @@html:--@@complement | ok | 0 | 0.0205316 | 2 | 21 | 66 | 84 | 2 | 4 | 0 | 0 | 0 |
| -:95.1-140.7 | automaton 2 | 2 | 10 | 26 | 26 | 1 | 2 | 6 | 1 | 0 | ltl2dstar @@html:--@@complement-input=yes | ok | 0 | 0.00263697 | 2 | 24 | 74 | 96 | 2 | 4 | 0 | 0 | 0 |
This file can then be loaded in any spreadsheet or statistical application.
@ -213,21 +216,37 @@ tools are the command specified on the command line. Like with
=ltlcross=, this can be adjusted by using a command specification of
the form ={short name}actual command=.
For instance
#+BEGIN_SRC sh :results verbatim :exports both
For instance:
#+NAME: autcross2
#+BEGIN_SRC sh :exports code
randaut -B -n 3 a b --name="automaton %L" |
autcross '{AF}autfilt --complement' '{L2D}ltl2dstar --complement-input=yes' --csv
#+END_SRC
#+BEGIN_SRC sh :results output raw :exports results :noweb yes
sed 's/"//g
s/--/@@html:--@@/g
s/^/| /
s/$/ |/
s/,/|/g
$d
1a\
|-|
' <<EOF
<<autcross2()>>
EOF
#+END_SRC
#+ATTR_HTML: :class csv-table
#+RESULTS:
: "input.source","input.name","input.ap","input.states","input.edges","input.transitions","input.acc_sets","input.scc","input.nondetstates","input.nondeterministic","input.alternating","tool","exit_status","exit_code","time","output.ap","output.states","output.edges","output.transitions","output.acc_sets","output.scc","output.nondetstates","output.nondeterministic","output.alternating"
: "-:1.1-46.7","automaton 0",2,10,26,26,1,1,6,0,0,"AF","ok",0,0.039722,2,27,95,108,3,2,0,0,0
: "-:1.1-46.7","automaton 0",2,10,26,26,1,1,6,0,0,"L2D","ok",0,0.00640371,2,34,121,136,6,2,0,9,0
: "-:47.1-94.7","automaton 1",2,10,28,28,1,1,4,0,0,"AF","ok",0,0.0400776,2,58,216,232,3,2,0,9,0
: "-:47.1-94.7","automaton 1",2,10,28,28,1,1,4,0,0,"L2D","ok",0,0.00489558,2,74,268,296,6,2,0,20,0
: "-:95.1-140.7","automaton 2",2,10,26,26,1,2,6,0,0,"AF","ok",0,0.0220585,2,21,69,84,2,4,0,7,0
: "-:95.1-140.7","automaton 2",2,10,26,26,1,2,6,0,0,"L2D","ok",0,0.00329786,2,24,74,96,2,4,0,23,0
| input.source | input.name | input.ap | input.states | input.edges | input.transitions | input.acc_sets | input.scc | input.nondetstates | input.nondeterministic | input.alternating | tool | exit_status | exit_code | time | output.ap | output.states | output.edges | output.transitions | output.acc_sets | output.scc | output.nondetstates | output.nondeterministic | output.alternating |
|--------------+-------------+----------+--------------+-------------+-------------------+----------------+-----------+--------------------+------------------------+-------------------+------+-------------+-----------+------------+-----------+---------------+--------------+--------------------+-----------------+------------+---------------------+-------------------------+--------------------|
| -:1.1-46.7 | automaton 0 | 2 | 10 | 26 | 26 | 1 | 1 | 6 | 1 | 0 | AF | ok | 0 | 0.0239042 | 2 | 26 | 91 | 104 | 5 | 2 | 0 | 0 | 0 |
| -:1.1-46.7 | automaton 0 | 2 | 10 | 26 | 26 | 1 | 1 | 6 | 1 | 0 | L2D | ok | 0 | 0.00315407 | 2 | 34 | 121 | 136 | 6 | 2 | 0 | 0 | 0 |
| -:47.1-94.7 | automaton 1 | 2 | 10 | 28 | 28 | 1 | 1 | 4 | 1 | 0 | AF | ok | 0 | 0.0218867 | 2 | 54 | 197 | 216 | 3 | 2 | 0 | 0 | 0 |
| -:47.1-94.7 | automaton 1 | 2 | 10 | 28 | 28 | 1 | 1 | 4 | 1 | 0 | L2D | ok | 0 | 0.00413592 | 2 | 74 | 268 | 296 | 6 | 2 | 0 | 0 | 0 |
| -:95.1-140.7 | automaton 2 | 2 | 10 | 26 | 26 | 1 | 2 | 6 | 1 | 0 | AF | ok | 0 | 0.0211636 | 2 | 21 | 66 | 84 | 2 | 4 | 0 | 0 | 0 |
| -:95.1-140.7 | automaton 2 | 2 | 10 | 26 | 26 | 1 | 2 | 6 | 1 | 0 | L2D | ok | 0 | 0.0028508 | 2 | 24 | 74 | 96 | 2 | 4 | 0 | 0 | 0 |
* Language preserving transformation
@ -264,28 +283,23 @@ To simulate a problem, let's compare pretend we want verify that
=autfilt --complement= preserves the input language (clearly it does
not, since it actually complement the language of the automaton).
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :prologue "exec 2>&1" :epilogue true
randaut -B -n 3 a b --name="automaton %L" |
autcross --language-preserved 'autfilt --complement'
#+END_SRC
#+BEGIN_SRC sh :results verbatim :exports output
randaut -B -n 3 a b --name="automaton %L" |
autcross --language-preserved 'autfilt --complement' 2>&1
#+END_SRC
#+RESULTS:
#+begin_example
-:1.1-46.7 automaton 0
Running [A0]: autfilt --complement 'lcr-i0-3gRqrd'>'lcr-o0-ubUpHb'
Running [A0]: autfilt --complement 'lcr-i0-ttpQt9'>'lcr-o0-elszrt'
Performing sanity checks and gathering statistics...
error: A0*Comp(input) is nonempty; both automata accept the infinite word:
!a & !b; a & !b; cycle{!a & !b; a & !b; !a & b; !a & b; !a & !b; !a & b; !a & b; !a & !b}
cycle{!a & !b; a & !b}
error: input*Comp(A0) is nonempty; both automata accept the infinite word:
!a & !b; !a & !b; cycle{!a & !b; !a & b; a & b}
-:47.1-94.7 automaton 1
Running [A0]: autfilt --complement 'lcr-i1-JxFi09'>'lcr-o0-oQGbj8'
Running [A0]: autfilt --complement 'lcr-i1-rFJYtN'>'lcr-o0-66sow7'
Performing sanity checks and gathering statistics...
error: A0*Comp(input) is nonempty; both automata accept the infinite word:
!a & b; cycle{a & !b}
@ -293,10 +307,10 @@ error: input*Comp(A0) is nonempty; both automata accept the infinite word:
!a & b; a & !b; cycle{!a & b; a & b}
-:95.1-140.7 automaton 2
Running [A0]: autfilt --complement 'lcr-i2-SQT7E6'>'lcr-o0-kWt404'
Running [A0]: autfilt --complement 'lcr-i2-00isDr'>'lcr-o0-R6BwKL'
Performing sanity checks and gathering statistics...
error: A0*Comp(input) is nonempty; both automata accept the infinite word:
a & !b; !a & !b; cycle{a & !b; !a & b}
!a & b; cycle{!a & !b}
error: input*Comp(A0) is nonempty; both automata accept the infinite word:
cycle{!a & b; !a & b; !a & !b; a & !b; a & !b; !a & !b}
@ -349,29 +363,24 @@ makes sense if you only care about the output of =--csv=.
The verbose option can be useful to troubleshoot problems or simply
follow the list of transformations and tests performed by =autcross=.
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :prologue "exec 2>&1" :epilogue true
randaut -B -n 1 a b --name="automaton %L" |
autcross 'autfilt --complement' 'ltl2dstar --complement-input=yes' --verbose
#+END_SRC
#+BEGIN_SRC sh :results verbatim :exports results
randaut -B -n 1 a b --name="automaton %L" |
autcross 'autfilt --complement' 'ltl2dstar --complement-input=yes' --verbose 2>&1
#+END_SRC
#+RESULTS:
#+begin_example
-:1.1-46.7 automaton 0
info: input (10 st.,26 ed.,1 sets)
Running [A0]: autfilt --complement 'lcr-i0-oZm5P2'>'lcr-o0-O4P0IB'
Running [A1]: ltl2dstar --complement-input=yes -B 'lcr-i0-gEwlJa' 'lcr-o1-wSaHJJ'
Running [A0]: autfilt --complement 'lcr-i0-KHA9NI'>'lcr-o0-BSYDwC'
Running [A1]: ltl2dstar --complement-input=yes -B 'lcr-i0-DjL8hw' 'lcr-o1-PASD3p'
info: collected automata:
info: A0 (27 st.,95 ed.,3 sets) deterministic complete
info: A0 (26 st.,91 ed.,5 sets) deterministic complete
info: A1 (34 st.,121 ed.,6 sets) deterministic complete
Performing sanity checks and gathering statistics...
info: getting rid of any Fin acceptance...
info: A0 (27 st.,95 ed.,3 sets) -> (58 st.,203 ed.,2 sets)
info: Comp(A0) (27 st.,95 ed.,3 sets) -> (51 st.,188 ed.,1 sets)
info: A0 (26 st.,91 ed.,5 sets) -> (83 st.,287 ed.,2 sets)
info: Comp(A0) (26 st.,91 ed.,5 sets) -> (76 st.,281 ed.,3 sets)
info: A1 (34 st.,121 ed.,6 sets) -> (64 st.,228 ed.,3 sets)
info: Comp(A1) (34 st.,121 ed.,6 sets) -> (34 st.,121 ed.,1 sets)
info: check_empty A0*Comp(A1)
@ -380,14 +389,6 @@ info: check_empty A1*Comp(A0)
No problem detected.
#+end_example
# LocalWords: utf autcross SETUPFILE html HOA neverclaim dstar's Nr
# LocalWords: autfilt dstar randaut lcr xZO urHakt mmkgH ABdm kMYrq
# LocalWords: kvBP lVlGfJ BexLFn rjvy rKKlxG Musr LyAxtZ shorthands
# LocalWords: COMMANDFMT seminator nba ldpa QHReWu eTOmZ jsoPPt ilV
# LocalWords: bQiY IubpMs dfmYfX NXLr zSwXhW bDOq og mUp QVurtU ap
# LocalWords: ok complementation Ai Aj gRqrd ubUpHb JxFi oQGbj SQT
# LocalWords: kWt Eo Xsc WXgCB vLwKMQ tI SXF qqlE KXplk ZFTCz PNY
# LocalWords: hUAK IjnFhD cWys ZqjdQh
* Use-cases for =%M=
If the input automata are named, it is possible to use =%M= in some
@ -404,70 +405,60 @@ LTL formula encoded in the name of the automaton). That LTL formula
is not in a syntax supported by =ltl2dstar=, so we call =ltl2dstar=
via [[file:ltldo.org][=ltldo=]] to arrange that.
#+BEGIN_SRC sh :results silent :export code
#+BEGIN_SRC sh :prologue "exec 2>&1" :epilogue true
genltl --eh-patterns=1..3 | ltl2tgba |
autcross 'autfilt -P -D' 'ltldo ltl2dstar -f %M >%O'
#+END_SRC
#+BEGIN_SRC sh :results verbatim :export results
genltl --eh-patterns=1..3 | ltl2tgba |
autcross 'autfilt -P -D' 'ltldo ltl2dstar -f %M >%O' 2>&1
#+END_SRC
#+RESULTS:
#+begin_example
-:1.1-16.7 p0 U (p1 & Gp2)
Running [A0]: autfilt -P -D 'lcr-i0-rBSCo9'>'lcr-o0-xyRJhy'
Running [A1]: ltldo ltl2dstar -f 'p0 U (p1 & Gp2)' >'lcr-o1-9uDUjX'
Running [A0]: autfilt -P -D 'lcr-i0-VyvQVJ'>'lcr-o0-fVtUyh'
Running [A1]: ltldo ltl2dstar -f 'p0 U (p1 & Gp2)' >'lcr-o1-4e57fP'
Performing sanity checks and gathering statistics...
-:17.1-34.7 p0 U (p1 & X(p2 U p3))
Running [A0]: autfilt -P -D 'lcr-i1-LFDrvm'>'lcr-o0-6fBZGL'
Running [A1]: ltldo ltl2dstar -f 'p0 U (p1 & X(p2 U p3))' >'lcr-o1-AUXx0a'
Running [A0]: autfilt -P -D 'lcr-i1-cNgs1m'>'lcr-o0-MWSMMU'
Running [A1]: ltldo ltl2dstar -f 'p0 U (p1 & X(p2 U p3))' >'lcr-o1-2oVyBs'
Performing sanity checks and gathering statistics...
-:35.1-64.7 p0 U (p1 & X(p2 & F(p3 & XF(p4 & XF(p5 & XFp6)))))
Running [A0]: autfilt -P -D 'lcr-i2-UaZCtA'>'lcr-o0-hhbJWZ'
Running [A1]: ltldo ltl2dstar -f 'p0 U (p1 & X(p2 & F(p3 & XF(p4 & XF(p5 & XFp6)))))' >'lcr-o1-xhS4Ap'
Running [A0]: autfilt -P -D 'lcr-i2-Tgzsu0'>'lcr-o0-aOBmny'
Running [A1]: ltldo ltl2dstar -f 'p0 U (p1 & X(p2 & F(p3 & XF(p4 & XF(p5 & XFp6)))))' >'lcr-o1-Sg7al6'
Performing sanity checks and gathering statistics...
No problem detected.
#+end_example
This example is a bit contrived, and in this case, an alternative would
be to use [[file:ltlcross.org][=ltlcross=]], as in:
The previous example was a bit contrived, and in this case, a saner
alternative would be to use [[file:ltlcross.org][=ltlcross=]], as in:
#+BEGIN_SRC sh :results silent :export code
#+BEGIN_SRC sh :prologue "exec 2>&1" :epilogue true
genltl --eh-patterns=1..3 |
ltlcross 'ltl2tgba %f | autfilt -P -D > %O' 'ltl2dstar'
#+END_SRC
#+BEGIN_SRC sh :results verbatim :export results
genltl --eh-patterns=1..3 |
ltlcross 'ltl2tgba %f | autfilt -P -D > %O' 'ltl2dstar' 2>&1
#+END_SRC
#+RESULTS:
#+begin_example
-:1: (p0) U ((p1) & (G(p2)))
Running [P0]: ltl2tgba '(p0) U ((p1) & (G(p2)))' | autfilt -P -D > 'lcr-o0-DnV1rm'
Running [P1]: ltl2dstar --output-format=hoa 'lcr-i0-jBLulv' 'lcr-o1-epwYeE'
Running [N0]: ltl2tgba '!((p0) U ((p1) & (G(p2))))' | autfilt -P -D > 'lcr-o0-8bVQ9M'
Running [N1]: ltl2dstar --output-format=hoa 'lcr-i0-5oAAdW' 'lcr-o1-W7elh5'
Running [P0]: ltl2tgba '(p0) U ((p1) & (G(p2)))' | autfilt -P -D > 'lcr-o0-6iPt1N'
Running [P1]: ltl2dstar --output-format=hoa 'lcr-i0-iZ22aA' 'lcr-o1-xyBCkm'
Running [N0]: ltl2tgba '!((p0) U ((p1) & (G(p2))))' | autfilt -P -D > 'lcr-o0-UL2Ju8'
Running [N1]: ltl2dstar --output-format=hoa 'lcr-i0-FyS5HU' 'lcr-o1-Xy3rVG'
Performing sanity checks and gathering statistics...
-:2: (p0) U ((p1) & (X((p2) U (p3))))
Running [P0]: ltl2tgba '(p0) U ((p1) & (X((p2) U (p3))))' | autfilt -P -D > 'lcr-o0-xMdCve'
Running [P1]: ltl2dstar --output-format=hoa 'lcr-i1-OJU1Sn' 'lcr-o1-wOCsgx'
Running [N0]: ltl2tgba '!((p0) U ((p1) & (X((p2) U (p3)))))' | autfilt -P -D > 'lcr-o0-SzgmFG'
Running [N1]: ltl2dstar --output-format=hoa 'lcr-i1-8iIddQ' 'lcr-o1-zBV5KZ'
Running [P0]: ltl2tgba '(p0) U ((p1) & (X((p2) U (p3))))' | autfilt -P -D > 'lcr-o0-3veUbt'
Running [P1]: ltl2dstar --output-format=hoa 'lcr-i1-Rceyvf' 'lcr-o1-YXtcP1'
Running [N0]: ltl2tgba '!((p0) U ((p1) & (X((p2) U (p3)))))' | autfilt -P -D > 'lcr-o0-imCn9N'
Running [N1]: ltl2dstar --output-format=hoa 'lcr-i1-Q49LwA' 'lcr-o1-xF2aUm'
Performing sanity checks and gathering statistics...
-:3: (p0) U ((p1) & (X((p2) & (F((p3) & (X(F((p4) & (X(F((p5) & (X(F(p6))))))))))))))
Running [P0]: ltl2tgba '(p0) U ((p1) & (X((p2) & (F((p3) & (X(F((p4) & (X(F((p5) & (X(F(p6))))))))))))))' | autfilt -P -D > 'lcr-o0-FEA6s9'
Running [P1]: ltl2dstar --output-format=hoa 'lcr-i2-E0Ikpj' 'lcr-o1-ppDzlt'
Running [N0]: ltl2tgba '!((p0) U ((p1) & (X((p2) & (F((p3) & (X(F((p4) & (X(F((p5) & (X(F(p6)))))))))))))))' | autfilt -P -D > 'lcr-o0-jqlelD'
Running [N1]: ltl2dstar --output-format=hoa 'lcr-i2-IwU1uN' 'lcr-o1-6YdQEX'
Running [P0]: ltl2tgba '(p0) U ((p1) & (X((p2) & (F((p3) & (X(F((p4) & (X(F((p5) & (X(F(p6))))))))))))))' | autfilt -P -D > 'lcr-o0-xdVyk9'
Running [P1]: ltl2dstar --output-format=hoa 'lcr-i2-UpeRPV' 'lcr-o1-4GM9kI'
Running [N0]: ltl2tgba '!((p0) U ((p1) & (X((p2) & (F((p3) & (X(F((p4) & (X(F((p5) & (X(F(p6)))))))))))))))' | autfilt -P -D > 'lcr-o0-J9yARu'
Running [N1]: ltl2dstar --output-format=hoa 'lcr-i2-1IDzrh' 'lcr-o1-Ck5y13'
Performing sanity checks and gathering statistics...
No problem detected.
@ -476,3 +467,16 @@ No problem detected.
However in practice you could also use the =name:= field of the input
automaton, combined with =%M= in the tool specification, to designate
an alternate filename to load, or some key to look up somewhere.
#+BEGIN_SRC sh :results silent :exports results
rm -f autcross.csv
#+END_SRC
# LocalWords: utf autcross SETUPFILE html HOA neverclaim dstar's Nr
# LocalWords: autfilt dstar randaut lcr xZO urHakt mmkgH ABdm kMYrq
# LocalWords: kvBP lVlGfJ BexLFn rjvy rKKlxG Musr LyAxtZ shorthands
# LocalWords: COMMANDFMT seminator nba ldpa QHReWu eTOmZ jsoPPt ilV
# LocalWords: bQiY IubpMs dfmYfX NXLr zSwXhW bDOq og mUp QVurtU ap
# LocalWords: ok complementation Ai Aj gRqrd ubUpHb JxFi oQGbj SQT
# LocalWords: kWt Eo Xsc WXgCB vLwKMQ tI SXF qqlE KXplk ZFTCz PNY
# LocalWords: hUAK IjnFhD cWys ZqjdQh

View file

@ -3,6 +3,7 @@
#+DESCRIPTION: Spot command-line tool for filtering, tranforming, and converting ω-automata.
#+INCLUDE: setup.org
#+HTML_LINK_UP: tools.html
#+PROPERTY: header-args:sh :results verbatim :exports both
The =autfilt= tool can filter, transform, and convert a stream of automata.
@ -32,7 +33,7 @@ By default the output uses the HOA format. This can be changed using
[[file:oaut.org][the common output options]] like =--spin=, =--lbtt=, =--dot=,
=--stats=...
#+BEGIN_SRC sh :results silent :exports both
#+BEGIN_SRC sh :results silent
cat >example.hoa <<EOF
HOA: v1
States: 1
@ -48,7 +49,7 @@ EOF
autfilt example.hoa --dot
#+END_SRC
#+BEGIN_SRC sh :results verbatim :exports results
#+BEGIN_SRC sh :exports results
SPOT_DOTEXTRA= autfilt example.hoa --dot
#+END_SRC
@ -65,7 +66,7 @@ SPOT_DOTEXTRA= autfilt example.hoa --dot
The =--spin= option implicitly requires a degeneralization:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
autfilt example.hoa --spin
#+END_SRC
@ -87,7 +88,7 @@ T0_S2:
Option =--lbtt= only works for Büchi or generalized Büchi acceptance.
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
autfilt example.hoa --lbtt
#+END_SRC
@ -106,7 +107,7 @@ automata, and pipe the result into =autfilt= to display various
statistics.
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
randaut -n 10 -A0..2 -Q10..20 -e0.05 2 |
autfilt --stats='%s states, %e edges, %a acc-sets, %c SCCs, det=%d'
#+END_SRC
@ -126,7 +127,7 @@ autfilt --stats='%s states, %e edges, %a acc-sets, %c SCCs, det=%d'
#+end_example
The following =%= sequences are available:
#+BEGIN_SRC sh :results verbatim :exports results
#+BEGIN_SRC sh :exports results
ltl2tgba --help | sed -n '/ sequences:/,/^$/p' | sed '1d;$d'
#+END_SRC
#+RESULTS:
@ -171,6 +172,11 @@ ltl2tgba --help | sed -n '/ sequences:/,/^$/p' | sed '1d;$d'
processes.
%s number of reachable states
%t number of reachable transitions
%u, %[e]u number of states (or [e]dges) with universal
branching
%u, %[LETTER]u 1 if the automaton contains some universal
branching (or a number of [s]tates or [e]dges with
universal branching)
%w one word accepted by the output automaton
%x, %[LETTERS]x number of atomic propositions declared in the
automaton; add LETTERS to list atomic
@ -193,7 +199,7 @@ automaton.
=autfilt= offers multiple options to filter automata based on
different characteristics of the automaton.
#+BEGIN_SRC sh :results verbatim :exports results
#+BEGIN_SRC sh :exports results
autfilt --help | sed -n '/Filtering options.*:/,/^$/p' | sed '1d;$d'
#+END_SRC
#+RESULTS:
@ -204,13 +210,19 @@ autfilt --help | sed -n '/Filtering options.*:/,/^$/p' | sed '1d;$d'
--acc-sets=RANGE keep automata whose number of acceptance sets is
in RANGE
--accept-word=WORD keep automata that accept WORD
--acceptance-is=NAME|FORMULA
match automata with given accetance condition
--ap=RANGE match automata with a number of (declared) atomic
propositions in RANGE
--are-isomorphic=FILENAME keep automata that are isomorphic to the
automaton in FILENAME
--edges=RANGE keep automata whose number of edges is in RANGE
--equivalent-to=FILENAME keep automata thare are equivalent
--equivalent-to=FILENAME keep automata that are equivalent
(language-wise) to the automaton in FILENAME
--has-exist-branching keep automata that use existential branching
(i.e., make non-deterministic choices)
--has-univ-branching keep alternating automata that use universal
branching
--included-in=FILENAME keep automata whose languages are included in that
of the automaton from FILENAME
--inherently-weak-sccs=RANGE
@ -220,14 +232,19 @@ autfilt --help | sed -n '/Filtering options.*:/,/^$/p' | sed '1d;$d'
rejecting cycle.
--intersect=FILENAME keep automata whose languages have an non-empty
intersection with the automaton from FILENAME
--is-alternating keep only automata using universal branching
--is-colored keep colored automata (i.e., exactly one
acceptance mark per transition or state)
--is-complete keep complete automata
--is-deterministic keep deterministic automata
--is-empty keep automata with an empty language
--is-inherently-weak keep only inherently weak automata
--is-semi-deterministic keep semi-deterministic automata
--is-stutter-invariant keep automata representing stutter-invariant
properties
--is-terminal keep only terminal automata
--is-unambiguous keep only unambiguous automata
--is-very-weak keep only very-weak automata
--is-weak keep only weak automata
--nondet-states=RANGE keep automata whose number of nondeterministic
states is in RANGE
@ -264,6 +281,9 @@ that use 3 acceptance sets and that have between 2 and 5 states, and
keep the others.
* Simplifying automata
:PROPERTIES:
:header-args:sh: :results verbatim :exports results
:END:
The standard set of automata simplification routines (these are often
referred to as the "post-processing" routines, because these are the
@ -272,12 +292,15 @@ TGBA) are available through the following options.
This set of options controls the desired type of output automaton:
#+BEGIN_SRC sh :results verbatim :exports results
#+BEGIN_SRC sh
autfilt --help | sed -n '/Output automaton type:/,/^$/p' | sed '1d;$d'
#+END_SRC
#+RESULTS:
#+begin_example
-B, --ba Büchi Automaton (with state-based acceptance)
--cobuchi, --coBuchi automaton with co-Büchi acceptance (will
recognize a superset of the input language if not
co-Büchi realizable)
-C, --complete output a complete automaton
-G, --generic any acceptance is allowed (default)
-M, --monitor Monitor (accepts all finite prefixes of the given
@ -293,19 +316,21 @@ autfilt --help | sed -n '/Output automaton type:/,/^$/p' | sed '1d;$d'
These options specify any simplification goal:
#+BEGIN_SRC sh :results verbatim :exports results
#+BEGIN_SRC sh
autfilt --help | sed -n '/Simplification goal:/,/^$/p' | sed '1d;$d'
#+END_SRC
#+RESULTS:
: -a, --any no preference, do not bother making it small or
: deterministic
: -D, --deterministic prefer deterministic automata
: -D, --deterministic prefer deterministic automata (combine with
: --generic to be sure to obtain a deterministic
: automaton)
: --small prefer small automata
Finally, the following switches control the amount of effort applied
toward the desired goal:
#+BEGIN_SRC sh :results verbatim :exports results
#+BEGIN_SRC sh
autfilt --help | sed -n '/Simplification level:/,/^$/p' | sed '1d;$d'
#+END_SRC
#+RESULTS:
@ -374,7 +399,7 @@ set.
The following transformations are available:
#+BEGIN_SRC sh :results verbatim :exports results
#+BEGIN_SRC sh :exports results
autfilt --help | sed -n '/Transformations:/,/^$/p' | sed '1d;$d'
#+END_SRC
@ -383,16 +408,20 @@ autfilt --help | sed -n '/Transformations:/,/^$/p' | sed '1d;$d'
--cleanup-acceptance remove unused acceptance sets from the automaton
--cnf-acceptance put the acceptance condition in Conjunctive Normal
Form
--complement complement each automaton (currently support only
deterministic automata)
--complement complement each automaton (different strategies
are used)
--complement-acceptance complement the acceptance condition (without
touching the automaton)
--decompose-strength=t|w|s extract the (t) terminal, (w) weak, or (s)
strong part of an automaton (letters may be
combined to combine more strengths in the output)
--decompose-scc=t|w|s|N|aN, --decompose-strength=t|w|s|N|aN
extract the (t) terminal, (w) weak, or (s) strong
part of an automaton or (N) the subautomaton
leading to the Nth SCC, or (aN) to the Nth
accepting SCC (option can be combined with commas
to extract multiple parts)
--destut allow less stuttering
--dnf-acceptance put the acceptance condition in Disjunctive Normal
Form
--dualize dualize each automaton
--exclusive-ap=AP,AP,... if any of those APs occur in the automaton,
restrict all edges to ensure two of them may not
be true at the same time. Use this option
@ -429,24 +458,44 @@ autfilt --help | sed -n '/Transformations:/,/^$/p' | sed '1d;$d'
quantification, or by assigning them 0 or 1
--remove-dead-states remove states that are unreachable, or that cannot
belong to an infinite path
--remove-fin rewrite the automaton without using Fin
acceptance
--remove-fin rewrite the automaton without using Fin acceptance
--remove-unreachable-states
remove states that are unreachable from the
initial state
--remove-unused-ap remove declared atomic propositions that are not
used
--sat-minimize[=options] minimize the automaton using a SAT solver
(only works for deterministic automata)
(only works for deterministic automata). Supported
options are acc=STRING, states=N, max-states=N,
sat-incr=N, sat-incr-steps=N, sat-langmap,
sat-naive, colored, preproc=N. Spot uses by
default its PicoSAT distribution but an external
SATsolver can be set thanks to the SPOT_SATSOLVER
environment variable(see spot-x).
--separate-sets if both Inf(x) and Fin(x) appear in the acceptance
condition, replace Fin(x) by a new Fin(y) and
adjust the automaton
--simplify-acceptance simplify the acceptance condition by merging
identical acceptance sets and by simplifying some
terms containing complementary sets
--simplify-exclusive-ap if --exclusive-ap is used, assume those AP
groups are actually exclusive in the system to
simplify the expression of transition labels
(implies --merge-transitions)
--split-edges split edges into transitions labeled by
conjunctions of all atomic propositions, so they
can be read as letters
--streett-like convert to an automaton with Streett-like
acceptance. Works only with acceptance condition
in DNF
--strip-acceptance remove the acceptance condition and all acceptance
sets
--sum=FILENAME, --sum-or=FILENAME
build the sum with the automaton in FILENAME to
sum languages
--sum-and=FILENAME build the sum with the automaton in FILENAME to
intersect languages
#+end_example
* Decorations
@ -455,19 +504,25 @@ Decorations work by coloring some states or edges in the automaton.
They are only useful when the automaton is output in Dot format (with
=--dot= or =-d=) or HOA v1.1 format (with =-H1.1= or =--hoa=1.1=).
#+BEGIN_SRC sh :results verbatim :exports results
#+BEGIN_SRC sh :exports results
autfilt --help | sed -n '/^ *Decorations.*:/,/^$/p' | sed '1d;$d'
#+END_SRC
#+RESULTS:
: --highlight-nondet[=NUM] highlight nondeterministic states and edges
: with color NUM
: --highlight-nondet-edges[=NUM]
: highlight nondeterministic edges with color NUM
: --highlight-nondet-states[=NUM]
: highlight nondeterministic states with color NUM
: --highlight-word=[NUM,]WORD
: highlight one run matching WORD using color NUM
#+begin_example
--highlight-accepting-run[=NUM]
highlight one accepting run using color NUM
--highlight-languages highlight states that recognize identical
languages
--highlight-nondet[=NUM] highlight nondeterministic states and edges
with color NUM
--highlight-nondet-edges[=NUM]
highlight nondeterministic edges with color NUM
--highlight-nondet-states[=NUM]
highlight nondeterministic states with color NUM
--highlight-word=[NUM,]WORD
highlight one run matching WORD using color NUM
#+end_example
Color numbers are indices in some hard-coded color palette. It is the
same palette that is currently used to display colored acceptance
@ -476,10 +531,13 @@ sets, but this might change in the future.
* Examples
** Acceptance transformations
:PROPERTIES:
:header-args:sh: :results verbatim :exports code
:END:
Here is an automaton with transition-based acceptance:
#+BEGIN_SRC sh :results silent :exports both
#+BEGIN_SRC sh :results silent
cat >aut-ex1.hoa<<EOF
HOA: v1
States: 3
@ -507,99 +565,24 @@ EOF
discussed [[file:oaut.org::#default-dot][on another page]].)
#+NAME: autfilt-ex1
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh
autfilt aut-ex1.hoa --dot
#+END_SRC
#+RESULTS: autfilt-ex1
#+begin_example
digraph G {
rankdir=LR
label=<(Fin(<font color="#F17CB0">❶</font>) &amp; Fin(<font color="#B276B2">❸</font>) &amp; Inf(<font color="#5DA5DA">⓿</font>)) | (Inf(<font color="#FAA43A">❷</font>)&amp;Inf(<font color="#B276B2">❸</font>)) | Inf(<font color="#F17CB0">❶</font>)>
labelloc="t"
fontname="Lato"
node [fontname="Lato"]
edge [fontname="Lato"]
node[style=filled, fillcolor="#ffffa0"] edge[arrowhead=vee, arrowsize=.7]
I [label="", style=invis, width=0]
I -> 0
0 [label="0"]
0 -> 0 [label=<1<br/><font color="#B276B2">❸</font>>]
0 -> 1 [label=<a<br/><font color="#F17CB0">❶</font><font color="#B276B2">❸</font>>]
0 -> 2 [label=<!a<br/><font color="#5DA5DA">⓿</font><font color="#B276B2">❸</font>>]
1 [label="1"]
1 -> 0 [label=<b<br/><font color="#B276B2">❸</font>>]
1 -> 1 [label=<a &amp; b<br/><font color="#5DA5DA">⓿</font><font color="#B276B2">❸</font>>]
1 -> 2 [label=<!a &amp; b<br/><font color="#FAA43A">❷</font><font color="#B276B2">❸</font>>]
2 [label="2"]
2 -> 0 [label=<!b>]
2 -> 1 [label=<a &amp; !b<br/><font color="#5DA5DA">⓿</font>>]
2 -> 2 [label=<!a &amp; !b<br/><font color="#5DA5DA">⓿</font>>]
}
#+end_example
#+BEGIN_SRC dot :file autfilt-ex1.svg :var txt=autfilt-ex1 :exports results
$txt
#+END_SRC
#+RESULTS:
[[file:autfilt-ex1.svgz]]
[[file:autfilt-ex1.svg]]
Using =-S= will "push" the acceptance membership of the transitions to the states:
#+NAME: autfilt-ex2
#+BEGIN_SRC sh :results verbatim :exports code
autfilt -S aut-ex1.hoa --dot=
#+BEGIN_SRC sh
autfilt -S aut-ex1.hoa --dot
#+END_SRC
#+RESULTS: autfilt-ex2
#+begin_example
digraph G {
rankdir=LR
label=<(Fin(<font color="#F17CB0">❶</font>) &amp; Fin(<font color="#B276B2">❸</font>) &amp; Inf(<font color="#5DA5DA">⓿</font>)) | (Inf(<font color="#FAA43A">❷</font>)&amp;Inf(<font color="#B276B2">❸</font>)) | Inf(<font color="#F17CB0">❶</font>)>
labelloc="t"
node [shape="circle"]
fontname="Lato"
node [fontname="Lato"]
edge [fontname="Lato"]
node[style=filled, fillcolor="#ffffa0"] edge[arrowhead=vee, arrowsize=.7]
I [label="", style=invis, width=0]
I -> 0
0 [label=<0<br/><font color="#B276B2">❸</font>>]
0 -> 0 [label=<1>]
0 -> 1 [label=<a>]
0 -> 2 [label=<!a>]
1 [label=<1<br/><font color="#F17CB0">❶</font><font color="#B276B2">❸</font>>]
1 -> 0 [label=<b>]
1 -> 6 [label=<a &amp; b>]
1 -> 7 [label=<!a &amp; b>]
2 [label=<2<br/><font color="#5DA5DA">⓿</font><font color="#B276B2">❸</font>>]
2 -> 3 [label=<!b>]
2 -> 4 [label=<a &amp; !b>]
2 -> 5 [label=<!a &amp; !b>]
3 [label=<3>]
3 -> 0 [label=<1>]
3 -> 1 [label=<a>]
3 -> 2 [label=<!a>]
4 [label=<4<br/><font color="#5DA5DA">⓿</font>>]
4 -> 0 [label=<b>]
4 -> 6 [label=<a &amp; b>]
4 -> 7 [label=<!a &amp; b>]
5 [label=<5<br/><font color="#5DA5DA">⓿</font>>]
5 -> 3 [label=<!b>]
5 -> 4 [label=<a &amp; !b>]
5 -> 5 [label=<!a &amp; !b>]
6 [label=<6<br/><font color="#5DA5DA">⓿</font><font color="#B276B2">❸</font>>]
6 -> 0 [label=<b>]
6 -> 6 [label=<a &amp; b>]
6 -> 7 [label=<!a &amp; b>]
7 [label=<7<br/><font color="#FAA43A">❷</font><font color="#B276B2">❸</font>>]
7 -> 3 [label=<!b>]
7 -> 4 [label=<a &amp; !b>]
7 -> 5 [label=<!a &amp; !b>]
}
#+end_example
#+BEGIN_SRC dot :file autfilt-ex2.svg :var txt=autfilt-ex2 :exports results
$txt
#+END_SRC
@ -610,37 +593,10 @@ $txt
Using =--cnf-acceptance= simply rewrites the acceptance condition in Conjunctive Normal Form:
#+NAME: autfilt-ex3
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh
autfilt --cnf-acceptance aut-ex1.hoa --dot
#+END_SRC
#+RESULTS: autfilt-ex3
#+begin_example
digraph G {
rankdir=LR
label=<(Inf(<font color="#5DA5DA">⓿</font>) | Inf(<font color="#F17CB0">❶</font>) | Inf(<font color="#B276B2">❸</font>)) &amp; (Fin(<font color="#B276B2">❸</font>) | Inf(<font color="#F17CB0">❶</font>) | Inf(<font color="#FAA43A">❷</font>))>
labelloc="t"
fontname="Lato"
node [fontname="Lato"]
edge [fontname="Lato"]
node[style=filled, fillcolor="#ffffa0"] edge[arrowhead=vee, arrowsize=.7]
I [label="", style=invis, width=0]
I -> 0
0 [label="0"]
0 -> 0 [label=<1<br/><font color="#B276B2">❸</font>>]
0 -> 1 [label=<a<br/><font color="#F17CB0">❶</font><font color="#B276B2">❸</font>>]
0 -> 2 [label=<!a<br/><font color="#5DA5DA">⓿</font><font color="#B276B2">❸</font>>]
1 [label="1"]
1 -> 0 [label=<b<br/><font color="#B276B2">❸</font>>]
1 -> 1 [label=<a &amp; b<br/><font color="#5DA5DA">⓿</font><font color="#B276B2">❸</font>>]
1 -> 2 [label=<!a &amp; b<br/><font color="#FAA43A">❷</font><font color="#B276B2">❸</font>>]
2 [label="2"]
2 -> 0 [label=<!b>]
2 -> 1 [label=<a &amp; !b<br/><font color="#5DA5DA">⓿</font>>]
2 -> 2 [label=<!a &amp; !b<br/><font color="#5DA5DA">⓿</font>>]
}
#+end_example
#+BEGIN_SRC dot :file autfilt-ex3.svg :var txt=autfilt-ex3 :exports results
$txt
#+END_SRC
@ -654,40 +610,10 @@ of Fin-acceptance: this usually requires adding non-deterministic jumps to
altered copies of strongly-connected components.
#+NAME: autfilt-ex4
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh
autfilt --remove-fin aut-ex1.hoa --dot
#+END_SRC
#+RESULTS: autfilt-ex4
#+begin_example
digraph G {
rankdir=LR
label=<Inf(<font color="#5DA5DA">⓿</font>) | Inf(<font color="#F17CB0">❶</font>) | (Inf(<font color="#FAA43A">❷</font>)&amp;Inf(<font color="#B276B2">❸</font>))>
labelloc="t"
fontname="Lato"
node [fontname="Lato"]
edge [fontname="Lato"]
node[style=filled, fillcolor="#ffffa0"] edge[arrowhead=vee, arrowsize=.7]
I [label="", style=invis, width=0]
I -> 0
0 [label="0"]
0 -> 0 [label=<1<br/><font color="#B276B2">❸</font>>]
0 -> 1 [label=<a<br/><font color="#F17CB0">❶</font><font color="#B276B2">❸</font>>]
0 -> 2 [label=<!a<br/><font color="#B276B2">❸</font>>]
1 [label="1"]
1 -> 0 [label=<b<br/><font color="#B276B2">❸</font>>]
1 -> 1 [label=<a &amp; b<br/><font color="#B276B2">❸</font>>]
1 -> 2 [label=<!a &amp; b<br/><font color="#FAA43A">❷</font><font color="#B276B2">❸</font>>]
2 [label="2"]
2 -> 0 [label=<!b>]
2 -> 1 [label=<a &amp; !b>]
2 -> 2 [label=<!a &amp; !b>]
2 -> 3 [label=<!a &amp; !b>]
3 [label="3"]
3 -> 3 [label=<!a &amp; !b<br/><font color="#5DA5DA">⓿</font>>]
}
#+end_example
#+BEGIN_SRC dot :file autfilt-ex4.svg :var txt=autfilt-ex4 :exports results
$txt
#+END_SRC
@ -700,35 +626,10 @@ transitions they contain. The acceptance condition will be updated to
reflect the fact that these sets can never be visited.
#+NAME: autfilt-ex5
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh
autfilt --mask-acc=1,2 aut-ex1.hoa --dot
#+END_SRC
#+RESULTS: autfilt-ex5
#+begin_example
digraph G {
rankdir=LR
label=<Fin(<font color="#F17CB0">❶</font>) &amp; Inf(<font color="#5DA5DA">⓿</font>)>
labelloc="t"
fontname="Lato"
node [fontname="Lato"]
edge [fontname="Lato"]
node[style=filled, fillcolor="#ffffa0"] edge[arrowhead=vee, arrowsize=.7]
I [label="", style=invis, width=0]
I -> 0
0 [label="0"]
0 -> 0 [label=<1<br/><font color="#F17CB0">❶</font>>]
0 -> 1 [label=<!a<br/><font color="#5DA5DA">⓿</font><font color="#F17CB0">❶</font>>]
1 [label="1"]
1 -> 0 [label=<!b>]
1 -> 2 [label=<a &amp; !b<br/><font color="#5DA5DA">⓿</font>>]
1 -> 1 [label=<!a &amp; !b<br/><font color="#5DA5DA">⓿</font>>]
2 [label="2"]
2 -> 0 [label=<b<br/><font color="#F17CB0">❶</font>>]
2 -> 2 [label=<a &amp; b<br/><font color="#5DA5DA">⓿</font><font color="#F17CB0">❶</font>>]
}
#+end_example
#+BEGIN_SRC dot :file autfilt-ex5.svg :var txt=autfilt-ex5 :exports results
$txt
#+END_SRC
@ -737,6 +638,9 @@ $txt
[[file:autfilt-ex5.svg]]
** Atomic proposition removal
:PROPERTIES:
:header-args:sh: :results verbatim :exports code
:END:
Atomic propositions can be removed from an automaton in three ways:
- use ~--remove-ap=a~ to remove =a= by existential quantification, i.e., both =a= and its negation will be replaced by true.
@ -747,37 +651,10 @@ Atomic propositions can be removed from an automaton in three ways:
Here are the results of these three options on our example:
#+NAME: autfilt-ex6a
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh
autfilt --remove-ap=a aut-ex1.hoa --dot
#+END_SRC
#+RESULTS: autfilt-ex6a
#+begin_example
digraph G {
rankdir=LR
label=<(Fin(<font color="#F17CB0">❶</font>) &amp; Fin(<font color="#B276B2">❸</font>) &amp; Inf(<font color="#5DA5DA">⓿</font>)) | (Inf(<font color="#FAA43A">❷</font>)&amp;Inf(<font color="#B276B2">❸</font>)) | Inf(<font color="#F17CB0">❶</font>)>
labelloc="t"
fontname="Lato"
node [fontname="Lato"]
edge [fontname="Lato"]
node[style=filled, fillcolor="#ffffa0"] edge[arrowhead=vee, arrowsize=.7]
I [label="", style=invis, width=0]
I -> 0
0 [label="0"]
0 -> 0 [label=<1<br/><font color="#B276B2">❸</font>>]
0 -> 1 [label=<1<br/><font color="#F17CB0">❶</font><font color="#B276B2">❸</font>>]
0 -> 2 [label=<1<br/><font color="#5DA5DA">⓿</font><font color="#B276B2">❸</font>>]
1 [label="1"]
1 -> 0 [label=<b<br/><font color="#B276B2">❸</font>>]
1 -> 1 [label=<b<br/><font color="#5DA5DA">⓿</font><font color="#B276B2">❸</font>>]
1 -> 2 [label=<b<br/><font color="#FAA43A">❷</font><font color="#B276B2">❸</font>>]
2 [label="2"]
2 -> 0 [label=<!b>]
2 -> 1 [label=<!b<br/><font color="#5DA5DA">⓿</font>>]
2 -> 2 [label=<!b<br/><font color="#5DA5DA">⓿</font>>]
}
#+end_example
#+BEGIN_SRC dot :file autfilt-ex6a.svg :var txt=autfilt-ex6a :exports results
$txt
#+END_SRC
@ -786,31 +663,10 @@ $txt
[[file:autfilt-ex6a.svg]]
#+NAME: autfilt-ex6b
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh
autfilt --remove-ap=a=0 aut-ex1.hoa --dot
#+END_SRC
#+RESULTS: autfilt-ex6b
#+begin_example
digraph G {
rankdir=LR
label=<(Fin(<font color="#F17CB0">❶</font>) &amp; Fin(<font color="#B276B2">❸</font>) &amp; Inf(<font color="#5DA5DA">⓿</font>)) | (Inf(<font color="#FAA43A">❷</font>)&amp;Inf(<font color="#B276B2">❸</font>)) | Inf(<font color="#F17CB0">❶</font>)>
labelloc="t"
fontname="Lato"
node [fontname="Lato"]
edge [fontname="Lato"]
node[style=filled, fillcolor="#ffffa0"] edge[arrowhead=vee, arrowsize=.7]
I [label="", style=invis, width=0]
I -> 0
0 [label="0"]
0 -> 0 [label=<1<br/><font color="#B276B2">❸</font>>]
0 -> 1 [label=<1<br/><font color="#5DA5DA">⓿</font><font color="#B276B2">❸</font>>]
1 [label="1"]
1 -> 0 [label=<!b>]
1 -> 1 [label=<!b<br/><font color="#5DA5DA">⓿</font>>]
}
#+end_example
#+BEGIN_SRC dot :file autfilt-ex6b.svg :var txt=autfilt-ex6b :exports results
$txt
#+END_SRC
@ -819,12 +675,10 @@ $txt
[[file:autfilt-ex6b.svg]]
#+NAME: autfilt-ex6c
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh
autfilt --remove-ap=a=1 aut-ex1.hoa --dot
#+END_SRC
#+RESULTS: autfilt-ex6c
#+BEGIN_SRC dot :file autfilt-ex6c.svg :var txt=autfilt-ex6c :exports results
$txt
#+END_SRC
@ -833,11 +687,15 @@ $txt
[[file:autfilt-ex6c.svg]]
** Testing word acceptance
:PROPERTIES:
:header-args:sh: :results verbatim :exports both
:END:
The following example checks whether the formula ~a U b U c~ accepts
the word ~a&!b&!c; cycle{!a&!b&c}~.
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltl2tgba 'a U b U c' |
autfilt --accept-word 'a&!b&!c; cycle{!a&!b&c}' -q && echo "word accepted"
#+END_SRC
@ -851,7 +709,7 @@ words =a&!b;cycle{!a&!b}= and =!a&!b;cycle{a&b}= yet reject any word
of the form =cycle{b}=, and display the associated formula (which was
stored as the name of the automaton by =ltl2tgba=).
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
randltl -n -1 a b | ltlfilt --simplify --uniq | ltl2tgba |
autfilt --accept-word='a&!b;cycle{!a&!b}' --accept-word='!a&!b;cycle{a&b}' \
--reject-word='cycle{b}' --stats=%M -n 10
@ -881,7 +739,7 @@ in a pipeline and preserve the formula name in the HOA output. For
example Here is a list of 5 LTL formulas that =ltl2dstar= converts to
Rabin automata that have exactly 4 states:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
randltl -n -1 a b | ltlfilt --simplify --remove-wm |
ltldo ltl2dstar --name=%f | autfilt --states=4 --stats=%M -n 5
#+END_SRC
@ -895,7 +753,7 @@ randltl -n -1 a b | ltlfilt --simplify --remove-wm |
** Decorations
:PROPERTIES:
:CUSTOM_ID: decorations
:header-args:sh: :results verbatim :exports code
:END:
We know from a previous exemple that formula =a U b U c= accepts the
@ -903,7 +761,7 @@ word =b; cycle{c}=. We can actually highlight the corresponding
run in the automaton:
#+NAME: highlight-word
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh
ltl2tgba 'a U b U c' | autfilt --highlight-word='a&!b&!c; cycle{!a&!b&c}' -d
#+END_SRC
@ -945,7 +803,7 @@ transition may only have one color so late highlights will overwrite
previous ones.
#+NAME: highlight-word2
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh
ltl2tgba 'a U b U c' |
autfilt --highlight-word=5,'a&!b&!c; cycle{!a&!b&c}' \
--highlight-word=4,'!a&b&!c; cycle{!a&!b&c}' -d
@ -989,40 +847,11 @@ highlight states or edges where nondeterministic choices need to be
made.
#+NAME: highlight-nondet
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh
ltl2tgba 'F((b R a) W Gb)' |
autfilt --highlight-nondet-states=5 --highlight-nondet-edges=1 -d
#+END_SRC
#+RESULTS: highlight-nondet
#+begin_example
digraph G {
rankdir=LR
node [shape="circle"]
node [style="filled", fillcolor="#ffffa0"]
fontname="Lato"
node [fontname="Lato"]
edge [fontname="Lato"]
edge[arrowhead=vee, arrowsize=.7]
I [label="", style=invis, width=0]
I -> 1
0 [label="0"]
0 -> 0 [label=<b<br/><font color="#5DA5DA">⓿</font>>]
1 [label="1", style="bold,filled", color="#F15854"]
1 -> 0 [label=<!a &amp; b>, style=bold, color="#5DA5DA"]
1 -> 1 [label=<1>, style=bold, color="#5DA5DA"]
1 -> 2 [label=<a &amp; b>]
1 -> 3 [label=<a &amp; !b>]
2 [label="2"]
2 -> 0 [label=<!a &amp; b>]
2 -> 2 [label=<a &amp; b<br/><font color="#5DA5DA">⓿</font>>]
2 -> 3 [label=<a &amp; !b<br/><font color="#5DA5DA">⓿</font>>]
3 [label="3"]
3 -> 2 [label=<a &amp; b<br/><font color="#5DA5DA">⓿</font>>]
3 -> 3 [label=<a &amp; !b<br/><font color="#5DA5DA">⓿</font>>]
}
#+end_example
#+BEGIN_SRC dot :file autfilt-hlnondet.svg :var txt=highlight-nondet :exports results
$txt
#+END_SRC

View file

@ -3,6 +3,7 @@
#+DESCRIPTION: How to compile C++14 programs using Spot
#+INCLUDE: setup.org
#+HTML_LINK_UP: tut.html
#+PROPERTY: header-args:C+++ :results verbatim :exports both
This page is not about compiling Spot itself (for this, please refer
to the [[file:install.org][installation instructions]]), but about how to compile and
@ -14,7 +15,7 @@ As an example we will take the following simple program, stored in a
file called =hello.cc=:
#+NAME: hello-word
#+BEGIN_SRC C++ :results verbatim :exports both
#+BEGIN_SRC C++
#include <iostream>
#include <spot/misc/version.hh>
@ -30,7 +31,7 @@ greetings and the Spot version:
#+RESULTS: hello-word
: Hello world!
: This is Spot 1.99.6a.
: This is Spot 2.7.2.dev.
To successfully compile this example program, we need a C++ compiler,

View file

@ -3,6 +3,7 @@
#+DESCRIPTION: Informal explanation of various concepts used in Spot.
#+INCLUDE: setup.org
#+HTML_LINK_UP: index.html
#+PROPERTY: header-args:sh :results verbatim :exports none
This page documents some of the concepts used in Spot, and whose
knowledge is usually assumed throughout the documentation. The
@ -128,7 +129,7 @@ For instance here is a Büchi automaton that accepts only words in
which $a$ is always true, and $b$ is true infinitely often.
#+NAME: buchi-example1
#+BEGIN_SRC sh :results verbatim :exports none
#+BEGIN_SRC sh
ltl2tgba 'G(a) & GF(b)' -B -d
#+END_SRC
@ -149,7 +150,7 @@ the [[#ltl][LTL formula]] =G(door_open -> light_on)= that specifies that
=light_on= should be true whenever =door_open= is true.
#+NAME: buchi-example2
#+BEGIN_SRC sh :results verbatim :exports none
#+BEGIN_SRC sh
ltl2tgba 'G(door_open -> light_on)' -d -C
#+END_SRC
@ -183,7 +184,7 @@ all runs in which at all point $a$ is true iff $b$ is true at the next
instant.
#+NAME: buchi-example3
#+BEGIN_SRC sh :results verbatim :exports none
#+BEGIN_SRC sh
ltl2tgba 'G(a <-> Xb)' -B -d
#+END_SRC
#+BEGIN_SRC dot :file concept-buchi3.svg :var txt=buchi-example3 :exports results
@ -210,7 +211,7 @@ have been aggregated in an edge.
Here is a simple example:
#+NAME: te1
#+BEGIN_SRC sh :results verbatim :exports none
#+BEGIN_SRC sh
cat >concept-te.hoa <<EOF
HOA: v1
Acceptance: 0 t
@ -232,7 +233,7 @@ $txt
[[file:concept-te1.svg]]
#+NAME: size
#+BEGIN_SRC sh :exports none
#+BEGIN_SRC sh
autfilt --merge --stats=$arg concept-te.hoa
#+END_SRC
@ -243,7 +244,7 @@ This is because those formula-labeled edges actually simplify the
following transition structure:
#+NAME: te2
#+BEGIN_SRC sh :results verbatim :exports none
#+BEGIN_SRC sh
autfilt concept-te.hoa -d.A
#+END_SRC
#+BEGIN_SRC dot :file concept-te2.svg :var txt=te2 :exports results
@ -296,7 +297,7 @@ states labeled with ❶ belong to set 1. Here each acceptance set
contains a single state.
#+NAME: gen-buchi-example1
#+BEGIN_SRC sh :results verbatim :exports none
#+BEGIN_SRC sh
ltl2tgba 'GFa & GFb' | autfilt -S --sat-minimize -d
#+END_SRC
@ -317,7 +318,7 @@ following automaton has the same language as the previous one (despite
its more complex look).
#+NAME: gen-buchi-example2
#+BEGIN_SRC sh :results verbatim :exports none
#+BEGIN_SRC sh
ltl2tgba 'GFa & GFb' -S -d
#+END_SRC
@ -337,7 +338,7 @@ with a 2-state generalized-Büchi automaton, but the smallest
equivalent Büchi automaton has three state:
#+NAME: gen-buchi-example-ba
#+BEGIN_SRC sh :results verbatim :exports none
#+BEGIN_SRC sh
ltl2tgba 'GFa & GFb' -B -d
#+END_SRC
@ -356,7 +357,7 @@ acceptance sets (as below). Spot's output routines have options for
both.
#+NAME: gen-buchi-example-ba2
#+BEGIN_SRC sh :results verbatim :exports none
#+BEGIN_SRC sh
ltl2tgba 'GFa & GFb' -B -d.b
#+END_SRC
@ -384,7 +385,7 @@ Here is an example of Transition-based Generalized Büchi Automaton
(TGBA).
#+NAME: tgba-example1
#+BEGIN_SRC sh :results verbatim :exports none
#+BEGIN_SRC sh
ltl2tgba 'GF(a & X(a U b))' -d
#+END_SRC
#+BEGIN_SRC dot :file concept-tgba1.svg :var txt=tgba-example1 :exports results
@ -403,7 +404,7 @@ The typical example is the LTL formula =GFa= (infinitely often $a$)
that can be represented using a one-state transition-based Büchi
automaton:
#+NAME: tgba-example2
#+BEGIN_SRC sh :results verbatim :exports none
#+BEGIN_SRC sh
ltl2tgba 'GFa' -d
#+END_SRC
#+BEGIN_SRC dot :file concept-tgba2.svg :var txt=tgba-example2 :exports results
@ -417,7 +418,7 @@ While the same property require a 2-state Büchi automaton using
state-based acceptance:
#+NAME: tgba-example3
#+BEGIN_SRC sh :results verbatim :exports none
#+BEGIN_SRC sh
ltl2tgba 'GFa' -B -d
#+END_SRC
#+BEGIN_SRC dot :file concept-tba-vs-ba.svg :var txt=tgba-example3 :exports results
@ -544,7 +545,7 @@ produced by =ltl2dstar= for the LTL formula =GFa | FGb=, but displayed
by Spot:
#+NAME: twa-example1
#+BEGIN_SRC sh :results verbatim :exports none
#+BEGIN_SRC sh
ltlfilt -l -f 'GFa | FGb' | ltl2dstar --output-format=hoa - - | autfilt --merge -d
#+END_SRC
#+BEGIN_SRC dot :file concept-twa1.svg :var txt=twa-example1 :exports results
@ -572,7 +573,7 @@ For instance the following alternating co-Büchi ω-automaton was
generated by [[https://sourceforge.net/projects/ltl3ba/][=ltl3ba 1.1.3=]] for the LTL formula =GF(a <-> Xb)=.
#+NAME: concepts-alt
#+BEGIN_SRC sh :results verbatim :exports none
#+BEGIN_SRC sh
autfilt -d.ba <<EOF
HOA: v1
States: 5
@ -635,7 +636,7 @@ alternating automata is the [[#hoa][HOA format, introduced below]].
infinitely often $p_1$). The graphical representation of that
automaton follows.
#+BEGIN_SRC sh :results verbatim :exports results
#+BEGIN_SRC sh :exports results
ltl2tgba -s 'p0 | GFp1' > tmp.$$
ltl2tgba -s6 'p0 | GFp1' | pr -w80 -m -t tmp.$$ -
rm tmp.$$
@ -665,7 +666,7 @@ accept_all: accept_all:
#+end_example
#+NAME: never-ex1
#+BEGIN_SRC sh :results verbatim :exports none
#+BEGIN_SRC sh
ltl2tgba -Bd 'p0 | GFp1'
#+END_SRC
#+BEGIN_SRC dot :file concept-never1.svg :var txt=never-ex1 :exports results
@ -697,7 +698,7 @@ LTL to (state-based) generalized Büchi automata, and then used by
For instance the Büchi automaton we used as an example for never
claims can be encoded as follows:
#+BEGIN_SRC sh :results verbatim :exports results
#+BEGIN_SRC sh :exports results
ltl2tgba --ba --lbtt 'p0 | GFp1'
#+END_SRC
@ -727,7 +728,7 @@ The format has been extended in two ways. First, LBTT extended it to
support transition-based acceptance. This is indicated by a =t= on
the first line:
#+BEGIN_SRC sh :results verbatim :exports results
#+BEGIN_SRC sh :exports results
ltl2tgba --lbtt 'p0 | GFp1'
#+END_SRC
@ -748,7 +749,7 @@ ltl2tgba --lbtt 'p0 | GFp1'
#+end_example
#+NAME: lbtt-ex2
#+BEGIN_SRC sh :results verbatim :exports none
#+BEGIN_SRC sh
ltl2tgba -d 'p0 | GFp1'
#+END_SRC
#+BEGIN_SRC dot :file concept-lbtt2.svg :var txt=lbtt-ex2 :exports results
@ -781,7 +782,7 @@ preferred. =ltl2dstar= can now also output HOA directly.
Here is one Rabin automaton in the DSTAR format:
#+BEGIN_SRC sh :results verbatim :exports results
#+BEGIN_SRC sh :exports results
echo '| F G p0 G F p1' | ltl2dstar --output-format=native - -
#+END_SRC
@ -821,7 +822,7 @@ Acc-Sig: +0 +1
#+end_example
#+NAME: dstar-example1
#+BEGIN_SRC sh :results verbatim :exports none
#+BEGIN_SRC sh
echo '| F G p0 G F p1' | ltl2dstar --output-format=native - - | autfilt -d
#+END_SRC
#+BEGIN_SRC dot :file concept-dstar.svg :var txt=dstar-example1 :exports results
@ -840,7 +841,7 @@ The [[http://adl.github.io/hoaf/][HOA format]] inherits several features from th
extends it in many ways, including support for non-deterministic
automata, alternating automata, and for arbitrary acceptance conditions.
#+BEGIN_SRC sh :results verbatim :exports results
#+BEGIN_SRC sh :exports results
ltldo ltl2dstar -f 'FGp0 | GFp1' --name=%f
#+END_SRC
@ -880,7 +881,7 @@ State: 3 {1 3}
#+end_example
#+NAME: hoa1
#+BEGIN_SRC sh :results verbatim :exports none
#+BEGIN_SRC sh
ltldo ltl2dstar -f 'FGp0 | GFp1' -d
#+END_SRC
#+BEGIN_SRC dot :file concept-hoa.svg :var txt=hoa1 :exports results
@ -994,7 +995,7 @@ automaton can then be simplified using several algorithms depending on what opti
Here is for instance a translation of ={(1;1)[*]}[]->a= discussed [[#psl][above]].
#+NAME: ltl2tgba1
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
ltl2tgba '{(1;1)[*]}[]->a' -d
#+END_SRC
#+BEGIN_SRC dot :file concept-ltl2tgba.svg :var txt=ltl2tgba1 :exports results

View file

@ -3,6 +3,7 @@
#+DESCRIPTION: Examples showing how to read and write CSV files using Spot's command-line tools.
#+INCLUDE: setup.org
#+HTML_LINK_UP: tools.html
#+PROPERTY: header-args:sh :results verbatim :exports both
This page discusses features available in Spot's command-line
tools to produce an consume CSV files.
@ -17,7 +18,7 @@ For instance here is how we could use =genltl= to generate a CSV file
with three columns: the family name of the formula, its parameter, and
the formula itself.
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
genltl --and-gf=1..5 --u-left=1..5 --format='%F,%L,%f' > gen.csv
cat gen.csv
#+END_SRC
@ -45,7 +46,7 @@ For instance, the following command will translate all the previous
formulas, and show the resulting number of states (=%s=) and edges
(=%e=) of the automaton constructed for each formula.
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
genltl --and-gf=1..5 --u-left=1..5 | ltl2tgba --stats '%f,%s,%e'
#+END_SRC
#+RESULTS:
@ -66,7 +67,7 @@ If the translated formulas may contain commas, or double quotes, this
simple output may prove difficult to process by other tools. For
instance consider the translation of the following two formulas:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltl2tgba -f Xa -f 'G("switch == on" -> F"tab[3,5] < 12")' --stats '%f,%s,%e'
#+END_SRC
#+RESULTS:
@ -77,7 +78,7 @@ The second line of this input does no conform to [[https://www.rfc-editor.org/rf
non-escaped fields are not allowed to contain comma or double quotes.
To fix this, simply double-quote the =%f= in the argument to =--stats=:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltl2tgba -f Xa -f 'G("switch == on" -> F"tab[3,5] < 12")' --stats '"%f",%s,%e'
#+END_SRC
@ -102,7 +103,7 @@ to support the specification of a CSV column. The notation
For instance let's consider the file =gen.csv= built with the first command of
this page. It contains:
#+BEGIN_SRC sh :results verbatim :exports results
#+BEGIN_SRC sh :exports results
cat gen.csv
#+END_SRC
#+RESULTS:
@ -122,7 +123,7 @@ u-left,5,(((p1 U p2) U p3) U p4) U p5
We can run =ltl2tgba= on the third column to produce
the same output as in a previous example:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltl2tgba -F gen.csv/3 --stats '%f,%s,%e'
#+END_SRC
#+RESULTS:
@ -143,7 +144,7 @@ When =ltlfilt= is used on a CSV file, it will preserve the
text before and after the matched formula in the CSV file.
For instance:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltlfilt -F gen.csv/3 --size-min=8 --relabel=abc
#+END_SRC
#+RESULTS:
@ -162,7 +163,7 @@ string.
For instance this moves the first two columns after the formulas.
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltlfilt -F gen.csv/3 --size-min=8 --format='"%f",%<'
#+END_SRC
#+RESULTS:
@ -190,7 +191,7 @@ Typical uses of =ltlfilt= on CSV file include:
Some CSV files contain a header lines that should not be processed.
For instance the CSV files produced by =ltlcross= have such a line:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
randltl -n 2 a b | ltlfilt --remove-wm |
ltlcross --csv=results.csv 'ltl2tgba -s %f >%N' 'ltl3ba -f %s >%N'
cat results.csv
@ -209,7 +210,7 @@ cat results.csv
If we run =ltlfilt= on the first column, it will process the =formula=
header as if it was an LTL formula.
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltlfilt -F results.csv/1 --format='%f' --unique
#+END_SRC
@ -223,7 +224,7 @@ ltlfilt -F results.csv/1 --format='%f' --unique
In such case, the syntax =FILENAME/-COL= (with a minus sign before the
column number) can be used to discard the first line of a CSV file.
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltlfilt -F results.csv/-1 --format='%f' --unique
#+END_SRC
@ -238,7 +239,7 @@ ltlfilt -F results.csv/-1 --format='%f' --unique
The =--stats= option of tools that generate automata can be used to
generate CSV files that embed automata. For instance
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
genltl --dac=1..3 | ltl2tgba --stats='"%f","%e edges","%h"' > csv-aut.csv
cat csv-aut.csv
#+END_SRC
@ -258,7 +259,7 @@ syntax we used previously, but by default it will just output the
automata. If you want to preserve the entire line, you should use
=%<= and =%>= in the =--stats= format.
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
autfilt csv-aut.csv/3 --states=2..3 --stats='%<,"%h"'
#+END_SRC
@ -271,7 +272,7 @@ Another source of automata in CSV format is =ltlcross=. Using options
=--automata= it will record the automata produced by each tool into
the CSV file:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
genltl --dac=1..3 | ltlcross --csv=result.csv --automata ltl2tgba
cat result.csv
#+END_SRC

View file

@ -3,6 +3,7 @@
#+DESCRIPTION: Spot command-line tool for converting automata into Transition-based Generalized Büchi Automata.
#+INCLUDE: setup.org
#+HTML_LINK_UP: tools.html
#+PROPERTY: header-args:sh :results verbatim :exports both
This tool converts automata into transition-based generalized Büchi
automata, a.k.a., TGBA. It can also produce Büchi automata on request
@ -35,85 +36,57 @@ The following command instructs =ltl2dstar= to:
Additionally we use =ltlfilt= to convert our formula to the
prefix format used by =ltl2dstar=.
#+BEGIN_SRC sh :results silent :exports both
#+BEGIN_SRC sh :results silent
ltlfilt -f '(a U b) & GFb' -l | ltl2dstar --ltl2nba=spin:ltl2tgba@-Ds - fagfb
#+END_SRC
By looking at the file =fagfb= you can see the =ltl2dsar= actually
produced a 4-state DRA:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
cat fagfb
#+END_SRC
#+RESULTS:
#+begin_example
DRA v2 explicit
Comment: "Safra[NBA=3]"
Comment: "DBA2DRA[NBA=3]"
States: 4
Acceptance-Pairs: 1
Start: 2
Start: 1
AP: 2 "a" "b"
---
State: 0
Acc-Sig: +0
3
3
Acc-Sig:
0
0
0
0
State: 1
Acc-Sig: -0
1
1
1
Acc-Sig:
0
1
3
3
State: 2
Acc-Sig:
1
2
0
0
2
3
3
State: 3
Acc-Sig:
Acc-Sig: +0
2
2
3
3
0
0
#+end_example
Let's display this automaton with =autfilt=:
#+NAME: fagfb
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
autfilt fagfb --dot
#+END_SRC
#+RESULTS: fagfb
#+begin_example
digraph G {
rankdir=LR
label=<Fin(<font color="#5DA5DA">⓿</font>) &amp; Inf(<font color="#F17CB0">❶</font>)>
labelloc="t"
node [shape="circle"]
fontname="Lato"
node [fontname="Lato"]
edge [fontname="Lato"]
node[style=filled, fillcolor="#ffffa0"] edge[arrowhead=vee, arrowsize=.7]
I [label="", style=invis, width=0]
I -> 2
0 [label=<0<br/><font color="#F17CB0">❶</font>>]
0 -> 0 [label=<b>]
0 -> 3 [label=<!b>]
1 [label=<1<br/><font color="#5DA5DA">⓿</font>>]
1 -> 1 [label=<1>]
2 [label=<2>]
2 -> 0 [label=<b>]
2 -> 1 [label=<!a &amp; !b>]
2 -> 2 [label=<a &amp; !b>]
3 [label=<3>]
3 -> 0 [label=<b>]
3 -> 3 [label=<!b>]
}
#+end_example
#+BEGIN_SRC dot :file fagfb.svg :var txt=fagfb :exports results
$txt
#+END_SRC
@ -127,31 +100,9 @@ a Monitor, using the same options as [[file:ltl2tgba.org][=ltl2tgba=]].
For instance here is the conversion to a Büchi automaton (=-B=):
#+NAME: fagfb2ba
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
dstar2tgba -B fagfb -d
#+END_SRC
#+RESULTS: fagfb2ba
#+begin_example
digraph G {
rankdir=LR
node [shape="circle"]
fontname="Lato"
node [fontname="Lato"]
edge [fontname="Lato"]
node[style=filled, fillcolor="#ffffa0"] edge[arrowhead=vee, arrowsize=.7]
I [label="", style=invis, width=0]
I -> 1
0 [label="0", peripheries=2]
0 -> 0 [label=<b>]
0 -> 2 [label=<!b>]
1 [label="1"]
1 -> 0 [label=<b>]
1 -> 1 [label=<a &amp; !b>]
2 [label="2"]
2 -> 0 [label=<b>]
2 -> 2 [label=<!b>]
}
#+end_example
#+BEGIN_SRC dot :file fagfb2ba.svg :var txt=fagfb2ba :exports results
$txt
@ -165,7 +116,7 @@ a complete automaton.
But we could as well require the output as a never claim for Spin (option =-s=):
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
dstar2tgba -s fagfb
#+END_SRC
#+RESULTS:
@ -173,18 +124,18 @@ dstar2tgba -s fagfb
never {
T0_init:
if
:: (b) -> goto accept_S0
:: ((a) && (!(b))) -> goto T0_init
:: (b) -> goto accept_S2
fi;
accept_S0:
T0_S1:
if
:: (b) -> goto accept_S0
:: (!(b)) -> goto T0_S2
:: (!(b)) -> goto T0_S1
:: (b) -> goto accept_S2
fi;
T0_S2:
accept_S2:
if
:: (b) -> goto accept_S0
:: (!(b)) -> goto T0_S2
:: (!(b)) -> goto T0_S1
:: (b) -> goto accept_S2
fi;
}
#+end_example
@ -197,7 +148,7 @@ T0_S2:
Here is the translation of =GFa | GFb= to a 4-state Streett automaton:
#+NAME: gfafgb
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
ltlfilt -f 'GFa & GFb' -l | ltl2dstar --automata=streett --ltl2nba=spin:ltl2tgba@-Ds - gfagfb
autfilt --dot gfagfb
#+END_SRC
@ -214,30 +165,9 @@ $txt
And now its conversion by =dstar2tgba= to a 1-state TGBA.
#+NAME: gfagfb2ba
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
dstar2tgba gfagfb -d
#+END_SRC
#+RESULTS: gfagfb2ba
#+begin_example
digraph "" {
rankdir=LR
label=<Inf(<font color="#1F78B4">⓿</font>)&amp;Inf(<font color="#FF4DA0">❶</font>)<br/>[gen. Büchi 2]>
labelloc="t"
node [shape="circle"]
node [style="filled", fillcolor="#ffffa0"]
fontname="Lato"
node [fontname="Lato"]
edge [fontname="Lato"]
node[fontsize=12] fontsize=12 stylesheet="spot.css" edge[arrowhead=vee, arrowsize=.7, fontsize=12]
I [label="", style=invis, width=0]
I -> 0
0 [label=<0>]
0 -> 0 [label=<!a &amp; !b>]
0 -> 0 [label=<!a &amp; b<br/><font color="#FF4DA0">❶</font>>]
0 -> 0 [label=<a &amp; !b<br/><font color="#1F78B4">⓿</font>>]
0 -> 0 [label=<a &amp; b<br/><font color="#1F78B4">⓿</font><font color="#FF4DA0">❶</font>>]
}
#+end_example
#+BEGIN_SRC dot :file gfagfb2ba.svg :var txt=gfagfb2ba :exports results
$txt
@ -267,7 +197,7 @@ The last two steps are shared with =ltl2tgba= and use the same options.
The type of automaton to produce can be selected using the =-B= or =-M=
switches:
#+BEGIN_SRC sh :results verbatim :exports results
#+BEGIN_SRC sh :exports results
dstar2tgba --help | sed -n '/Output automaton type:/,/^$/p' | sed '1d;$d'
#+END_SRC
@ -283,7 +213,7 @@ dstar2tgba --help | sed -n '/Output automaton type:/,/^$/p' | sed '1d;$d'
And these may be refined by a simplification goal, should the
post-processor routine had a choice to make:
#+BEGIN_SRC sh :results verbatim :exports results
#+BEGIN_SRC sh :exports results
dstar2tgba --help | sed -n '/Simplification goal:/,/^$/p' | sed '1d;$d'
#+END_SRC
#+RESULTS:
@ -295,7 +225,7 @@ dstar2tgba --help | sed -n '/Simplification goal:/,/^$/p' | sed '1d;$d'
The effort put into post-processing can be limited with the =--low= or
=--medium= options:
#+BEGIN_SRC sh :results verbatim :exports results
#+BEGIN_SRC sh :exports results
dstar2tgba --help | sed -n '/Simplification level:/,/^$/p' | sed '1d;$d'
#+END_SRC
#+RESULTS:
@ -308,7 +238,7 @@ should you find =dstar2tgba= too slow.
Finally, the output format can be changed with the following
[[file:oaut.org][common ouput options]]:
#+BEGIN_SRC sh :results verbatim :exports results
#+BEGIN_SRC sh :exports results
dstar2tgba --help | sed -n '/Output format:/,/^$/p' | sed '1d;$d'
#+END_SRC
#+RESULTS:
@ -377,7 +307,7 @@ of the input (Rabin) automaton, =%s=, the number of states of the
output (Büchi) automaton, =%d=, whether the output automaton is
deterministic, and =%p= whether the automaton is complete.
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
randltl -n -1 --tree-size=10..14 a b c |
ltlfilt --remove-wm -r -u --size-min=3 -n 10 |
while read f; do
@ -392,20 +322,20 @@ done
#+begin_example
(b | Fa) R Fc
DRA: 9st.; BA: 9st.; det.? 1; complete? 1
Ga U (Gc R (!a | Gc))
Ga U G(!a | Gc)
DRA: 7st.; BA: 7st.; det.? 0; complete? 0
GFc
DRA: 3st.; BA: 3st.; det.? 1; complete? 1
DRA: 2st.; BA: 2st.; det.? 1; complete? 1
!a | (a R b)
DRA: 3st.; BA: 2st.; det.? 1; complete? 0
Xc R (G!c R (b | G!c))
DRA: 4st.; BA: 2st.; det.? 1; complete? 0
Xc R G(b | G!c)
DRA: 3st.; BA: 2st.; det.? 1; complete? 0
c & G(b | F(a & c))
DRA: 4st.; BA: 3st.; det.? 1; complete? 0
XXFc
DRA: 4st.; BA: 4st.; det.? 1; complete? 1
XFc | Gb
DRA: 5st.; BA: 4st.; det.? 1; complete? 1
DRA: 4st.; BA: 4st.; det.? 1; complete? 1
G(((!a & Gc) | (a & F!c)) U (!a | Ga))
DRA: 6st.; BA: 5st.; det.? 1; complete? 1
a & !b

View file

@ -3,13 +3,14 @@
#+DESCRIPTION: Spot command-line tool that generates ω-automata from known patterns
#+INCLUDE: setup.org
#+HTML_LINK_UP: tools.html
#+PROPERTY: header-args:sh :results verbatim :exports both
This tool outputs ω-automata generated from scalable patterns.
These patterns are usually taken from the literature (see the
[[./man/genaut.1.html][=genaut=]](1) man page for references).
#+BEGIN_SRC sh :results verbatim :exports results
#+BEGIN_SRC sh :exports results
genaut --help | sed -n '/Pattern selection:/,/^$/p' | sed '1d;$d'
#+END_SRC
@ -19,9 +20,9 @@ genaut --help | sed -n '/Pattern selection:/,/^$/p' | sed '1d;$d'
: has at least 2^N/(2N+1) states.
: --l-dsa=RANGE A deterministic Streett automaton with 4N states
: with no equivalent deterministic Rabin automaton
: of less than n! states.
: of less than N! states.
: --l-nba=RANGE A Büchi automaton with 3N+1 states whose
: complementary Streett automaton needs at least n!
: complementary Streett automaton needs at least N!
: states.
@ -30,7 +31,7 @@ By default, the output format is [[file:hoa.org][HOA]], but this can be controll
For instance:
#+NAME: kscobuchi2
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
genaut --ks-nca=2 --dot
#+END_SRC

View file

@ -3,6 +3,7 @@
#+DESCRIPTION: Spot command-line tool that generates LTL formulas from known patterns
#+INCLUDE: setup.org
#+HTML_LINK_UP: tools.html
#+PROPERTY: header-args:sh :results verbatim :exports both
This tool outputs LTL formulas that either comes from named lists of
formulas, or from scalable patterns.
@ -12,7 +13,7 @@ These patterns are usually taken from the literature (see the
given different names in different papers, so we alias different
option names to the same pattern.
#+BEGIN_SRC sh :results verbatim :exports results
#+BEGIN_SRC sh :exports results
genltl --help | sed -n '/Pattern selection:/,/^$/p' | sed '1d;$d'
#+END_SRC
#+RESULTS:
@ -32,10 +33,16 @@ genltl --help | sed -n '/Pattern selection:/,/^$/p' | sed '1d;$d'
(range should be included in 1..55)
--eh-patterns[=RANGE] Etessami and Holzmann [Concur'00] patterns (range
should be included in 1..12)
--fxg-or=RANGE F(p0 | XG(p1 | XG(p2 | ... XG(pn))))
--gf-equiv=RANGE (GFa1 & GFa2 & ... & GFan) <-> GFz
--gf-equiv-xn=RANGE GF(a <-> X^n(a))
--gf-implies=RANGE (GFa1 & GFa2 & ... & GFan) -> GFz
--gf-implies-xn=RANGE GF(a -> X^n(a))
--gh-q=RANGE (F(p1)|G(p2))&(F(p2)|G(p3))&...&(F(pn)|G(p{n+1}))
--gh-r=RANGE (GF(p1)|FG(p2))&(GF(p2)|FG(p3))&...
&(GF(pn)|FG(p{n+1}))
--go-theta=RANGE !((GF(p1)&GF(p2)&...&GF(pn)) -> G(q->F(r)))
--gxf-and=RANGE G(p0 & XF(p1 & XF(p2 & ... XF(pn))))
--hkrss-patterns[=RANGE], --liberouter-patterns[=RANGE]
Holeček et al. patterns from the Liberouter
project (range should be included in 1..55)
@ -43,11 +50,19 @@ genltl --help | sed -n '/Pattern selection:/,/^$/p' | sed '1d;$d'
--kr-nlogn=RANGE quasilinear formula with doubly exponential DBA
--kv-psi=RANGE, --kr-n2=RANGE
quadratic formula with doubly exponential DBA
--ms-example=RANGE[,RANGE]
GF(a1&X(a2&X(a3&...Xan)))&F(b1&F(b2&F(b3&...&Xbm)))
--ms-phi-h=RANGE FG(a|b)|FG(!a|Xb)|FG(a|XXb)|FG(!a|XXXb)|...
--ms-phi-r=RANGE (FGa{n}&GFb{n})|((FGa{n-1}|GFb{n-1})&(...))
--ms-phi-s=RANGE (FGa{n}|GFb{n})&((FGa{n-1}&GFb{n-1})|(...))
--or-fg=RANGE, --ccj-xi=RANGE
FG(p1)|FG(p2)|...|FG(pn)
--or-g=RANGE, --gh-s=RANGE G(p1)|G(p2)|...|G(pn)
--or-gf=RANGE, --gh-c1=RANGE
GF(p1)|GF(p2)|...|GF(pn)
--p-patterns[=RANGE], --beem-patterns[=RANGE], --p[=RANGE]
Pelánek [Spin'07] patterns from BEEM (range
should be included in 1..20)
--r-left=RANGE (((p1 R p2) R p3) ... R pn)
--r-right=RANGE (p1 R (p2 R (... R pn)))
--rv-counter=RANGE n-bit counter
@ -57,6 +72,12 @@ genltl --help | sed -n '/Pattern selection:/,/^$/p' | sed '1d;$d'
--rv-counter-linear=RANGE n-bit counter (linear size)
--sb-patterns[=RANGE] Somenzi and Bloem [CAV'00] patterns (range should
be included in 1..27)
--sejk-f=RANGE[,RANGE] f(0,j)=(GFa0 U X^j(b)), f(i,j)=(GFai U
G(f(i-1,j)))
--sejk-j=RANGE (GFa1&...&GFan) -> (GFb1&...&GFbn)
--sejk-k=RANGE (GFa1|FGb1)&...&(GFan|FGbn)
--sejk-patterns[=RANGE] φ₁,φ₂,φ₃ from Sikert et al's [CAV'16]
paper (range should be included in 1..3)
--tv-f1=RANGE G(p -> (q | Xq | ... | XX...Xq)
--tv-f2=RANGE G(p -> (q | X(q | X(... | Xq)))
--tv-g1=RANGE G(p -> (q & Xq & ... & XX...Xq)
@ -70,7 +91,7 @@ genltl --help | sed -n '/Pattern selection:/,/^$/p' | sed '1d;$d'
An example is probably all it takes to understand how this tool works:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
genltl --and-gf=1..5 --u-left=1..5
#+END_SRC
#+RESULTS:
@ -94,7 +115,7 @@ For instance here is the same formulas, but formatted in a way that is
suitable for being included in a LaTeX table.
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
genltl --and-gf=1..5 --u-left=1..5 --latex --format='%F & %L & $%f$ \\'
#+END_SRC
#+RESULTS:
@ -115,19 +136,19 @@ Note that for the =--lbt= syntax, each formula is relabeled using
=p0=, =p1=, ... before it is output, when the pattern (like
=--ccj-alpha=) use different names. Compare:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
genltl --ccj-alpha=3
#+END_SRC
#+RESULTS:
: F(F(Fq3 & q2) & q1) & F(F(Fp3 & p2) & p1)
: F(p1 & F(p2 & Fp3)) & F(q1 & F(q2 & Fq3))
with
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
genltl --ccj-alpha=3 --lbt
#+END_SRC
#+RESULTS:
: & F & p2 F & p1 F p0 F & F & F p3 p4 p5
: & F & p0 F & p1 F p2 F & p3 F & p4 F p5
This is because most tools using =lbt='s syntax require atomic
propositions to have the form =pNN=.
@ -140,181 +161,181 @@ and =--sb-patterns=. With these options, the range is used to select
a subset of the list of formulas. Without range, all formulas are
used. Here is the complete list:
#+BEGIN_SRC sh :results verbatim :exports both
genltl --dac --eh --hkrss --p --sb --format=%F:%L,%f
#+BEGIN_SRC sh
genltl --dac --eh --hkrss --p --sb --format='%F=%L,%f'
#+END_SRC
#+RESULTS:
#+begin_example
dac-patterns:1,G!p0
dac-patterns:2,Fp0 -> (!p1 U p0)
dac-patterns:3,G(p0 -> G!p1)
dac-patterns:4,G((p0 & !p1 & Fp1) -> (!p2 U p1))
dac-patterns:5,G((p0 & !p1) -> (!p2 W p1))
dac-patterns:6,Fp0
dac-patterns:7,!p0 W (!p0 & p1)
dac-patterns:8,G!p0 | F(p0 & Fp1)
dac-patterns:9,G((p0 & !p1) -> (!p1 W (!p1 & p2)))
dac-patterns:10,G((p0 & !p1) -> (!p1 U (!p1 & p2)))
dac-patterns:11,!p0 W (p0 W (!p0 W (p0 W G!p0)))
dac-patterns:12,Fp0 -> ((!p0 & !p1) U (p0 | ((!p0 & p1) U (p0 | ((!p0 & !p1) U (p0 | ((!p0 & p1) U (p0 | (!p1 U p0)))))))))
dac-patterns:13,Fp0 -> (!p0 U (p0 & (!p1 W (p1 W (!p1 W (p1 W G!p1))))))
dac-patterns:14,G((p0 & Fp1) -> ((!p1 & !p2) U (p1 | ((!p1 & p2) U (p1 | ((!p1 & !p2) U (p1 | ((!p1 & p2) U (p1 | (!p2 U p1))))))))))
dac-patterns:15,G(p0 -> ((!p1 & !p2) U (p2 | ((p1 & !p2) U (p2 | ((!p1 & !p2) U (p2 | ((p1 & !p2) U (p2 | (!p1 W p2) | Gp1)))))))))
dac-patterns:16,Gp0
dac-patterns:17,Fp0 -> (p1 U p0)
dac-patterns:18,G(p0 -> Gp1)
dac-patterns:19,G((p0 & !p1 & Fp1) -> (p2 U p1))
dac-patterns:20,G((p0 & !p1) -> (p2 W p1))
dac-patterns:21,!p0 W p1
dac-patterns:22,Fp0 -> (!p1 U (p0 | p2))
dac-patterns:23,G!p0 | F(p0 & (!p1 W p2))
dac-patterns:24,G((p0 & !p1 & Fp1) -> (!p2 U (p1 | p3)))
dac-patterns:25,G((p0 & !p1) -> (!p2 W (p1 | p3)))
dac-patterns:26,G(p0 -> Fp1)
dac-patterns:27,Fp0 -> ((p1 -> (!p0 U (!p0 & p2))) U p0)
dac-patterns:28,G(p0 -> G(p1 -> Fp2))
dac-patterns:29,G((p0 & !p1 & Fp1) -> ((p2 -> (!p1 U (!p1 & p3))) U p1))
dac-patterns:30,G((p0 & !p1) -> ((p2 -> (!p1 U (!p1 & p3))) W p1))
dac-patterns:31,Fp0 -> (!p0 U (!p0 & p1 & X(!p0 U p2)))
dac-patterns:32,Fp0 -> (!p1 U (p0 | (!p1 & p2 & X(!p1 U p3))))
dac-patterns:33,G!p0 | (!p0 U ((p0 & Fp1) -> (!p1 U (!p1 & p2 & X(!p1 U p3)))))
dac-patterns:34,G((p0 & Fp1) -> (!p2 U (p1 | (!p2 & p3 & X(!p2 U p4)))))
dac-patterns:35,G(p0 -> (Fp1 -> (!p1 U (p2 | (!p1 & p3 & X(!p1 U p4))))))
dac-patterns:36,F(p0 & XFp1) -> (!p0 U p2)
dac-patterns:37,Fp0 -> (!(!p0 & p1 & X(!p0 U (!p0 & p2))) U (p0 | p3))
dac-patterns:38,G!p0 | (!p0 U (p0 & (F(p1 & XFp2) -> (!p1 U p3))))
dac-patterns:39,G((p0 & Fp1) -> (!(!p1 & p2 & X(!p1 U (!p1 & p3))) U (p1 | p4)))
dac-patterns:40,G(p0 -> ((!(!p1 & p2 & X(!p1 U (!p1 & p3))) U (p1 | p4)) | G!(p2 & XFp3)))
dac-patterns:41,G((p0 & XFp1) -> XF(p1 & Fp2))
dac-patterns:42,Fp0 -> (((p1 & X(!p0 U p2)) -> X(!p0 U (p2 & Fp3))) U p0)
dac-patterns:43,G(p0 -> G((p1 & XFp2) -> X(!p2 U (p2 & Fp3))))
dac-patterns:44,G((p0 & Fp1) -> (((p2 & X(!p1 U p3)) -> X(!p1 U (p3 & Fp4))) U p1))
dac-patterns:45,G(p0 -> (((p1 & X(!p2 U p3)) -> X(!p2 U (p3 & Fp4))) U (p2 | G((p1 & X(!p2 U p3)) -> X(!p2 U (p3 & Fp4))))))
dac-patterns:46,G(p0 -> F(p1 & XFp2))
dac-patterns:47,Fp0 -> ((p1 -> (!p0 U (!p0 & p2 & X(!p0 U p3)))) U p0)
dac-patterns:48,G(p0 -> G(p1 -> (p2 & XFp3)))
dac-patterns:49,G((p0 & Fp1) -> ((p2 -> (!p1 U (!p1 & p3 & X(!p1 U p4)))) U p1))
dac-patterns:50,G(p0 -> ((p1 -> (!p2 U (!p2 & p3 & X(!p2 U p4)))) U (p2 | G(p1 -> (p3 & XFp4)))))
dac-patterns:51,G(p0 -> F(p1 & !p2 & X(!p2 U p3)))
dac-patterns:52,Fp0 -> ((p1 -> (!p0 U (!p0 & p2 & !p3 & X((!p0 & !p3) U p4)))) U p0)
dac-patterns:53,G(p0 -> G(p1 -> (p2 & !p3 & X(!p3 U p4))))
dac-patterns:54,G((p0 & Fp1) -> ((p2 -> (!p1 U (!p1 & p3 & !p4 & X((!p1 & !p4) U p5)))) U p1))
dac-patterns:55,G(p0 -> ((p1 -> (!p2 U (!p2 & p3 & !p4 & X((!p2 & !p4) U p5)))) U (p2 | G(p1 -> (p3 & !p4 & X(!p4 U p5))))))
eh-patterns:1,p0 U (p1 & Gp2)
eh-patterns:2,p0 U (p1 & X(p2 U p3))
eh-patterns:3,p0 U (p1 & X(p2 & F(p3 & XF(p4 & XF(p5 & XFp6)))))
eh-patterns:4,F(p0 & XGp1)
eh-patterns:5,F(p0 & X(p1 & XFp2))
eh-patterns:6,F(p0 & X(p1 U p2))
eh-patterns:7,FGp0 | GFp1
eh-patterns:8,G(p0 -> (p1 U p2))
eh-patterns:9,G(p0 & XF(p1 & XF(p2 & XFp3)))
eh-patterns:10,GFp0 & GFp1 & GFp2 & GFp3 & GFp4
eh-patterns:11,(p0 U (p1 U p2)) | (p1 U (p2 U p0)) | (p2 U (p0 U p1))
eh-patterns:12,G(p0 -> (p1 U (Gp2 | Gp3)))
hkrss-patterns:1,G(Fp0 & F!p0)
hkrss-patterns:2,GFp0 & GF!p0
hkrss-patterns:3,GF(!(p1 <-> Xp1) | !(p0 <-> Xp0))
hkrss-patterns:4,GF(!(p1 <-> Xp1) | !(p0 <-> Xp0) | !(p2 <-> Xp2) | !(p3 <-> Xp3))
hkrss-patterns:5,G!p0
hkrss-patterns:6,G((p0 -> F!p0) & (!p0 -> Fp0))
hkrss-patterns:7,G(p0 -> F(p0 & p1))
hkrss-patterns:8,G(p0 -> F((!p0 & p1 & p2 & p3) -> Fp4))
hkrss-patterns:9,G(p0 -> F!p1)
hkrss-patterns:10,G(p0 -> Fp1)
hkrss-patterns:11,G(p0 -> F(p1 -> Fp2))
hkrss-patterns:12,G(p0 -> F((p1 & p2) -> Fp3))
hkrss-patterns:13,G((p0 -> Fp1) & (p2 -> Fp3) & (p4 -> Fp5) & (p6 -> Fp7))
hkrss-patterns:14,G(!p0 & !p1)
hkrss-patterns:15,G!(p0 & p1)
hkrss-patterns:16,G(p0 -> p1)
hkrss-patterns:17,G((p0 -> !p1) & (p1 -> !p0))
hkrss-patterns:18,G(!p0 -> (p1 <-> !p2))
hkrss-patterns:19,G((!p0 & (p1 | p2 | p3)) -> p4)
hkrss-patterns:20,G((p0 & p1) -> (p2 | !(p3 & p4)))
hkrss-patterns:21,G((!p0 & p1 & !p2 & !p3 & !p4) -> F(!p5 & !p6 & !p7 & !p8))
hkrss-patterns:22,G((p0 & p1 & !p2 & !p3 & !p4) -> F(p5 & !p6 & !p7 & !p8))
hkrss-patterns:23,G(!p0 -> !(p1 & p2 & p3 & p4 & p5))
hkrss-patterns:24,G(!p0 -> ((p1 & p2 & p3 & p4) -> !p5))
hkrss-patterns:25,G((p0 & p1) -> (p2 | p3 | !(p4 & p5)))
hkrss-patterns:26,G((!p0 & (p1 | p2 | p3 | p4)) -> (!p5 <-> p6))
hkrss-patterns:27,G((p0 & p1) -> (p2 | p3 | p4 | !(p5 & p6)))
hkrss-patterns:28,G((p0 & p1) -> (p2 | p3 | p4 | p5 | !(p6 & p7)))
hkrss-patterns:29,G((p0 & p1 & !p2 & Xp2) -> X(p3 | X(!p1 | p3)))
hkrss-patterns:30,G((p0 & p1 & !p2 & Xp2) -> X(X!p1 | (p2 U (!p2 U (p2 U (!p1 | p3))))))
hkrss-patterns:31,G(p0 & p1 & !p2 & Xp2) -> X(X!p1 | (p2 U (!p2 U (p2 U (!p1 | p3)))))
hkrss-patterns:32,G(p0 -> (p1 U (!p1 U (!p2 | p3))))
hkrss-patterns:33,G(p0 -> (p1 U (!p1 U (p2 | p3))))
hkrss-patterns:34,G((!p0 & p1) -> Xp2)
hkrss-patterns:35,G(p0 -> X(p0 | p1))
hkrss-patterns:36,G((!(p1 <-> Xp1) | !(p0 <-> Xp0) | !(p2 <-> Xp2) | !(p3 <-> Xp3)) -> (X!p4 & X(!(!(p1 <-> Xp1) | !(p0 <-> Xp0) | !(p2 <-> Xp2) | !(p3 <-> Xp3)) U p4)))
hkrss-patterns:37,G((p0 & !p1 & Xp1 & Xp0) -> (p2 -> Xp3))
hkrss-patterns:38,G(p0 -> X(!p0 U p1))
hkrss-patterns:39,G((!p0 & Xp0) -> X((p0 U p1) | Gp0))
hkrss-patterns:40,G((!p0 & Xp0) -> X(p0 U (p0 & !p1 & X(p0 & p1))))
hkrss-patterns:41,G((!p0 & Xp0) -> X(p0 U (p0 & !p1 & X(p0 & p1 & (p0 U (p0 & !p1 & X(p0 & p1)))))))
hkrss-patterns:42,G((p0 & X!p0) -> X(!p0 U (!p0 & !p1 & X(!p0 & p1 & (!p0 U (!p0 & !p1 & X(!p0 & p1)))))))
hkrss-patterns:43,G((p0 & X!p0) -> X(!p0 U (!p0 & !p1 & X(!p0 & p1 & (!p0 U (!p0 & !p1 & X(!p0 & p1 & (!p0 U (!p0 & !p1 & X(!p0 & p1))))))))))
hkrss-patterns:44,G((!p0 & Xp0) -> X(!(!p0 & Xp0) U (!p1 & Xp1)))
hkrss-patterns:45,G(!p0 | X(!p0 | X(!p0 | X(!p0 | X(!p0 | X(!p0 | X(!p0 | X(!p0 | X(!p0 | X(!p0 | X(!p0 | X!p0)))))))))))
hkrss-patterns:46,G((Xp0 -> p0) -> (p1 <-> Xp1))
hkrss-patterns:47,G((Xp0 -> p0) -> ((p1 -> Xp1) & (!p1 -> X!p1)))
hkrss-patterns:48,!p0 U G!((p1 & p2) | (p3 & p4) | (p2 & p3) | (p2 & p4) | (p1 & p4) | (p1 & p3))
hkrss-patterns:49,!p0 U p1
hkrss-patterns:50,(p0 U p1) | Gp0
hkrss-patterns:51,p0 & XG!p0
hkrss-patterns:52,XG(p0 -> (G!p1 | (!Xp1 U p2)))
hkrss-patterns:53,XG((p0 & !p1) -> (G!p1 | (!p1 U p2)))
hkrss-patterns:54,XG((p0 & p1) -> ((p1 U p2) | Gp1))
hkrss-patterns:55,Xp0 & G((!p0 & Xp0) -> XXp0)
p-patterns:1,G(p0 -> Fp1)
p-patterns:2,(GFp1 & GFp0) -> GFp2
p-patterns:3,G(p0 -> (p1 & (p2 U p3)))
p-patterns:4,F(p0 | p1)
p-patterns:5,GF(p0 | p1)
p-patterns:6,(p0 U p1) -> ((p2 U p3) | Gp2)
p-patterns:7,G(p0 -> (!p1 U (p1 U (!p1 & (p2 R !p1)))))
p-patterns:8,G(p0 -> (p1 R !p2))
p-patterns:9,G(!p0 -> Fp0)
p-patterns:10,G(p0 -> F(p1 | p2))
p-patterns:11,!(!(p0 | p1) U p2) & G(p3 -> !(!(p0 | p1) U p2))
p-patterns:12,G!p0 -> G!p1
p-patterns:13,G(p0 -> (G!p1 | (!p2 U p1)))
p-patterns:14,G(p0 -> (p1 R (p1 | !p2)))
p-patterns:15,G((p0 & p1) -> (!p1 R (p0 | !p1)))
p-patterns:16,G(p0 -> F(p1 & p2))
p-patterns:17,G(p0 -> (!p1 U (p1 U (p1 & p2))))
p-patterns:18,G(p0 -> (!p1 U (p1 U (!p1 U (p1 U (p1 & p2))))))
p-patterns:19,GFp0 -> GFp1
p-patterns:20,GF(p0 | p1) & GF(p1 | p2)
sb-patterns:1,p0 U p1
sb-patterns:2,p0 U (p1 U p2)
sb-patterns:3,!(p0 U (p1 U p2))
sb-patterns:4,GFp0 -> GFp1
sb-patterns:5,Fp0 U Gp1
sb-patterns:6,Gp0 U p1
sb-patterns:7,!(Fp0 <-> Fp1)
sb-patterns:8,!(GFp0 -> GFp1)
sb-patterns:9,!(GFp0 <-> GFp1)
sb-patterns:10,p0 R (p0 | p1)
sb-patterns:11,(Xp0 U Xp1) | !X(p0 U p1)
sb-patterns:12,(Xp0 U p1) | !X(p0 U (p0 & p1))
sb-patterns:13,G(p0 -> Fp1) & ((Xp0 U p1) | !X(p0 U (p0 & p1)))
sb-patterns:14,G(p0 -> Fp1) & ((Xp0 U Xp1) | !X(p0 U p1))
sb-patterns:15,G(p0 -> Fp1)
sb-patterns:16,!G(p0 -> X(p1 R p2))
sb-patterns:17,!(FGp0 | FGp1)
sb-patterns:18,G(Fp0 & Fp1)
sb-patterns:19,Fp0 & F!p0
sb-patterns:20,(p0 & Xp1) R X(((p2 U p3) R p0) U (p2 R p0))
sb-patterns:21,Gp2 | (G(p0 | GFp1) & G(p2 | GF!p1)) | Gp0
sb-patterns:22,Gp0 | Gp2 | (G(p0 | FGp1) & G(p2 | FG!p1))
sb-patterns:23,!(Gp2 | (G(p0 | GFp1) & G(p2 | GF!p1)) | Gp0)
sb-patterns:24,!(Gp0 | Gp2 | (G(p0 | FGp1) & G(p2 | FG!p1)))
sb-patterns:25,G(p0 | XGp1) & G(p2 | XG!p1)
sb-patterns:26,G(p0 | (Xp1 & X!p1))
sb-patterns:27,p0 | (p1 U p0)
dac-patterns=1,G!p0
dac-patterns=2,Fp0 -> (!p1 U p0)
dac-patterns=3,G(p0 -> G!p1)
dac-patterns=4,G((p0 & !p1 & Fp1) -> (!p2 U p1))
dac-patterns=5,G((p0 & !p1) -> (!p2 W p1))
dac-patterns=6,Fp0
dac-patterns=7,!p0 W (!p0 & p1)
dac-patterns=8,G!p0 | F(p0 & Fp1)
dac-patterns=9,G((p0 & !p1) -> (!p1 W (!p1 & p2)))
dac-patterns=10,G((p0 & !p1) -> (!p1 U (!p1 & p2)))
dac-patterns=11,!p0 W (p0 W (!p0 W (p0 W G!p0)))
dac-patterns=12,Fp0 -> ((!p0 & !p1) U (p0 | ((!p0 & p1) U (p0 | ((!p0 & !p1) U (p0 | ((!p0 & p1) U (p0 | (!p1 U p0)))))))))
dac-patterns=13,Fp0 -> (!p0 U (p0 & (!p1 W (p1 W (!p1 W (p1 W G!p1))))))
dac-patterns=14,G((p0 & Fp1) -> ((!p1 & !p2) U (p1 | ((!p1 & p2) U (p1 | ((!p1 & !p2) U (p1 | ((!p1 & p2) U (p1 | (!p2 U p1))))))))))
dac-patterns=15,G(p0 -> ((!p1 & !p2) U (p2 | ((p1 & !p2) U (p2 | ((!p1 & !p2) U (p2 | ((p1 & !p2) U (p2 | (!p1 W p2) | Gp1)))))))))
dac-patterns=16,Gp0
dac-patterns=17,Fp0 -> (p1 U p0)
dac-patterns=18,G(p0 -> Gp1)
dac-patterns=19,G((p0 & !p1 & Fp1) -> (p2 U p1))
dac-patterns=20,G((p0 & !p1) -> (p2 W p1))
dac-patterns=21,!p0 W p1
dac-patterns=22,Fp0 -> (!p1 U (p0 | p2))
dac-patterns=23,G!p0 | F(p0 & (!p1 W p2))
dac-patterns=24,G((p0 & !p1 & Fp1) -> (!p2 U (p1 | p3)))
dac-patterns=25,G((p0 & !p1) -> (!p2 W (p1 | p3)))
dac-patterns=26,G(p0 -> Fp1)
dac-patterns=27,Fp0 -> ((p1 -> (!p0 U (!p0 & p2))) U p0)
dac-patterns=28,G(p0 -> G(p1 -> Fp2))
dac-patterns=29,G((p0 & !p1 & Fp1) -> ((p2 -> (!p1 U (!p1 & p3))) U p1))
dac-patterns=30,G((p0 & !p1) -> ((p2 -> (!p1 U (!p1 & p3))) W p1))
dac-patterns=31,Fp0 -> (!p0 U (!p0 & p1 & X(!p0 U p2)))
dac-patterns=32,Fp0 -> (!p1 U (p0 | (!p1 & p2 & X(!p1 U p3))))
dac-patterns=33,G!p0 | (!p0 U ((p0 & Fp1) -> (!p1 U (!p1 & p2 & X(!p1 U p3)))))
dac-patterns=34,G((p0 & Fp1) -> (!p2 U (p1 | (!p2 & p3 & X(!p2 U p4)))))
dac-patterns=35,G(p0 -> (Fp1 -> (!p1 U (p2 | (!p1 & p3 & X(!p1 U p4))))))
dac-patterns=36,F(p0 & XFp1) -> (!p0 U p2)
dac-patterns=37,Fp0 -> (!(!p0 & p1 & X(!p0 U (!p0 & p2))) U (p0 | p3))
dac-patterns=38,G!p0 | (!p0 U (p0 & (F(p1 & XFp2) -> (!p1 U p3))))
dac-patterns=39,G((p0 & Fp1) -> (!(!p1 & p2 & X(!p1 U (!p1 & p3))) U (p1 | p4)))
dac-patterns=40,G(p0 -> ((!(!p1 & p2 & X(!p1 U (!p1 & p3))) U (p1 | p4)) | G!(p2 & XFp3)))
dac-patterns=41,G((p0 & XFp1) -> XF(p1 & Fp2))
dac-patterns=42,Fp0 -> (((p1 & X(!p0 U p2)) -> X(!p0 U (p2 & Fp3))) U p0)
dac-patterns=43,G(p0 -> G((p1 & XFp2) -> X(!p2 U (p2 & Fp3))))
dac-patterns=44,G((p0 & Fp1) -> (((p2 & X(!p1 U p3)) -> X(!p1 U (p3 & Fp4))) U p1))
dac-patterns=45,G(p0 -> (((p1 & X(!p2 U p3)) -> X(!p2 U (p3 & Fp4))) U (p2 | G((p1 & X(!p2 U p3)) -> X(!p2 U (p3 & Fp4))))))
dac-patterns=46,G(p0 -> F(p1 & XFp2))
dac-patterns=47,Fp0 -> ((p1 -> (!p0 U (!p0 & p2 & X(!p0 U p3)))) U p0)
dac-patterns=48,G(p0 -> G(p1 -> (p2 & XFp3)))
dac-patterns=49,G((p0 & Fp1) -> ((p2 -> (!p1 U (!p1 & p3 & X(!p1 U p4)))) U p1))
dac-patterns=50,G(p0 -> ((p1 -> (!p2 U (!p2 & p3 & X(!p2 U p4)))) U (p2 | G(p1 -> (p3 & XFp4)))))
dac-patterns=51,G(p0 -> F(p1 & !p2 & X(!p2 U p3)))
dac-patterns=52,Fp0 -> ((p1 -> (!p0 U (!p0 & p2 & !p3 & X((!p0 & !p3) U p4)))) U p0)
dac-patterns=53,G(p0 -> G(p1 -> (p2 & !p3 & X(!p3 U p4))))
dac-patterns=54,G((p0 & Fp1) -> ((p2 -> (!p1 U (!p1 & p3 & !p4 & X((!p1 & !p4) U p5)))) U p1))
dac-patterns=55,G(p0 -> ((p1 -> (!p2 U (!p2 & p3 & !p4 & X((!p2 & !p4) U p5)))) U (p2 | G(p1 -> (p3 & !p4 & X(!p4 U p5))))))
eh-patterns=1,p0 U (p1 & Gp2)
eh-patterns=2,p0 U (p1 & X(p2 U p3))
eh-patterns=3,p0 U (p1 & X(p2 & F(p3 & XF(p4 & XF(p5 & XFp6)))))
eh-patterns=4,F(p0 & XGp1)
eh-patterns=5,F(p0 & X(p1 & XFp2))
eh-patterns=6,F(p0 & X(p1 U p2))
eh-patterns=7,FGp0 | GFp1
eh-patterns=8,G(p0 -> (p1 U p2))
eh-patterns=9,G(p0 & XF(p1 & XF(p2 & XFp3)))
eh-patterns=10,GFp0 & GFp1 & GFp2 & GFp3 & GFp4
eh-patterns=11,(p0 U (p1 U p2)) | (p1 U (p2 U p0)) | (p2 U (p0 U p1))
eh-patterns=12,G(p0 -> (p1 U (Gp2 | Gp3)))
hkrss-patterns=1,G(Fp0 & F!p0)
hkrss-patterns=2,GFp0 & GF!p0
hkrss-patterns=3,GF(!(p1 <-> Xp1) | !(p0 <-> Xp0))
hkrss-patterns=4,GF(!(p1 <-> Xp1) | !(p0 <-> Xp0) | !(p2 <-> Xp2) | !(p3 <-> Xp3))
hkrss-patterns=5,G!p0
hkrss-patterns=6,G((p0 -> F!p0) & (!p0 -> Fp0))
hkrss-patterns=7,G(p0 -> F(p0 & p1))
hkrss-patterns=8,G(p0 -> F((!p0 & p1 & p2 & p3) -> Fp4))
hkrss-patterns=9,G(p0 -> F!p1)
hkrss-patterns=10,G(p0 -> Fp1)
hkrss-patterns=11,G(p0 -> F(p1 -> Fp2))
hkrss-patterns=12,G(p0 -> F((p1 & p2) -> Fp3))
hkrss-patterns=13,G((p0 -> Fp1) & (p2 -> Fp3) & (p4 -> Fp5) & (p6 -> Fp7))
hkrss-patterns=14,G(!p0 & !p1)
hkrss-patterns=15,G!(p0 & p1)
hkrss-patterns=16,G(p0 -> p1)
hkrss-patterns=17,G((p0 -> !p1) & (p1 -> !p0))
hkrss-patterns=18,G(!p0 -> (p1 <-> !p2))
hkrss-patterns=19,G((!p0 & (p1 | p2 | p3)) -> p4)
hkrss-patterns=20,G((p0 & p1) -> (p2 | !(p3 & p4)))
hkrss-patterns=21,G((!p0 & p1 & !p2 & !p3 & !p4) -> F(!p5 & !p6 & !p7 & !p8))
hkrss-patterns=22,G((p0 & p1 & !p2 & !p3 & !p4) -> F(p5 & !p6 & !p7 & !p8))
hkrss-patterns=23,G(!p0 -> !(p1 & p2 & p3 & p4 & p5))
hkrss-patterns=24,G(!p0 -> ((p1 & p2 & p3 & p4) -> !p5))
hkrss-patterns=25,G((p0 & p1) -> (p2 | p3 | !(p4 & p5)))
hkrss-patterns=26,G((!p0 & (p1 | p2 | p3 | p4)) -> (!p5 <-> p6))
hkrss-patterns=27,G((p0 & p1) -> (p2 | p3 | p4 | !(p5 & p6)))
hkrss-patterns=28,G((p0 & p1) -> (p2 | p3 | p4 | p5 | !(p6 & p7)))
hkrss-patterns=29,G((p0 & p1 & !p2 & Xp2) -> X(p3 | X(!p1 | p3)))
hkrss-patterns=30,G((p0 & p1 & !p2 & Xp2) -> X(X!p1 | (p2 U (!p2 U (p2 U (!p1 | p3))))))
hkrss-patterns=31,G(p0 & p1 & !p2 & Xp2) -> X(X!p1 | (p2 U (!p2 U (p2 U (!p1 | p3)))))
hkrss-patterns=32,G(p0 -> (p1 U (!p1 U (!p2 | p3))))
hkrss-patterns=33,G(p0 -> (p1 U (!p1 U (p2 | p3))))
hkrss-patterns=34,G((!p0 & p1) -> Xp2)
hkrss-patterns=35,G(p0 -> X(p0 | p1))
hkrss-patterns=36,G((!(p1 <-> Xp1) | !(p0 <-> Xp0) | !(p2 <-> Xp2) | !(p3 <-> Xp3)) -> (X!p4 & X(!(!(p1 <-> Xp1) | !(p0 <-> Xp0) | !(p2 <-> Xp2) | !(p3 <-> Xp3)) U p4)))
hkrss-patterns=37,G((p0 & !p1 & Xp1 & Xp0) -> (p2 -> Xp3))
hkrss-patterns=38,G(p0 -> X(!p0 U p1))
hkrss-patterns=39,G((!p0 & Xp0) -> X((p0 U p1) | Gp0))
hkrss-patterns=40,G((!p0 & Xp0) -> X(p0 U (p0 & !p1 & X(p0 & p1))))
hkrss-patterns=41,G((!p0 & Xp0) -> X(p0 U (p0 & !p1 & X(p0 & p1 & (p0 U (p0 & !p1 & X(p0 & p1)))))))
hkrss-patterns=42,G((p0 & X!p0) -> X(!p0 U (!p0 & !p1 & X(!p0 & p1 & (!p0 U (!p0 & !p1 & X(!p0 & p1)))))))
hkrss-patterns=43,G((p0 & X!p0) -> X(!p0 U (!p0 & !p1 & X(!p0 & p1 & (!p0 U (!p0 & !p1 & X(!p0 & p1 & (!p0 U (!p0 & !p1 & X(!p0 & p1))))))))))
hkrss-patterns=44,G((!p0 & Xp0) -> X(!(!p0 & Xp0) U (!p1 & Xp1)))
hkrss-patterns=45,G(!p0 | X(!p0 | X(!p0 | X(!p0 | X(!p0 | X(!p0 | X(!p0 | X(!p0 | X(!p0 | X(!p0 | X(!p0 | X!p0)))))))))))
hkrss-patterns=46,G((Xp0 -> p0) -> (p1 <-> Xp1))
hkrss-patterns=47,G((Xp0 -> p0) -> ((p1 -> Xp1) & (!p1 -> X!p1)))
hkrss-patterns=48,!p0 U G!((p1 & p2) | (p3 & p4) | (p2 & p3) | (p2 & p4) | (p1 & p4) | (p1 & p3))
hkrss-patterns=49,!p0 U p1
hkrss-patterns=50,(p0 U p1) | Gp0
hkrss-patterns=51,p0 & XG!p0
hkrss-patterns=52,XG(p0 -> (G!p1 | (!Xp1 U p2)))
hkrss-patterns=53,XG((p0 & !p1) -> (G!p1 | (!p1 U p2)))
hkrss-patterns=54,XG((p0 & p1) -> ((p1 U p2) | Gp1))
hkrss-patterns=55,Xp0 & G((!p0 & Xp0) -> XXp0)
p-patterns=1,G(p0 -> Fp1)
p-patterns=2,(GFp1 & GFp0) -> GFp2
p-patterns=3,G(p0 -> (p1 & (p2 U p3)))
p-patterns=4,F(p0 | p1)
p-patterns=5,GF(p0 | p1)
p-patterns=6,(p0 U p1) -> ((p2 U p3) | Gp2)
p-patterns=7,G(p0 -> (!p1 U (p1 U (!p1 & (p2 R !p1)))))
p-patterns=8,G(p0 -> (p1 R !p2))
p-patterns=9,G(!p0 -> Fp0)
p-patterns=10,G(p0 -> F(p1 | p2))
p-patterns=11,!(!(p0 | p1) U p2) & G(p3 -> !(!(p0 | p1) U p2))
p-patterns=12,G!p0 -> G!p1
p-patterns=13,G(p0 -> (G!p1 | (!p2 U p1)))
p-patterns=14,G(p0 -> (p1 R (p1 | !p2)))
p-patterns=15,G((p0 & p1) -> (!p1 R (p0 | !p1)))
p-patterns=16,G(p0 -> F(p1 & p2))
p-patterns=17,G(p0 -> (!p1 U (p1 U (p1 & p2))))
p-patterns=18,G(p0 -> (!p1 U (p1 U (!p1 U (p1 U (p1 & p2))))))
p-patterns=19,GFp0 -> GFp1
p-patterns=20,GF(p0 | p1) & GF(p1 | p2)
sb-patterns=1,p0 U p1
sb-patterns=2,p0 U (p1 U p2)
sb-patterns=3,!(p0 U (p1 U p2))
sb-patterns=4,GFp0 -> GFp1
sb-patterns=5,Fp0 U Gp1
sb-patterns=6,Gp0 U p1
sb-patterns=7,!(Fp0 <-> Fp1)
sb-patterns=8,!(GFp0 -> GFp1)
sb-patterns=9,!(GFp0 <-> GFp1)
sb-patterns=10,p0 R (p0 | p1)
sb-patterns=11,(Xp0 U Xp1) | !X(p0 U p1)
sb-patterns=12,(Xp0 U p1) | !X(p0 U (p0 & p1))
sb-patterns=13,G(p0 -> Fp1) & ((Xp0 U p1) | !X(p0 U (p0 & p1)))
sb-patterns=14,G(p0 -> Fp1) & ((Xp0 U Xp1) | !X(p0 U p1))
sb-patterns=15,G(p0 -> Fp1)
sb-patterns=16,!G(p0 -> X(p1 R p2))
sb-patterns=17,!(FGp0 | FGp1)
sb-patterns=18,G(Fp0 & Fp1)
sb-patterns=19,Fp0 & F!p0
sb-patterns=20,(p0 & Xp1) R X(((p2 U p3) R p0) U (p2 R p0))
sb-patterns=21,Gp2 | (G(p0 | GFp1) & G(p2 | GF!p1)) | Gp0
sb-patterns=22,Gp0 | Gp2 | (G(p0 | FGp1) & G(p2 | FG!p1))
sb-patterns=23,!(Gp2 | (G(p0 | GFp1) & G(p2 | GF!p1)) | Gp0)
sb-patterns=24,!(Gp0 | Gp2 | (G(p0 | FGp1) & G(p2 | FG!p1)))
sb-patterns=25,G(p0 | XGp1) & G(p2 | XG!p1)
sb-patterns=26,G(p0 | (Xp1 & X!p1))
sb-patterns=27,p0 | (p1 U p0)
#+end_example
Note that ~--sb-patterns=2 --sb-patterns=4 --sb-patterns=21..22~ also
@ -323,7 +344,7 @@ have their complement formula listed as ~--sb-patterns=3
formula output by =genltl --sb-patterns= plus its negation, it will
contain only 46 formulas, not 54.
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
genltl --sb | ltlfilt --uniq --count
genltl --sb --pos --neg | ltlfilt --uniq --count
#+END_SRC

View file

@ -3,6 +3,7 @@
#+DESCRIPTION: Spot command-line tools for exploring the temporal hierarchy of Manna & Pnueli
#+INCLUDE: setup.org
#+HTML_LINK_UP: tools.html
#+PROPERTY: header-args:sh :results verbatim :exports both
/A hierarchy of temporal properties/ was defined by Manna & Pnueli in
their [[ftp://www-cs.stanford.edu/cs/theory/amir/hierarchy.ps][PODC'90 paper]].
@ -83,7 +84,7 @@ Spot to denote the classes.
The =--format=%h= option can be used to display the "class key" of the
most precise class to which a formula belongs.
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltlfilt -f 'a U b' --format=%h
#+END_SRC
#+RESULTS:
@ -92,7 +93,7 @@ ltlfilt -f 'a U b' --format=%h
If you find hard to remember the class name corresponding to the class
keys, you can request verbose output with =%[v]h=:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltlfilt -f 'a U b' --format='%[v]h'
#+END_SRC
#+RESULTS:
@ -102,7 +103,7 @@ But actually any /guarantee/ property is also an /obligation/, a
/recurrence/, a /persistence/, and a /reactivity/ property. You can
get the complete list of classes using =%[w]h= or =%[vw]h=:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltlfilt -f 'a U b' --format='%[w]h = %[vw]h'
#+END_SRC
#+RESULTS:
@ -112,7 +113,7 @@ This =--format= option is also supported by =randltl=, =genltl=, and
=ltlgrind=. So for instance if you want to classify the 55 LTL
patterns of [[http://patterns.projects.cs.ksu.edu/documentation/patterns/ltl.shtml][Dwyers et al. (FMSP'98)]] using this hierarchy, try:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
genltl --dac-patterns --format='%[v]h' | sort | uniq -c
#+END_SRC
@ -139,7 +140,7 @@ three non-recurrence formulas, we can use =ltlfilt -v --recurrence= to
remove all recurrence properties from the =genltl --dac-pattern=
output:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
genltl --dac-patterns |
ltlfilt -v --recurrence --format='%[v]h, %f'
#+END_SRC
@ -154,7 +155,7 @@ are automata-based, they work with PSL formulas as well. For instance,
here is how to generate 10 random recurrence PSL formulas that are
not LTL formulas, and that are not obligations:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
randltl --psl -n -1 a b |
ltlfilt -v --ltl |
ltlfilt -v --obligation |
@ -193,18 +194,18 @@ sequences, we can use it with =%h= to split a list of formulas in 7
possible files. Here is a generation of 200 random LTL formulas
binned into aptly named files:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
randltl -n 200 a b -o random-%h.ltl
wc -l random-?.ltl
#+END_SRC
#+RESULTS:
: 40 random-B.ltl
: 45 random-B.ltl
: 49 random-G.ltl
: 12 random-O.ltl
: 21 random-P.ltl
: 18 random-R.ltl
: 51 random-S.ltl
: 46 random-S.ltl
: 9 random-T.ltl
: 200 total
@ -229,7 +230,7 @@ is in class syntactic-C).
Here is how to generate 10 random LTL formulas that describe safety
properties but that are not in the syntactic-safety class:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
randltl -n-1 a b |
ltlfilt -v --syntactic-safety |
ltlfilt --safety -n10
@ -255,7 +256,7 @@ fragment. For instance =b M Gb= can be rewritten as just =Gb=, which
belongs to this fragment. In this particular case, =ltlfilt
--simplify= recognizes this:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltlfilt --simplify -f 'b M Gb'
#+END_SRC
#+RESULTS:
@ -291,7 +292,7 @@ the translator could produce before determinization and minimization.
For instance =Fa R b= is an obligation:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltlfilt -f 'Fa R b' --format='%[v]h'
#+END_SRC
@ -303,7 +304,7 @@ automaton (here we use =autfilt --highlight-nondet= to show where the
non-determinism occurs):
#+NAME: hier-oblig-1
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
ltl2tgba 'Fa R b' | autfilt --highlight-nondet -d
#+END_SRC
@ -351,7 +352,7 @@ For instance, let us use =ltl2dstar= to construct a Streett automaton
for the obligation property =Ga | XFb=.
#+NAME: hier-oblig-3
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
ltldo 'ltl2dstar --automata=streett' -f 'Ga | XFb' -d
#+END_SRC
@ -365,7 +366,7 @@ $txt
We can now minimize this automaton with:
#+NAME: hier-oblig-4
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
ltldo 'ltl2dstar --automata=streett' -f 'Ga | XFb' | autfilt -D -C -d
#+END_SRC
#+BEGIN_SRC dot :file hier-oblig-4.svg :var txt=hier-oblig-4 :exports results
@ -390,7 +391,7 @@ The output should be a terminal automaton in either case,
An example is =a U Xb=:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltlfilt -f 'a U Xb' --format='%[v]h'
#+END_SRC
@ -399,7 +400,7 @@ ltlfilt -f 'a U Xb' --format='%[v]h'
#+NAME: hier-guarantee-1
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
ltl2tgba 'a U Xb' | autfilt --highlight-nondet -d
#+END_SRC
#+BEGIN_SRC dot :file hier-guarantee-1.svg :var txt=hier-guarantee-1 :exports results
@ -410,7 +411,7 @@ $txt
[[file:hier-guarantee-1.svg]]
#+NAME: hier-guarantee-2
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
ltl2tgba -D 'a U Xb' -d
#+END_SRC
#+BEGIN_SRC dot :file hier-guarantee-2.svg :var txt=hier-guarantee-2 :exports results
@ -440,7 +441,7 @@ run are accepting.
Here is an example:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltlfilt -f '(a W Gb) M b' --format='%[v]h'
#+END_SRC
@ -449,7 +450,7 @@ ltlfilt -f '(a W Gb) M b' --format='%[v]h'
#+NAME: hier-safety-1
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
ltl2tgba '(a W Gb) M b' | autfilt --highlight-nondet -d
#+END_SRC
#+BEGIN_SRC dot :file hier-safety-1.svg :var txt=hier-safety-1 :exports results
@ -466,7 +467,7 @@ Using =-D= will fix that: it then produces a deterministic automaton
that is guaranteed to be minimal, and where all runs are accepting.
#+NAME: hier-safety-2
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
ltl2tgba -D '(a W Gb) M b' -d
#+END_SRC
#+BEGIN_SRC dot :file hier-safety-2.svg :var txt=hier-safety-2 :exports results
@ -485,7 +486,7 @@ acceptance (i.e. =t=). You can interpret this output as a monitor
extended into valid ω-words).
#+NAME: hier-safety-1m
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
ltl2tgba -M '(a W Gb) M b' | autfilt --highlight-nondet -d
#+END_SRC
#+BEGIN_SRC dot :file hier-safety-1m.svg :var txt=hier-safety-1m :exports results
@ -496,7 +497,7 @@ ltl2tgba -M '(a W Gb) M b' | autfilt --highlight-nondet -d
[[file:hier-safety-1m.svg]]
#+NAME: hier-safety-2m
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
ltl2tgba -M -D '(a W Gb) M b' -d
#+END_SRC
#+BEGIN_SRC dot :file hier-safety-2m.svg :var txt=hier-safety-2m :exports results
@ -530,7 +531,7 @@ transition-based acceptance will often produce shorter automata.
The typical example is =GFa=, which can be translated into a 1-state
transition-based Büchi automaton:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltlfilt -f 'GFa' --format='%[v]h'
#+END_SRC
@ -538,7 +539,7 @@ ltlfilt -f 'GFa' --format='%[v]h'
: recurrence
#+NAME: hier-recurrence-1
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
ltl2tgba 'GFa' -d
#+END_SRC
#+BEGIN_SRC dot :file hier-recurrence-1.svg :var txt=hier-recurrence-1 :exports results
@ -551,7 +552,7 @@ $txt
Using state-based acceptance, at least two states are required. For instance:
#+NAME: hier-recurrence-2
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
ltl2tgba -S 'GFa' -d
#+END_SRC
#+BEGIN_SRC dot :file hier-recurrence-2.svg :var txt=hier-recurrence-2 :exports results
@ -565,7 +566,7 @@ $txt
Here is an example of a formula for which =ltl2tgba= does not produce a
deterministic automaton, even with =-D=.
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltlfilt -f 'G(Gb | Fa)' --format='%[v]h'
#+END_SRC
@ -573,7 +574,7 @@ ltlfilt -f 'G(Gb | Fa)' --format='%[v]h'
: recurrence
#+NAME: hier-recurrence-3
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
ltl2tgba -D 'G(Gb | Fa)' | autfilt --highlight-nondet -d
#+END_SRC
#+BEGIN_SRC dot :file hier-recurrence-3.svg :var txt=hier-recurrence-3 :exports results
@ -592,7 +593,7 @@ a /recurrence/ property), is to chain a few algorithms implemented in Spot:
acceptance is desired.
#+NAME: hier-recurrence-4
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
ltl2tgba -P -D 'G(Gb | Fa)' -d
#+END_SRC
#+BEGIN_SRC dot :file hier-recurrence-4.svg :var txt=hier-recurrence-4 :exports results
@ -607,7 +608,7 @@ a /recurrence/ property), is to chain a few algorithms implemented in Spot:
generalized Rabin.
#+NAME: hier-recurrence-5
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
ltl2tgba -P -D 'G(Gb | Fa)' |
autfilt --generalized-rabin -d
#+END_SRC
@ -649,7 +650,7 @@ a /recurrence/ property), is to chain a few algorithms implemented in Spot:
simply get a larger deterministic automaton).
#+NAME: hier-recurrence-7
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
ltl2tgba -P -D 'G(Gb | Fa)' |
autfilt -S --generalized-rabin |
autfilt -B -D -d
@ -668,7 +669,7 @@ passing =-S= to the first =autfilt= was optional, but in this case it
helps producing a smaller automaton. Here is what we get without it:
#+NAME: hier-recurrence-8
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
ltl2tgba -P -D 'G(Gb | Fa)' |
autfilt --generalized-rabin |
autfilt -B -D -d
@ -692,7 +693,7 @@ they cannot be represented by deterministic Büchi automata. The typical
persistence formula is =FGa=, and using =-D= on this is hopeless.
#+NAME: hier-persistence-1
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
ltl2tgba -D FGa -d
#+END_SRC
#+BEGIN_SRC dot :file hier-persistence-1.svg :var txt=hier-persistence-1 :exports results
@ -710,7 +711,7 @@ that =FGa= could be represented by a deterministic co-Büchi automaton.
complementation ourselves:
#+NAME: hier-persistence-2
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
ltlfilt --negate -f FGa |
ltl2tgba -D |
autfilt --complement -d
@ -746,7 +747,7 @@ automaton.
Let's do that on the persistence formula =F(G!a | G(b U a))=, just for
the fun of it.
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltlfilt -f 'F(G!a | G(b U a))' --format='%[v]h'
#+END_SRC
#+RESULTS:
@ -755,7 +756,7 @@ ltlfilt -f 'F(G!a | G(b U a))' --format='%[v]h'
Unfortunately the default output of the translation is not weak:
#+NAME: hier-persistence-3
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
ltl2tgba 'F(G!a | G(b U a))' -d
#+END_SRC
#+BEGIN_SRC dot :file hier-persistence-3.svg :var txt=hier-persistence-3 :exports results
@ -770,7 +771,7 @@ Büchi automaton for the complement, instead we get a non-deterministic
generalized Büchi automaton:
#+NAME: hier-persistence-4
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
ltlfilt --negate -f 'F(G!a | G(b U a))' |
ltl2tgba -D |
autfilt --highlight-nondet=5 -d
@ -787,7 +788,7 @@ determinizing this automaton into a Rabin automaton, and then back to
deterministic Büchi:
#+NAME: hier-persistence-5
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
ltlfilt --negate -f 'F(G!a | G(b U a))' |
ltl2tgba -P -D |
autfilt --generalized-rabin |
@ -804,7 +805,7 @@ This is a deterministic Büchi automaton for the negation of our formula.
Now we can complement it to obtain a deterministic co-Büchi automaton for =F(G!a | G(b U a))=:
#+NAME: hier-persistence-6
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
ltlfilt --negate -f 'F(G!a | G(b U a))' |
ltl2tgba -P -D |
autfilt --generalized-rabin |
@ -822,7 +823,7 @@ $txt
And finally we convert the result back to Büchi:
#+NAME: hier-persistence-7
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
ltlfilt --negate -f 'F(G!a | G(b U a))' |
ltl2tgba -P -D |
autfilt --generalized-rabin |

View file

@ -2,6 +2,7 @@
#+DESCRIPTION: Details about support of the HOA format in Spot
#+INCLUDE: setup.org
#+HTML_LINK_UP: tools.html
#+PROPERTY: header-args:sh :results verbatim :exports both
The [[http://adl.github.io/hoaf/][Hanoi Omega-Automa format]] is a textual representation of
@ -150,7 +151,7 @@ EOF
#+RESULTS:
#+BEGIN_SRC sh :results verbatim :exports results :wrap SRC hoa
#+BEGIN_SRC sh :exports results :wrap SRC hoa
sed -n '/--BODY/,/--END/p' stvstracc.hoa | grep -v -- --
#+END_SRC
@ -173,7 +174,7 @@ State: 2
will always be stored as a TωA with this transition structure:
#+BEGIN_SRC sh :results verbatim :exports results :wrap SRC hoa
#+BEGIN_SRC sh :exports results :wrap SRC hoa
autfilt -Ht stvstracc.hoa | sed -n '/--BODY/,/--END/p' | grep -v -- --
#+END_SRC
@ -208,7 +209,7 @@ For instance in the following automaton, the outgoing transitions of
each states belong to the same sets:
#+NAME: state-based-example
#+BEGIN_SRC sh :results verbatim :exports both :wrap SRC hoa
#+BEGIN_SRC sh :wrap SRC hoa
cat >sba.hoa <<EOF_HOA
HOA: v1
States: 3
@ -272,7 +273,7 @@ Nevertheless, should you really insist on having an output with
transition-based acceptance, you can do so by passing the option =t=
to the HOA printer:
#+BEGIN_SRC sh :results verbatim :exports both :wrap SRC hoa
#+BEGIN_SRC sh :wrap SRC hoa
autfilt -Ht sba.hoa
#+END_SRC
@ -305,7 +306,7 @@ format to prevents mixing the two: if you use =-Hm=, the decision of
using state or transition-based acceptance will be made for each state
separately. For instance:
#+BEGIN_SRC sh :results verbatim :exports both :wrap SRC hoa
#+BEGIN_SRC sh :wrap SRC hoa
ltl2tgba -Hm 'GFa | Fb'
#+END_SRC
@ -345,7 +346,7 @@ when necessary. Most tools have a =-S= option (or
=--state-based-acceptance=) for this purpose. Compare the following
output with the previous one.
#+BEGIN_SRC sh :results verbatim :exports both :wrap SRC hoa
#+BEGIN_SRC sh :wrap SRC hoa
ltl2tgba -S -Hm 'GFa | Fb'
#+END_SRC
@ -434,7 +435,7 @@ In the following example, you can see =autfilt= removing the duplicate
Rabin pair, and reordering the remaining pair to fit the syntax
corresponding to =Rabin 1=.
#+BEGIN_SRC sh :results verbatim :exports both :wrap SRC hoa
#+BEGIN_SRC sh :wrap SRC hoa
autfilt <<EOF
HOA: v1
States: 3
@ -501,7 +502,7 @@ When you look at an acceptance condition output by Spot, you can
actually spot the terms that have been grouped together internally by
looking at the spacing around operators =&= and =|=. For instance:
#+BEGIN_SRC sh :results verbatim :exports both :wrap SRC hoa
#+BEGIN_SRC sh :wrap SRC hoa
randaut -A"Fin(0)|Fin(1)|Fin(2)&Fin(3)&Inf(4)&Inf(5)" 0 | grep Acceptance:
#+END_SRC
@ -541,7 +542,7 @@ EOF
#+RESULTS:
#+BEGIN_SRC sh :results verbatim :exports results :wrap SRC hoa
#+BEGIN_SRC sh :exports results :wrap SRC hoa
sed -n '/--BODY/,/--END/p' stvstrlab.hoa | grep -v -- --
#+END_SRC
@ -559,7 +560,7 @@ will always be stored as an automaton with the following transition
structure
#+BEGIN_SRC sh :results verbatim :exports results :wrap SRC hoa
#+BEGIN_SRC sh :exports results :wrap SRC hoa
autfilt -Ht stvstrlab.hoa | sed -n '/--BODY/,/--END/p' | grep -v -- --
#+END_SRC
@ -701,7 +702,7 @@ There are currently two [[file:concepts.org::#named-properties][named properties
You can see these properties being preserved when an automaton is read and then immediately output:
#+NAME: hello-world
#+BEGIN_SRC sh :results verbatim :exports both :wrap SRC hoa
#+BEGIN_SRC sh :wrap SRC hoa
cat >hw.hoa <<EOF
HOA: v1
name: "hello world!"
@ -760,7 +761,7 @@ the old states and the new ones.
Here is for instance the result when =autfilt= is instructed to
simplify the automaton:
#+BEGIN_SRC sh :results verbatim :exports both :wrap SRC hoa
#+BEGIN_SRC sh :wrap SRC hoa
autfilt --small hw.hoa
#+END_SRC
@ -793,7 +794,7 @@ fixed via the =--name= option. For instance =--name=%M= will
construct the new name by simply copying the one of the original
automaton.
#+BEGIN_SRC sh :results verbatim :exports both :wrap SRC hoa
#+BEGIN_SRC sh :wrap SRC hoa
autfilt --small hw.hoa --name=%M
#+END_SRC
@ -838,7 +839,7 @@ in the HOA format, and then read those automata with =autfilt= to
randomize the order of their transitions and states before printing
them in HOA format.
#+BEGIN_SRC sh :results verbatim :exports both :wrap SRC hoa
#+BEGIN_SRC sh :wrap SRC hoa
genltl --and-gf=1..3 | ltl2tgba -B | autfilt --randomize
#+END_SRC
@ -972,7 +973,7 @@ HOA format. These are =spot.highlight.states= and
with colors.
#+NAME: decorate
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
cat >decorate.hoa <<EOF
HOA: v1.1
States: 3
@ -997,21 +998,23 @@ autfilt decorate.hoa -d'.#'
#+RESULTS: decorate
#+begin_example
digraph G {
digraph "" {
rankdir=LR
label=<t<br/>[all]>
labelloc="t"
node [shape="circle"]
node [style="filled", fillcolor="#ffffa0"]
fontname="Lato"
node [fontname="Lato"]
edge [fontname="Lato"]
edge[arrowhead=vee, arrowsize=.7]
node[fontsize=12] fontsize=12 stylesheet="spot.css" edge[arrowhead=vee, arrowsize=.7, fontsize=12]
I [label="", style=invis, width=0]
I -> 1
0 [label=<0>]
0 -> 0 [label=<1>, taillabel="#1", style=bold, color="#F17CB0"]
1 [label=<1>, style="bold,filled", color="#5DA5DA"]
1 -> 2 [label=<1>, taillabel="#2", style=bold, color="#FAA43A"]
2 [label=<2>, style="bold,filled", color="#B276B2"]
0 -> 0 [label=<1>, taillabel="#1", style=bold, color="#FF4DA0"]
1 [label=<1>, style="bold,filled", color="#1F78B4"]
1 -> 2 [label=<1>, taillabel="#2", style=bold, color="#FF7F00"]
2 [label=<2>, style="bold,filled", color="#6A3D9A"]
2 -> 0 [label=<b>, taillabel="#3"]
2 -> 2 [label=<a &amp; !b>, taillabel="#4"]
}
@ -1031,7 +1034,7 @@ headers ~spot.highlight.states:~ and ~spot.highlight.edges:~ are both
followed by a list of alternating state/edges numbers and color numbers.
So in the above file,
#+BEGIN_SRC sh :results verbatim :exports results :wrap SRC hoa
#+BEGIN_SRC sh :exports results :wrap SRC hoa
grep spot.highlight decorate.hoa
#+END_SRC
#+RESULTS:
@ -1058,7 +1061,7 @@ these lines when version 1.1 is selected.
Compare:
#+BEGIN_SRC sh :results verbatim :exports both :wrap SRC hoa
#+BEGIN_SRC sh :wrap SRC hoa
autfilt -H1 decorate.hoa; echo
autfilt -H1.1 decorate.hoa
#+END_SRC

View file

@ -3,6 +3,7 @@
#+DESCRIPTION: Options for input and output of temporal logic formulas in Spot's command-line tools
#+INCLUDE: setup.org
#+HTML_LINK_UP: tools.html
#+PROPERTY: header-args:sh :results verbatim :exports both
Spot supports different syntaxes for LTL/PSL formulas. This page
documents the options, common to all tools where it makes sense, that
@ -12,14 +13,14 @@ are used to specify input and output of formula.
All tools that read LTL/PSL formulas implement the following options:
#+BEGIN_SRC sh :results verbatim :exports results
#+BEGIN_SRC sh :exports results
ltl2tgba --help | sed -n '/Input options:/,/^$/p' | sed '1d;$d'
#+END_SRC
#+RESULTS:
: -f, --formula=STRING process the formula STRING
: -F, --file=FILENAME[/COL] process each line of FILENAME as a formula; if COL
: is a positive integer, assume a CSV file and read
: column COL; usea negative COL to drop the first
: column COL; use a negative COL to drop the first
: line of the CSV file
: --lbt-input read all formulas using LBT's prefix syntax
: --lenient parenthesized blocks that cannot be parsed as
@ -97,21 +98,18 @@ consider =a + b < 2= as an atomic proposition.
An unfortunate side-effect of =--lenient= parsing is that many syntax
errors will not be caught. Compare the following syntax error:
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :prologue "exec 2>&1" :epilogue true
ltlfilt -f '(a U b U) U c'
#+END_SRC
#+RESULTS:
#+BEGIN_SRC sh :results verbatim :exports results
(ltlfilt -f '(a U b U) U c' 2>&1 | cat) | sed '/^$/d'
#+END_SRC
#+RESULTS:
: >>> (a U b U) U c
: ^
: syntax error, unexpected closing parenthesis
:
: >>> (a U b U) U c
: ^
: missing right operand for "until operator"
:
With the same command in =--lenient= mode:
@ -146,7 +144,7 @@ used by [[http://www.ltl2dstar.de][ltl2dstar]].
All tools that output LTL/PSL formulas implement the following options:
#+BEGIN_SRC sh :results verbatim :exports results
#+BEGIN_SRC sh :exports results
genltl --help | sed -n '/Output options:/,/^$/p' | sed '1d;$d'
#+END_SRC
#+RESULTS:
@ -154,14 +152,18 @@ genltl --help | sed -n '/Output options:/,/^$/p' | sed '1d;$d'
-0, --zero-terminated-output separate output formulas with \0 instead of \n
(for use with xargs -0)
-8, --utf8 output using UTF-8 characters
--csv-escape quote the formula for use in a CSV file
--format=FORMAT specify how each line should be output (default:
--format=FORMAT, --stats=FORMAT
specify how each line should be output (default:
"%f")
-l, --lbt output in LBT's syntax
--latex output using LaTeX macros
--negative, --negated output the negated versions of all formulas
-o, --output=FORMAT send output to a file named FORMAT instead of
standard output. The first formula sent to a file
truncates it unless FORMAT starts with '>>'.
--positive output the positive versions of all formulas (done
by default, unless --negative is specified without
--positive)
-p, --full-parentheses output fully-parenthesized formulas
-s, --spin output in Spin's syntax
--spot output in Spot's syntax (default)
@ -218,7 +220,7 @@ the above =%=-sequences.
For instance the following invocation of [[file:randltl.org][=randltl=]] will create 5
random formulas, but in 5 different files:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
randltl -n5 a b -o example-%L.ltl
wc -l example-*.ltl
#+END_SRC
@ -241,7 +243,7 @@ in LTL formulas), but you can use =xargs -0= to split the input on
null characters. So for instance the following two invocations have
nearly the same output:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
genltl -0 --gh-q=1..4 | xargs -0 ltl2tgba --stats='%F,%f,%s'
genltl --gh-q=1..4 | ltl2tgba -F- --stats='%F,%f,%s'
#+END_SRC

View file

@ -3,6 +3,7 @@
#+DESCRIPTION: Spot command-line tool for translating LTL into Transition-based Generalized Büchi Automata.
#+INCLUDE: setup.org
#+HTML_LINK_UP: tools.html
#+PROPERTY: header-args:sh :results verbatim :exports both
This tool translates LTL or PSL formulas into different types of
automata.
@ -31,7 +32,7 @@ less frequent.)
Formulas to translate may be specified using [[file:ioltl.org][common input options for
LTL/PSL formulas]].
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltl2tgba -f 'Fa & GFb'
#+END_SRC
@ -69,7 +70,7 @@ can easily be piped to other tools.
To convert the automaton into a picture, or into vectorial format, use
=--dot= or =-d= to request [[http://www.graphviz.org/][GraphViz output]] and process the result with
=dot= or =dotty=. Typically, you could get a =pdf= of this TGBA using
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
ltl2tgba "Fa & GFb" -d | dot -Tpdf > tgba.pdf
#+END_SRC
#+RESULTS:
@ -78,7 +79,7 @@ The result would look like this (note that in this documentation
we use some [[file:oaut.org::#default-dot][environment variables]] to produce a more colorful
output by default)
#+NAME: dotex
#+BEGIN_SRC sh :results verbatim :exports none
#+BEGIN_SRC sh :exports none
ltl2tgba "Fa & GFb" -d
#+END_SRC
#+RESULTS: dotex
@ -123,7 +124,7 @@ Here is a TGBA with multiple acceptance sets (we omit the call to
=dot= to render the output of =ltl2tgba= from now on):
#+NAME: dotex2
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
ltl2tgba "GFa & GFb" -d
#+END_SRC
#+RESULTS: dotex2
@ -158,7 +159,7 @@ A Büchi automaton for the previous formula can be obtained with the
=-B= option:
#+NAME: dotex2ba
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
ltl2tgba -B 'GFa & GFb' -d
#+END_SRC
#+RESULTS: dotex2ba
@ -200,12 +201,12 @@ can see this underlying TGBA if you pass the =--dot=t= option (the =t=
requests the use of transition-based acceptance as it is done
internally):
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
ltl2tgba --dot=t -B 'GFa & GFb'
#+END_SRC
#+NAME: dotex2ba-t
#+BEGIN_SRC sh :results verbatim :exports none
#+BEGIN_SRC sh :exports none
ltl2tgba --dot=.t -B 'GFa & GFb'
#+END_SRC
@ -244,7 +245,7 @@ Büchi automata with state-based acceptance. Here is the same formula
as above, for comparison.
#+NAME: dotex2gba
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
ltl2tgba -S 'GFa & GFb' -d
#+END_SRC
@ -297,7 +298,7 @@ than the BA produced by =-B=.
As already discussed on the page about [[file:oaut.org][common output options]], various
options controls the output format of =ltl2tgba=:
#+BEGIN_SRC sh :results verbatim :exports results
#+BEGIN_SRC sh :exports results
ltl2tgba --help | sed -n '/Output format:/,/^$/p' | sed '1d;$d'
#+END_SRC
#+RESULTS:
@ -346,7 +347,7 @@ Option =-8= can be used to improve the readability of the output
if your system can display UTF-8 correctly.
#+NAME: dotex2ba8
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
ltl2tgba -B8 "GFa & GFb" -d
#+END_SRC
#+RESULTS: dotex2ba8
@ -386,7 +387,7 @@ Using the =--spin= or =-s= option, =ltl2tgba= will produce a Büchi automaton
=ltl2tgba -s= is therefore a drop-in replacement for =spin -f=.
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltl2tgba -s 'GFa & GFb'
#+END_SRC
#+RESULTS:
@ -416,14 +417,14 @@ Since Spin 6 extended its syntax to support arbitrary atomic
propositions, you may also need put the parser in =--lenient= mode to
support these:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltl2tgba -s --lenient '(a < b) U (process[2]@ok)'
#+END_SRC
#+RESULTS:
: never { /* "a < b" U "process[2]@ok" */
: T0_init:
: if
: :: ((process[2]@ok)) -> goto accept_all
: :: (process[2]@ok) -> goto accept_all
: :: ((a < b) && (!(process[2]@ok))) -> goto T0_init
: fi;
: accept_all:
@ -437,13 +438,15 @@ set of options specifies the goal of the simplification routines:
whenever possible, would you prefer a small automaton (=--small=) or a
deterministic (=--deterministic=) automaton?
#+BEGIN_SRC sh :results verbatim :exports results
#+BEGIN_SRC sh :exports results
ltl2tgba --help | sed -n '/Simplification goal:/,/^$/p' | sed '1d;$d'
#+END_SRC
#+RESULTS:
: -a, --any no preference, do not bother making it small or
: deterministic
: -D, --deterministic prefer deterministic automata
: -D, --deterministic prefer deterministic automata (combine with
: --generic to be sure to obtain a deterministic
: automaton)
: --small prefer small automata (default)
The =--any= option tells the translator that it should attempt to
@ -475,7 +478,7 @@ An example formula where the difference between =-D= and =--small= is
flagrant is =Ga|Gb|Gc=:
#+NAME: gagbgc1
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
ltl2tgba 'Ga|Gb|Gc' -d
#+END_SRC
#+RESULTS: gagbgc1
@ -509,7 +512,7 @@ $txt
[[file:gagbgc1.svg]]
#+NAME: gagbgc2
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
ltl2tgba -D 'Ga|Gb|Gc' -d
#+END_SRC
#+RESULTS: gagbgc2
@ -577,7 +580,7 @@ two ways to accept a run that repeats continuously the configuration
$\bar ab$.
#+NAME: ambig1
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
ltl2tgba -B 'GFa -> GFb' -d
#+END_SRC
#+RESULTS: ambig1
@ -616,7 +619,7 @@ Here is an unambiguous automaton for the same formula, in which there
is only one run that recognizes this example word:
#+NAME: ambig2
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
ltl2tgba -B -U 'GFa -> GFb' -d
#+END_SRC
@ -670,7 +673,7 @@ will be complete and unambiguous.
A last parameter that can be used to tune the translation is the amount
of pre- and post-processing performed. These two steps can be adjusted
via a common set of switches:
#+BEGIN_SRC sh :results verbatim :exports results
#+BEGIN_SRC sh :exports results
ltl2tgba --help | sed -n '/Simplification level:/,/^$/p' | sed '1d;$d'
#+END_SRC
#+RESULTS:
@ -740,7 +743,7 @@ expectations.
deterministic TGBA exists.
#+NAME: ltl2tgba-fga
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
ltl2tgba "FGa" -D -d
#+END_SRC
@ -754,7 +757,7 @@ ltl2tgba "FGa" -D -d
But with =--generic=, =ltl2tgba= will output the following co-Büchi automaton:
#+NAME: ltl2tgba-fga-D
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
ltl2tgba "FGa" -G -D -d
#+END_SRC
@ -770,7 +773,7 @@ If we translate =Fb|Gc= as a deterministic automaton with any
acceptance condition, we get a weak and deterministic Büchi automaton:
#+NAME: ltl2tgba-fbgc-D
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
ltl2tgba "Fb|Gc" -G -D -d
#+END_SRC
@ -786,7 +789,7 @@ Finally if we translate the conjunction of these two subformulas, a
product of these two automata will be made, producing:
#+NAME: ltl2tgba-fbgcfga-D
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
ltl2tgba "(Fb|Gc)&FGa" -G -D -d
#+END_SRC
@ -804,7 +807,7 @@ TGBA is non-deterministic, it will then be determinized into an
automaton with parity acceptance:
#+NAME: ltl2tgba-fbgcfga-nosplit-D
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
ltl2tgba "(Fb|Gc)&FGa" -G -D -xltl-split=0 -d
#+END_SRC
#+BEGIN_SRC dot :file ltl2tgba-fbgcfga-nosplit-D.svg :var txt=ltl2tgba-fbgcfga-nosplit-D :exports results
@ -823,7 +826,7 @@ purpose.
For instance the following deterministic automaton
#+NAME: ltl2tgba-det1
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
ltl2tgba "F(a W FGb)" -G -D -d
#+END_SRC
@ -837,7 +840,7 @@ ltl2tgba "F(a W FGb)" -G -D -d
would be larger if SCC-based optimizations were disabled:
#+NAME: ltl2tgba-det2
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
ltl2tgba "F(a W FGb)" -xdet-scc=0 -G -D -d
#+END_SRC
@ -882,7 +885,7 @@ For instance, =FGa= gets translated into an automaton with =Rabin 1=
acceptance (another name for =parity min odd 2=):
#+NAME: ltl2tgba-dp1
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
ltl2tgba "FGa" -D -P -d
#+END_SRC
@ -897,7 +900,7 @@ And =GFa & GFb= gets translated into a =Büchi= automaton (another name
for =parity min even 1=):
#+NAME: ltl2tgba-dp2
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
ltl2tgba "GFa & GFb" -D -P -d
#+END_SRC
@ -912,7 +915,7 @@ If we really want to use the same style of parity acceptance for all outputs,
we can specify it as an argument to the =--parity= option. For instance
#+NAME: ltl2tgba-dp3
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
ltl2tgba "GFa & GFb" -D -P'min odd' -d
#+END_SRC
@ -930,7 +933,7 @@ I.e., each transition (or state if state-based acceptance is
requested) should belong to exactly one acceptance set.
#+NAME: ltl2tgba-dp4
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
ltl2tgba "GFa & GFb" -D -p -d
#+END_SRC
@ -942,7 +945,7 @@ ltl2tgba "GFa & GFb" -D -p -d
[[file:ltl2tgba-dp4.svg]]
#+NAME: ltl2tgba-dp5
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
ltl2tgba "GFa & GFb" -D -p'min odd' -d
#+END_SRC
@ -957,7 +960,7 @@ Note that all these options can be combined with state-based
acceptance if needed:
#+NAME: ltl2tgba-dp6
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
ltl2tgba "GFa & GFb" -D -S -p'max even' -d
#+END_SRC
@ -983,7 +986,7 @@ automata themselves. The =FORMAT= string should indicate which
statistics should be output, and how they should be output using the
following sequence of characters (other characters are output as-is):
#+BEGIN_SRC sh :results verbatim :exports results
#+BEGIN_SRC sh :exports results
ltl2tgba --help | sed -n '/ sequences:/,/^$/p' | sed '1d;$d'
#+END_SRC
#+RESULTS:
@ -1042,7 +1045,7 @@ ltl2tgba --help | sed -n '/ sequences:/,/^$/p' | sed '1d;$d'
For instance we can study the size of the automata generated for the
right-nested =U= formulas as follows:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
genltl --u-right=1..8 | ltl2tgba --stats '%s states and %e edges for "%f"'
#+END_SRC
#+RESULTS:
@ -1093,7 +1096,7 @@ compatible outgoing transition exist.
deterministic monitor for the given formula.
#+NAME: monitor1
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
ltl2tgba -M '(Xa & Fb) | Gc' -d
#+END_SRC
@ -1128,7 +1131,7 @@ $txt
[[file:monitor1.svg]]
#+NAME: monitor2
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
ltl2tgba -MD '(Xa & Fb) | Gc' -d
#+END_SRC
@ -1155,7 +1158,7 @@ if) a sink state had to be added. For instance, here is the
"complete" version of the previous monitor.
#+NAME: monitor3
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
ltl2tgba -C -M -D '(Xa & Fb) | Gc' -d
#+END_SRC

View file

@ -3,6 +3,7 @@
#+DESCRIPTION: Spot command-line tool for translating LTL into Transition-based Generalized Testing Automata.
#+INCLUDE: setup.org
#+HTML_LINK_UP: tools.html
#+PROPERTY: header-args:sh :results verbatim :exports code
This tool generates various form of Testing Automata, i.e., automata
that observe the /changes/ of atomic propositions, not their values.
@ -18,39 +19,10 @@ Here is the output on =a U Gb= (we omit the call to =dot=, as shown while
discussing [[file:ltl2tgba.org][=ltl2tgba=]]).
#+NAME: augb-ta
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh
ltl2tgta --ta --multiple-init 'a U Gb'
#+END_SRC
#+RESULTS: augb-ta
#+begin_example
digraph G {
rankdir=LR
node [style="filled", fillcolor="#ffffa0"]
fontname="Lato"
node [fontname="Lato"]
edge [fontname="Lato"]
edge[arrowhead=vee, arrowsize=.7]
-1 [label="", style=invis, height=0]
-1 -> 1 [label="!a & b"]
-2 [label="", style=invis, height=0]
-2 -> 2 [label="a & !b"]
-3 [label="", style=invis, height=0]
-3 -> 3 [label="a & b"]
1 [label="2\n!a & b",shape=box]
1 -> 4 [label="{a}\n"]
2 [label="1\na & !b"]
2 -> 3 [label="{b}\n"]
2 -> 1 [label="{a, b}\n"]
3 [label="0\na & b",shape=box]
3 -> 4 [label="{a}\n"]
3 -> 1 [label="{a}\n"]
3 -> 2 [label="{b}\n"]
4 [label="3",peripheries=2,shape=box]
4 -> 4 [label="{a}\n{0}"]
}
#+end_example
#+BEGIN_SRC dot :file augb-ta.svg :var txt=augb-ta :exports results
$txt
#+END_SRC
@ -78,31 +50,9 @@ Without the =--multiple-init= option, a fake initial state is added.
This is the default since it often makes the result more readable.
#+NAME: augb-ta2
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh
ltl2tgta --ta 'a U Gb'
#+END_SRC
#+RESULTS:
#+begin_example
digraph G {
0 [label="", style=invis, height=0]
0 -> 1
1 [label=init]
1 -> 2 [label="!a & b\n"]
1 -> 3 [label="a & b\n"]
1 -> 4 [label="a & !b\n"]
2 [label="2",shape=box]
2 -> 5 [label="{a}\n"]
3 [label="3",shape=box]
3 -> 5 [label="{a}\n"]
3 -> 2 [label="{a}\n"]
3 -> 4 [label="{b}\n"]
4 [label="1"]
4 -> 3 [label="{b}\n"]
4 -> 2 [label="{a, b}\n"]
5 [label="4",peripheries=2,shape=box]
5 -> 5 [label="{a}\n{0}"]
}
#+end_example
#+BEGIN_SRC dot :file augb-ta2.svg :var txt=augb-ta2 :exports results
$txt
@ -117,37 +67,9 @@ Büchi accepting transitions are marked with the same ={0,1}=
notation used in TGBA.
#+NAME: gfagfb-gta
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh
ltl2tgta --gta 'GFa & GFb'
#+END_SRC
#+RESULTS:
#+begin_example
digraph G {
0 [label="", style=invis, height=0]
0 -> 1
1 [label=init]
1 -> 2 [label="a & b\n"]
1 -> 3 [label="!a & b\n"]
1 -> 4 [label="a & !b\n"]
1 -> 5 [label="!a & !b\n"]
2 [label="1",shape=box]
2 -> 3 [label="{a}\n{0,1}"]
2 -> 4 [label="{b}\n{0,1}"]
2 -> 5 [label="{a, b}\n{0,1}"]
3 [label="3"]
3 -> 2 [label="{a}\n{1}"]
3 -> 4 [label="{a, b}\n{1}"]
3 -> 5 [label="{b}\n{1}"]
4 [label="2"]
4 -> 2 [label="{b}\n{0}"]
4 -> 3 [label="{a, b}\n{0}"]
4 -> 5 [label="{a}\n{0}"]
5 [label="4"]
5 -> 2 [label="{a, b}\n"]
5 -> 3 [label="{b}\n"]
5 -> 4 [label="{a}\n"]
}
#+end_example
#+BEGIN_SRC dot :file gfagfb-gta.svg :var txt=gfagfb-gta :exports results
$txt
@ -167,41 +89,9 @@ made explicit with ={}= self-loops. Since these self-loop can be in
acceptance sets, livelock acceptance states are no longer needed.
#+NAME: gfagfb-tgta
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh
ltl2tgta 'GFa & GFb'
#+END_SRC
#+RESULTS:
#+begin_example
digraph G {
0 [label="", style=invis, height=0]
0 -> 1
1 [label=init]
1 -> 2 [label="a & b\n"]
1 -> 3 [label="!a & b\n"]
1 -> 4 [label="a & !b\n"]
1 -> 5 [label="!a & !b\n"]
2 [label="3"]
2 -> 3 [label="{a}\n{0,1}"]
2 -> 4 [label="{b}\n{0,1}"]
2 -> 5 [label="{a, b}\n{0,1}"]
2 -> 2 [label="{}\n{0,1}"]
3 [label="2"]
3 -> 2 [label="{a}\n{1}"]
3 -> 4 [label="{a, b}\n{1}"]
3 -> 5 [label="{b}\n{1}"]
3 -> 3 [label="{}\n"]
4 [label="4"]
4 -> 2 [label="{b}\n{0}"]
4 -> 3 [label="{a, b}\n{0}"]
4 -> 5 [label="{a}\n{0}"]
4 -> 4 [label="{}\n"]
5 [label="1"]
5 -> 2 [label="{a, b}\n"]
5 -> 3 [label="{b}\n"]
5 -> 4 [label="{a}\n"]
5 -> 5 [label="{}\n"]
}
#+end_example
#+BEGIN_SRC dot :file gfagfb-tgta.svg :var txt=gfagfb-tgta :exports results
$txt
@ -210,10 +100,12 @@ $txt
[[file:gfagfb-tgta.svg]]
[fn:topnoc]: This new class of automaton, as well as the
implementation of the previous testing automata classes, is part of
Ala Eddine BEN SALEM's PhD work, and should appear in a future edition
of ToPNoC (LNCS 7400).
[fn:topnoc]: This new class of automata, as well as the implementation
of the previous testing automata classes, is part of Ala Eddine BEN
SALEM's PhD work, and is discussed in [[https://www.lrde.epita.fr/~adl/dl/adl/bensalem.12.topnoc.pdf][*Model checking using
generalized testing automata*]], /Ala Eddine Ben Salem/, /Alexandre
Duret-Lutz/, and /Fabrice Kordon/, in Transactions on Petri Nets and
Other Models of Concurrency (ToPNoC VI), LNCS 7400, p. 94--112, 2012.
# LocalWords: ltl tgta num toc Automata automata GraphViz UTF Gb na

View file

@ -3,6 +3,8 @@
#+DESCRIPTION: Spot command-line tool for cross-comparing the output of LTL translators.
#+INCLUDE: setup.org
#+HTML_LINK_UP: tools.html
#+PROPERTY: header-args:sh :results verbatim :exports both
#+PROPERTY: header-args:R :session :results output :exports both
=ltlcross= is a tool for cross-comparing the output of LTL-to-automata
translators. It is actually a Spot-based clone of [[http://www.tcs.hut.fi/Software/lbtt/][LBTT]], the
@ -58,7 +60,7 @@ and no =-f= or =-F= options are given.
Each translator should be specified as a string that use some of the
following character sequences:
#+BEGIN_SRC sh :results verbatim :exports results
#+BEGIN_SRC sh :exports results
ltlcross --help | sed -n '/character sequences:/,/^$/p' | sed '1d;$d'
#+END_SRC
#+RESULTS:
@ -73,7 +75,7 @@ following character sequences:
For instance here is how we could cross-compare the never claims
output by =spin= and =ltl2tgba= for the formulas =GFa= and =X(a U b)=.
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
ltlcross -f 'GFa' -f 'X(a U b)' 'ltl2tgba -s %s >%O' 'spin -f %s >%O'
#+END_SRC
#+RESULTS:
@ -83,7 +85,7 @@ by the formula in Spin's syntax, and =%O= will be replaced by a
temporary file into which the output of the translator is redirected
before it is read back by =ltlcross=.
#+BEGIN_SRC sh :results verbatim :exports results
#+BEGIN_SRC sh :exports results
ltlcross -f 'GFa' -f 'X(a U b)' 'ltl2tgba -s %s >%O' 'spin -f %s >%O' 2>&1
#+END_SRC
#+RESULTS:
@ -174,7 +176,7 @@ To simplify the use of some of the above tools, a set of predefined
shorthands are available. Those can be listed with the
=--list-shorthands= option.
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltlcross --list-shorthands
#+END_SRC
#+RESULTS:
@ -182,24 +184,28 @@ ltlcross --list-shorthands
If a COMMANDFMT does not use any %-sequence, and starts with one of
the following words, then the string on the right is appended.
delag %f>%O
lbt <%L>%O
ltl2ba -f %s>%O
ltl2da %f>%O
ltl2dgra %f>%O
ltl2dpa %f>%O
ltl2dra %f>%O
ltl2ldba %f>%O
ltl2dstar --output-format=hoa %[MW]L %O
ltl2tgba -H %f>%O
ltl3ba -f %s>%O
ltl3dra -f %s>%O
ltl3hoa -f %f>%O
ltl3tela -f %f>%O
modella %[MWei^]L %O
spin -f %s>%O
Any {name} and directory component is skipped for the purpose of
matching those prefixes. So for instance
'{DRA} ~/mytools/ltl2dstar-0.5.2'
will changed into
'{DRA} ~/mytools/ltl2dstar-0.5.2 --output-format=hoa %[MR]L %O'
will be changed into
'{DRA} ~/mytools/ltl2dstar-0.5.2 --output-format=hoa %[MW]L %O'
#+end_example
What this implies is that running =ltlcross ltl2ba ltl3ba ...= is
@ -381,67 +387,45 @@ randltl -n 3 a b | ltlfilt --remove-wm |
ltlcross --csv=results.csv --json=results.json \
'ltl2tgba -s %f >%O' \
'spin -f %s >%O' \
'lbt < %L >%O' --csv=results.csv 2>&1
'lbt < %L >%O' 2>&1
#+END_SRC
#+RESULTS:
#+begin_example
-:1: 0
Running [P0]: ltl2tgba -s '0' >'lcr-o0-HIoc9n'
Running [P1]: spin -f 'false' >'lcr-o1-69Gi3B'
Running [P2]: lbt < 'lcr-i0-cYhaYP' >'lcr-o2-CZe2S3'
Running [N0]: ltl2tgba -s '1' >'lcr-o0-9YEpOh'
Running [N1]: spin -f 'true' >'lcr-o1-exCCOv'
Running [N2]: lbt < 'lcr-i0-DMSnRJ' >'lcr-o2-E0H9TX'
Performing sanity checks and gathering statistics...
-:2: !((1) U (F(!(p0))))
Running [P0]: ltl2tgba -s '!((1) U (F(!(p0))))' >'lcr-o0-ubhgZb'
Running [P1]: spin -f '!((true) U (<>(!(p0))))' >'lcr-o1-wBnwcq'
Running [P2]: lbt < 'lcr-i1-D3WcqE' >'lcr-o2-i3VTDS'
Running [N0]: ltl2tgba -s '(1) U (F(!(p0)))' >'lcr-o0-8F2eS6'
Running [N1]: spin -f '(true) U (<>(!(p0)))' >'lcr-o1-focrcl'
Running [N2]: lbt < 'lcr-i1-VgW9wz' >'lcr-o2-GbdTRN'
Performing sanity checks and gathering statistics...
-:3: (1) U ((G(p0)) | (F(p1)))
Running [P0]: ltl2tgba -s '(1) U ((G(p0)) | (F(p1)))' >'lcr-o0-jj8Ih2'
Running [P1]: spin -f '(true) U (([](p0)) || (<>(p1)))' >'lcr-o1-JarYMg'
Running [P2]: lbt < 'lcr-i2-yq4yiv' >'lcr-o2-Lw29NJ'
Running [N0]: ltl2tgba -s '!((1) U ((G(p0)) | (F(p1))))' >'lcr-o0-mHp6jY'
Running [N1]: spin -f '!((true) U (([](p0)) || (<>(p1))))' >'lcr-o1-pA7KVc'
Running [N2]: lbt < 'lcr-i2-ZxXHBr' >'lcr-o2-YadFhG'
Performing sanity checks and gathering statistics...
No problem detected.
#+end_example
After this execution, the file =results.csv= contains the following:
#+BEGIN_SRC sh :results verbatim :exports results
cat results.csv
#+BEGIN_SRC sh :results output raw :exports results
sed 's/"//g
s/|/\\vert{}/g
s/--/@@html:--@@/g
1a\
|-|
s/^/| /
s/$/ |/
s/,/|/g
' results.csv
#+END_SRC
#+ATTR_HTML: :class csv-table
#+RESULTS:
#+begin_example
"formula","tool","exit_status","exit_code","time","states","edges","transitions","acc","scc","nondet_states","nondet_aut","complete_aut","product_states","product_transitions","product_scc"
"0","ltl2tgba -s %f >%O","ok",0,0.0299298,1,1,0,1,1,0,0,0,1,0,1
"0","spin -f %s >%O","ok",0,0.00396246,2,2,1,1,2,0,0,0,1,0,1
"0","lbt < %L >%O","ok",0,0.00262385,1,0,0,0,1,0,0,0,1,0,1
"1","ltl2tgba -s %f >%O","ok",0,0.0261614,1,1,1,1,1,0,0,1,200,4199,1
"1","spin -f %s >%O","ok",0,0.0137128,2,2,2,1,2,0,0,1,201,4220,2
"1","lbt < %L >%O","ok",0,0.00792516,3,3,3,0,3,0,0,1,222,4653,23
"!((1) U (F(!(p0))))","ltl2tgba -s %f >%O","ok",0,0.043858,1,1,1,1,1,0,0,0,200,2059,1
"!((1) U (F(!(p0))))","spin -f %s >%O","ok",0,0.00202537,1,1,1,1,1,0,0,0,200,2059,1
"!((1) U (F(!(p0))))","lbt < %L >%O","ok",0,0.00331618,2,2,2,0,2,0,0,0,201,2071,2
"(1) U (F(!(p0)))","ltl2tgba -s %f >%O","ok",0,0.031689,2,3,4,1,2,0,0,1,400,8264,2
"(1) U (F(!(p0)))","spin -f %s >%O","ok",0,0.0026263,2,3,5,1,2,1,1,1,400,10337,2
"(1) U (F(!(p0)))","lbt < %L >%O","ok",0,0.00266354,7,13,22,2,7,4,1,1,1201,35191,604
"(1) U ((G(p0)) | (F(p1)))","ltl2tgba -s %f >%O","ok",0,0.0287222,3,5,11,1,3,1,1,0,600,11358,3
"(1) U ((G(p0)) | (F(p1)))","spin -f %s >%O","ok",0,0.00167423,4,8,24,1,4,2,1,0,800,24920,4
"(1) U ((G(p0)) | (F(p1)))","lbt < %L >%O","ok",0,0.0016987,9,17,52,2,9,4,1,0,1601,41559,805
"!((1) U ((G(p0)) | (F(p1))))","ltl2tgba -s %f >%O","ok",0,0.0308937,2,4,4,1,1,0,0,0,395,3964,1
"!((1) U ((G(p0)) | (F(p1))))","spin -f %s >%O","ok",0,0.0230605,6,18,17,1,4,5,1,0,592,8891,1
"!((1) U ((G(p0)) | (F(p1))))","lbt < %L >%O","ok",0,0.00280787,3,6,9,1,2,3,1,0,397,5957,2
#+end_example
| formula | tool | exit_status | exit_code | time | states | edges | transitions | acc | scc | nondet_states | nondet_aut | complete_aut | product_states | product_transitions | product_scc |
|-------------------------------+--------------------+-------------+-----------+------------+--------+-------+-------------+-----+-----+---------------+------------+--------------+----------------+---------------------+-------------|
| 0 | ltl2tgba -s %f >%O | ok | 0 | 0.0269145 | 1 | 1 | 0 | 1 | 1 | 0 | 0 | 0 | 1 | 0 | 1 |
| 0 | spin -f %s >%O | ok | 0 | 0.00112819 | 2 | 2 | 1 | 1 | 2 | 0 | 0 | 0 | 1 | 0 | 1 |
| 0 | lbt < %L >%O | ok | 0 | 0.00228413 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 1 |
| 1 | ltl2tgba -s %f >%O | ok | 0 | 0.0269548 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | 200 | 4199 | 1 |
| 1 | spin -f %s >%O | ok | 0 | 0.00121962 | 2 | 2 | 2 | 1 | 2 | 0 | 0 | 1 | 201 | 4220 | 2 |
| 1 | lbt < %L >%O | ok | 0 | 0.00206923 | 3 | 3 | 3 | 0 | 3 | 0 | 0 | 1 | 222 | 4653 | 23 |
| !(F(!(p0))) | ltl2tgba -s %f >%O | ok | 0 | 0.0293213 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 200 | 2059 | 1 |
| !(F(!(p0))) | spin -f %s >%O | ok | 0 | 0.00114213 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 200 | 2059 | 1 |
| !(F(!(p0))) | lbt < %L >%O | ok | 0 | 0.00281165 | 2 | 2 | 2 | 0 | 2 | 0 | 0 | 0 | 201 | 2071 | 2 |
| F(!(p0)) | ltl2tgba -s %f >%O | ok | 0 | 0.0273697 | 2 | 3 | 4 | 1 | 2 | 0 | 0 | 1 | 400 | 8264 | 2 |
| F(!(p0)) | spin -f %s >%O | ok | 0 | 0.00110435 | 2 | 3 | 5 | 1 | 2 | 1 | 1 | 1 | 400 | 10337 | 2 |
| F(!(p0)) | lbt < %L >%O | ok | 0 | 0.00205025 | 4 | 6 | 10 | 1 | 4 | 2 | 1 | 1 | 601 | 14497 | 203 |
| F((G(p0)) \vert{} (F(p1))) | ltl2tgba -s %f >%O | ok | 0 | 0.0283784 | 3 | 5 | 11 | 1 | 3 | 1 | 1 | 0 | 600 | 11358 | 3 |
| F((G(p0)) \vert{} (F(p1))) | spin -f %s >%O | ok | 0 | 0.00144813 | 4 | 8 | 24 | 1 | 4 | 2 | 1 | 0 | 800 | 24920 | 4 |
| F((G(p0)) \vert{} (F(p1))) | lbt < %L >%O | ok | 0 | 0.00218541 | 9 | 17 | 52 | 2 | 9 | 4 | 1 | 0 | 1601 | 41559 | 805 |
| !(F((G(p0)) \vert{} (F(p1)))) | ltl2tgba -s %f >%O | ok | 0 | 0.026898 | 2 | 4 | 4 | 1 | 1 | 0 | 0 | 0 | 395 | 3964 | 1 |
| !(F((G(p0)) \vert{} (F(p1)))) | spin -f %s >%O | ok | 0 | 0.00365003 | 2 | 3 | 5 | 1 | 1 | 1 | 1 | 0 | 396 | 4964 | 1 |
| !(F((G(p0)) \vert{} (F(p1)))) | lbt < %L >%O | ok | 0 | 0.00184477 | 3 | 6 | 9 | 1 | 2 | 3 | 1 | 0 | 397 | 5957 | 2 |
This file can be loaded in any spreadsheet or statistical application.
@ -453,11 +437,11 @@ If we had used the option =--json=results.json= instead of (or in
addition to) =--cvs=results.csv=, the file =results.json= would have
contained the following [[http://www.json.org/][JSON]] output.
#+BEGIN_SRC sh :results verbatim :exports results
#+BEGIN_SRC sh :exports results :wrap SRC json
cat results.json
#+END_SRC
#+RESULTS:
#+begin_example
#+begin_SRC json
{
"tool": [
"ltl2tgba -s %f >%O",
@ -467,37 +451,37 @@ cat results.json
"formula": [
"0",
"1",
"!((1) U (F(!(p0))))",
"(1) U (F(!(p0)))",
"(1) U ((G(p0)) | (F(p1)))",
"!((1) U ((G(p0)) | (F(p1))))"
"!(F(!(p0)))",
"F(!(p0))",
"F((G(p0)) | (F(p1)))",
"!(F((G(p0)) | (F(p1))))"
],
"fields": [
"formula","tool","exit_status","exit_code","time","states","edges","transitions","acc","scc","nondet_states","nondet_aut","complete_aut","product_states","product_transitions","product_scc"
],
"inputs": [ 0, 1 ],
"results": [
[ 0,0,"ok",0,0.0299298,1,1,0,1,1,0,0,0,1,0,1 ],
[ 0,1,"ok",0,0.00396246,2,2,1,1,2,0,0,0,1,0,1 ],
[ 0,2,"ok",0,0.00262385,1,0,0,0,1,0,0,0,1,0,1 ],
[ 1,0,"ok",0,0.0261614,1,1,1,1,1,0,0,1,200,4199,1 ],
[ 1,1,"ok",0,0.0137128,2,2,2,1,2,0,0,1,201,4220,2 ],
[ 1,2,"ok",0,0.00792516,3,3,3,0,3,0,0,1,222,4653,23 ],
[ 2,0,"ok",0,0.043858,1,1,1,1,1,0,0,0,200,2059,1 ],
[ 2,1,"ok",0,0.00202537,1,1,1,1,1,0,0,0,200,2059,1 ],
[ 2,2,"ok",0,0.00331618,2,2,2,0,2,0,0,0,201,2071,2 ],
[ 3,0,"ok",0,0.031689,2,3,4,1,2,0,0,1,400,8264,2 ],
[ 3,1,"ok",0,0.0026263,2,3,5,1,2,1,1,1,400,10337,2 ],
[ 3,2,"ok",0,0.00266354,7,13,22,2,7,4,1,1,1201,35191,604 ],
[ 4,0,"ok",0,0.0287222,3,5,11,1,3,1,1,0,600,11358,3 ],
[ 4,1,"ok",0,0.00167423,4,8,24,1,4,2,1,0,800,24920,4 ],
[ 4,2,"ok",0,0.0016987,9,17,52,2,9,4,1,0,1601,41559,805 ],
[ 5,0,"ok",0,0.0308937,2,4,4,1,1,0,0,0,395,3964,1 ],
[ 5,1,"ok",0,0.0230605,6,18,17,1,4,5,1,0,592,8891,1 ],
[ 5,2,"ok",0,0.00280787,3,6,9,1,2,3,1,0,397,5957,2 ]
[ 0,0,"ok",0,0.0137672,1,1,0,1,1,0,0,0,1,0,1 ],
[ 0,1,"ok",0,0.000908285,2,2,1,1,2,0,0,0,1,0,1 ],
[ 0,2,"ok",0,0.00133153,1,0,0,0,1,0,0,0,1,0,1 ],
[ 1,0,"ok",0,0.0135283,1,1,1,1,1,0,0,1,200,4199,1 ],
[ 1,1,"ok",0,0.000828822,2,2,2,1,2,0,0,1,201,4220,2 ],
[ 1,2,"ok",0,0.00134064,3,3,3,0,3,0,0,1,222,4653,23 ],
[ 2,0,"ok",0,0.0140072,1,1,1,1,1,0,0,0,200,2059,1 ],
[ 2,1,"ok",0,0.00081293,1,1,1,1,1,0,0,0,200,2059,1 ],
[ 2,2,"ok",0,0.00134737,2,2,2,0,2,0,0,0,201,2071,2 ],
[ 3,0,"ok",0,0.0137064,2,3,4,1,2,0,0,1,400,8264,2 ],
[ 3,1,"ok",0,0.000911401,2,3,5,1,2,1,1,1,400,10337,2 ],
[ 3,2,"ok",0,0.00130378,4,6,10,1,4,2,1,1,601,14497,203 ],
[ 4,0,"ok",0,0.0144879,3,5,11,1,3,1,1,0,600,11358,3 ],
[ 4,1,"ok",0,0.00103421,4,8,24,1,4,2,1,0,800,24920,4 ],
[ 4,2,"ok",0,0.0013883,9,17,52,2,9,4,1,0,1601,41559,805 ],
[ 5,0,"ok",0,0.0142669,2,4,4,1,1,0,0,0,395,3964,1 ],
[ 5,1,"ok",0,0.00240013,2,3,5,1,1,1,1,0,396,4964,1 ],
[ 5,2,"ok",0,0.00134713,3,6,9,1,2,3,1,0,397,5957,2 ]
]
}
#+end_example
#+end_SRC
Here the =fields= table describes the columns of the =results= table.
The =inputs= tables lists the columns that are considered as inputs
@ -535,8 +519,8 @@ for i in range(0, len(data["tool"])):
#+RESULTS:
: tool & count & time & states & edges & transitions & acc & scc & nondet_states & nondet_aut & complete_aut & product_states & product_transitions & product_scc \\
: ltl2tgba -s %f >%O & 6 & 0.0 & 1.7 & 2.5 & 3.5 & 1.0 & 1.5 & 0.2 & 0.2 & 0.3 & 299.3 & 4974.0 & 1.5 \\
: spin -f %s >%O & 6 & 0.0 & 2.8 & 5.7 & 8.3 & 1.0 & 2.5 & 1.3 & 0.5 & 0.3 & 365.7 & 8404.5 & 1.8 \\
: lbt < %L >%O & 6 & 0.0 & 4.2 & 6.8 & 14.7 & 0.8 & 4.0 & 1.8 & 0.5 & 0.3 & 603.8 & 14905.2 & 239.5 \\
: spin -f %s >%O & 6 & 0.0 & 2.2 & 3.2 & 6.3 & 1.0 & 2.0 & 0.7 & 0.5 & 0.3 & 333.0 & 7750.0 & 1.8 \\
: lbt < %L >%O & 6 & 0.0 & 3.7 & 5.7 & 12.7 & 0.7 & 3.5 & 1.5 & 0.5 & 0.3 & 503.8 & 11456.2 & 172.7 \\
The script =bench/ltl2tgba/sum.py= is a more evolved version of the
above script that generates two kinds of LaTeX tables.
@ -589,43 +573,14 @@ sets. When building (degeneralized) Büchi automata, it will always be
=1=, so its value is meaningful only when evaluating translations to
generalized Büchi automata. =edges= counts the actual number of edges
in the graph supporting the automaton; an edge (labeled by a Boolean
formula) might actually represent several transitions (each labeled by
formula) [[file:concepts.org::#trans-edge][might actually represent several transitions]] (each labeled by
assignment of all atomic propositions). For instance in an automaton
where the atomic proposition are $a$ and $b$, one edge labeled by
$a\lor b$ actually represents three transitions $a b$, $a\bar b$, and
$\bar a b$.
The following picture displays two automata for the LTL formula =a U
b=. They both have 2 states and 3 edges, however they differ in the
number of transitions (7 versus 8), because the initial self-loop is
more constrained in the first automaton. A smaller number of
transition is therefore an indication of a more constrained automaton.
#+BEGIN_SRC dot :file edges.svg :exports results
digraph G {
0 [label="", style=invis, height=0]
0 -> 1
1 [label="A1"]
1 -> 2 [label="b\n"]
1 -> 1 [label="a & !b\n"]
2 [label="B1", peripheries=2]
2 -> 2 [label="1"]
3 [label="", style=invis, height=0]
3 -> 4
4 [label="A2"]
4 -> 5 [label="b\n"]
4 -> 4 [label="a\n"]
5 [label="B2", peripheries=2]
5 -> 5 [label="1"]
}
#+END_SRC
#+RESULTS:
[[file:edges.svg]]
=scc= counts the number of strongly-connected components in the automaton.
=scc= counts the number of strongly-connected components in the
automaton.
If option =--strength= is passed to =ltlcross=, these SCCs are
also partitioned on four sets based on their strengths:
@ -713,19 +668,38 @@ For instance in the following, =ltl2tgba= is run in two
configurations, and the strings =ltl2tgba -s --small %f >%O= and
=ltl2tgba -s --deter %f >%O= appear verbatim in the output:
#+BEGIN_SRC sh :results verbatim :exports both
#+NAME: ltlcross-unnamed
#+BEGIN_SRC sh :exports code
ltlcross -f a -f Ga 'ltl2tgba -s --small %f >%O' 'ltl2tgba -s --deter %f >%O' --csv
#+END_SRC
#+BEGIN_SRC sh :results output raw :exports results :noweb yes
sed 's/"//g
s/|/\\vert{}/g
s/--/@@html:--@@/g
s/^/| /
s/$/ |/
s/,/|/g
$d
1a\
|-|
' <<EOF
<<ltlcross-unnamed()>>
EOF
#+END_SRC
#+ATTR_HTML: :class csv-table
#+RESULTS:
: "formula","tool","exit_status","exit_code","time","states","edges","transitions","acc","scc","nondet_states","nondet_aut","complete_aut","product_states","product_transitions","product_scc"
: "a","ltl2tgba -s --small %f >%O","ok",0,0.0129968,2,2,3,1,2,0,0,0,201,4144,2
: "a","ltl2tgba -s --deter %f >%O","ok",0,0.0116347,2,2,3,1,2,0,0,0,201,4144,2
: "!(a)","ltl2tgba -s --small %f >%O","ok",0,0.0127019,2,2,3,1,2,0,0,0,201,4149,2
: "!(a)","ltl2tgba -s --deter %f >%O","ok",0,0.0117374,2,2,3,1,2,0,0,0,201,4149,2
: "G(a)","ltl2tgba -s --small %f >%O","ok",0,0.0126186,1,1,1,1,1,0,0,0,200,2059,1
: "G(a)","ltl2tgba -s --deter %f >%O","ok",0,0.011645,1,1,1,1,1,0,0,0,200,2059,1
: "!(G(a))","ltl2tgba -s --small %f >%O","ok",0,0.0129519,2,3,4,1,2,0,0,1,400,8264,2
: "!(G(a))","ltl2tgba -s --deter %f >%O","ok",0,0.0129941,2,3,4,1,2,0,0,1,400,8264,2
| formula | tool | exit_status | exit_code | time | states | edges | transitions | acc | scc | nondet_states | nondet_aut | complete_aut | product_states | product_transitions | product_scc |
|---------+-------------------------------------+-------------+-----------+-----------+--------+-------+-------------+-----+-----+---------------+------------+--------------+----------------+---------------------+-------------|
| a | ltl2tgba -s @@html:--@@small %f >%O | ok | 0 | 0.045425 | 2 | 2 | 3 | 1 | 2 | 0 | 0 | 0 | 201 | 4144 | 2 |
| a | ltl2tgba -s @@html:--@@deter %f >%O | ok | 0 | 0.0452103 | 2 | 2 | 3 | 1 | 2 | 0 | 0 | 0 | 201 | 4144 | 2 |
| !(a) | ltl2tgba -s @@html:--@@small %f >%O | ok | 0 | 0.0475807 | 2 | 2 | 3 | 1 | 2 | 0 | 0 | 0 | 201 | 4149 | 2 |
| !(a) | ltl2tgba -s @@html:--@@deter %f >%O | ok | 0 | 0.0441754 | 2 | 2 | 3 | 1 | 2 | 0 | 0 | 0 | 201 | 4149 | 2 |
| G(a) | ltl2tgba -s @@html:--@@small %f >%O | ok | 0 | 0.0453961 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 200 | 2059 | 1 |
| G(a) | ltl2tgba -s @@html:--@@deter %f >%O | ok | 0 | 0.0467509 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 200 | 2059 | 1 |
| !(G(a)) | ltl2tgba -s @@html:--@@small %f >%O | ok | 0 | 0.0459274 | 2 | 3 | 4 | 1 | 2 | 0 | 0 | 1 | 400 | 8264 | 2 |
| !(G(a)) | ltl2tgba -s @@html:--@@deter %f >%O | ok | 0 | 0.04534 | 2 | 3 | 4 | 1 | 2 | 0 | 0 | 1 | 400 | 8264 | 2 |
To present these results graphically, or even when analyzing these
data, it might be convenient to give each configured tool a shorter
@ -733,37 +707,50 @@ name. =ltlcross= supports the specification of such short names by
looking whether the command specification for a translator has the
form "={short name}actual command=".
For instance:
#+BEGIN_SRC sh :results verbatim :exports both
For instance, after
#+BEGIN_SRC sh :exports code
genltl --and-f=1..5 |
ltlcross '{small} ltl2tgba -s --small %f >%O' \
'{deter} ltl2tgba -s --deter %f >%O' --csv=ltlcross.csv
cat ltlcross.csv
#+END_SRC
The file =ltlcross.csv= now contains:
#+BEGIN_SRC sh :results output raw :exports results
sed 's/"//g
s/|/\\vert{}/g
s/--/@@html:--@@/g
s/^/| /
s/$/ |/
s/,/|/g
$d
1a\
|-|
' ltlcross.csv
#+END_SRC
#+ATTR_HTML: :class csv-table
#+RESULTS:
#+begin_example
"formula","tool","exit_status","exit_code","time","states","edges","transitions","acc","scc","nondet_states","nondet_aut","complete_aut","product_states","product_transitions","product_scc"
"F(p1)","small","ok",0,0.0138108,2,3,4,1,2,0,0,1,400,8272,3
"F(p1)","deter","ok",0,0.0142178,2,3,4,1,2,0,0,1,400,8272,3
"!(F(p1))","small","ok",0,0.013972,1,1,1,1,1,0,0,0,200,2055,2
"!(F(p1))","deter","ok",0,0.0139471,1,1,1,1,1,0,0,0,200,2055,2
"(F(p1)) & (F(p2))","small","ok",0,0.0136648,4,9,16,1,4,0,0,1,798,16533,5
"(F(p1)) & (F(p2))","deter","ok",0,0.0140229,4,9,16,1,4,0,0,1,798,16533,5
"!((F(p1)) & (F(p2)))","small","ok",0,0.0144659,3,5,7,1,3,0,0,0,598,7367,4
"!((F(p1)) & (F(p2)))","deter","ok",0,0.0143098,3,5,7,1,3,0,0,0,598,7367,4
"(F(p1)) & (F(p2)) & (F(p3))","small","ok",0,0.0142109,8,27,64,1,8,0,0,1,1587,33068,34
"(F(p1)) & (F(p2)) & (F(p3))","deter","ok",0,0.0149064,8,27,64,1,8,0,0,1,1587,33068,34
"!((F(p1)) & (F(p2)) & (F(p3)))","small","ok",0,0.0159551,4,6,24,1,4,1,1,0,601,6171,4
"!((F(p1)) & (F(p2)) & (F(p3)))","deter","ok",0,0.0143288,7,19,37,1,7,0,0,0,1387,18792,33
"(F(p1)) & (F(p2)) & (F(p3)) & (F(p4))","small","ok",0,0.0152539,16,81,256,1,16,0,0,1,2727,57786,74
"(F(p1)) & (F(p2)) & (F(p3)) & (F(p4))","deter","ok",0,0.0155381,16,81,256,1,16,0,0,1,2727,57786,74
"!((F(p1)) & (F(p2)) & (F(p3)) & (F(p4)))","small","ok",0,0.015231,5,8,64,1,5,1,1,0,801,8468,5
"!((F(p1)) & (F(p2)) & (F(p3)) & (F(p4)))","deter","ok",0,0.0157937,15,65,175,1,15,0,0,0,2527,37226,73
"(F(p1)) & (F(p2)) & (F(p3)) & (F(p4)) & (F(p5))","small","ok",0,0.017919,32,243,1024,1,32,0,0,1,5330,114068,350
"(F(p1)) & (F(p2)) & (F(p3)) & (F(p4)) & (F(p5))","deter","ok",0,0.0167644,32,243,1024,1,32,0,0,1,5330,114068,350
"!((F(p1)) & (F(p2)) & (F(p3)) & (F(p4)) & (F(p5)))","small","ok",0,0.0187427,6,10,160,1,6,1,1,0,1000,10707,6
"!((F(p1)) & (F(p2)) & (F(p3)) & (F(p4)) & (F(p5)))","deter","ok",0,0.0183562,31,211,781,1,31,0,0,0,5130,82897,349
#+end_example
| formula | tool | exit_status | exit_code | time | states | edges | transitions | acc | scc | nondet_states | nondet_aut | complete_aut | product_states | product_transitions | product_scc |
|----------------------------------------------------+-------+-------------+-----------+-----------+--------+-------+-------------+-----+-----+---------------+------------+--------------+----------------+---------------------+-------------|
| F(p1) | small | ok | 0 | 0.0143077 | 2 | 3 | 4 | 1 | 2 | 0 | 0 | 1 | 400 | 8272 | 3 |
| F(p1) | deter | ok | 0 | 0.0143547 | 2 | 3 | 4 | 1 | 2 | 0 | 0 | 1 | 400 | 8272 | 3 |
| !(F(p1)) | small | ok | 0 | 0.0146721 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 200 | 2055 | 2 |
| !(F(p1)) | deter | ok | 0 | 0.0145825 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 200 | 2055 | 2 |
| (F(p1)) & (F(p2)) | small | ok | 0 | 0.0147275 | 4 | 9 | 16 | 1 | 4 | 0 | 0 | 1 | 798 | 16533 | 5 |
| (F(p1)) & (F(p2)) | deter | ok | 0 | 0.0144936 | 4 | 9 | 16 | 1 | 4 | 0 | 0 | 1 | 798 | 16533 | 5 |
| !((F(p1)) & (F(p2))) | small | ok | 0 | 0.0147704 | 3 | 5 | 7 | 1 | 3 | 0 | 0 | 0 | 598 | 7367 | 4 |
| !((F(p1)) & (F(p2))) | deter | ok | 0 | 0.0146198 | 3 | 5 | 7 | 1 | 3 | 0 | 0 | 0 | 598 | 7367 | 4 |
| (F(p1)) & (F(p2)) & (F(p3)) | small | ok | 0 | 0.0153116 | 8 | 27 | 64 | 1 | 8 | 0 | 0 | 1 | 1587 | 33068 | 34 |
| (F(p1)) & (F(p2)) & (F(p3)) | deter | ok | 0 | 0.0156095 | 8 | 27 | 64 | 1 | 8 | 0 | 0 | 1 | 1587 | 33068 | 34 |
| !((F(p1)) & (F(p2)) & (F(p3))) | small | ok | 0 | 0.015041 | 4 | 6 | 24 | 1 | 4 | 1 | 1 | 0 | 601 | 6171 | 4 |
| !((F(p1)) & (F(p2)) & (F(p3))) | deter | ok | 0 | 0.0151199 | 7 | 19 | 37 | 1 | 7 | 0 | 0 | 0 | 1387 | 18792 | 33 |
| (F(p1)) & (F(p2)) & (F(p3)) & (F(p4)) | small | ok | 0 | 0.0166691 | 16 | 81 | 256 | 1 | 16 | 0 | 0 | 1 | 2727 | 57786 | 74 |
| (F(p1)) & (F(p2)) & (F(p3)) & (F(p4)) | deter | ok | 0 | 0.0161634 | 16 | 81 | 256 | 1 | 16 | 0 | 0 | 1 | 2727 | 57786 | 74 |
| !((F(p1)) & (F(p2)) & (F(p3)) & (F(p4))) | small | ok | 0 | 0.0167047 | 5 | 8 | 64 | 1 | 5 | 1 | 1 | 0 | 801 | 8468 | 5 |
| !((F(p1)) & (F(p2)) & (F(p3)) & (F(p4))) | deter | ok | 0 | 0.0160785 | 15 | 65 | 175 | 1 | 15 | 0 | 0 | 0 | 2527 | 37226 | 73 |
| (F(p1)) & (F(p2)) & (F(p3)) & (F(p4)) & (F(p5)) | small | ok | 0 | 0.018485 | 32 | 243 | 1024 | 1 | 32 | 0 | 0 | 1 | 5330 | 114068 | 350 |
| (F(p1)) & (F(p2)) & (F(p3)) & (F(p4)) & (F(p5)) | deter | ok | 0 | 0.0209914 | 32 | 243 | 1024 | 1 | 32 | 0 | 0 | 1 | 5330 | 114068 | 350 |
| !((F(p1)) & (F(p2)) & (F(p3)) & (F(p4)) & (F(p5))) | small | ok | 0 | 0.0196063 | 6 | 10 | 160 | 1 | 6 | 1 | 1 | 0 | 1000 | 10707 | 6 |
In this last example, we saved the CSV output to =ltlcross.csv= so we
can play with it in the next section.
@ -773,19 +760,21 @@ can play with it in the next section.
The produced CSV should be directly readable by R's CSV input functions like
=read.csv()=, =readr::read_csv()=, or =data.table::fread()=.
#+BEGIN_SRC R :session :results output :exports both
#+BEGIN_SRC R
library(data.table)
dt <- fread('ltlcross.csv')
str(dt)
#+END_SRC
#+RESULTS:
#+begin_example
data.table 1.12.0 Latest news: r-datatable.com
Classes data.table and 'data.frame': 20 obs. of 16 variables:
$ formula : chr "F(p1)" "F(p1)" "!(F(p1))" "!(F(p1))" ...
$ tool : chr "small" "deter" "small" "deter" ...
$ exit_status : chr "ok" "ok" "ok" "ok" ...
$ exit_code : int 0 0 0 0 0 0 0 0 0 0 ...
$ time : num 0.0133 0.0133 0.0139 0.0128 0.0144 ...
$ time : num 0.0284 0.0283 0.0283 0.0282 0.029 ...
$ states : int 2 2 1 1 4 4 3 3 8 8 ...
$ edges : int 3 3 1 1 9 9 5 5 27 27 ...
$ transitions : int 4 4 1 1 16 16 7 7 64 64 ...
@ -808,21 +797,22 @@ A common transformation is to group the results of all tools on the
same line: using exactly one line per formula. This is easily
achieved using =dcast()= from the =data.table= library.
#+BEGIN_SRC R :session :results output :exports both
#+BEGIN_SRC R
dt2 <- dcast(dt, formula ~ tool, value.var=names(dt)[-(1:2)], sep=".")
str(dt2)
#+END_SRC
#+RESULTS:
#+begin_example
Classes data.table and 'data.frame': 10 obs. of 29 variables:
$ formula : chr "!((F(p1)) & (F(p2)) & (F(p3)) & (F(p4)) & (F(p5)))" "!((F(p1)) & (F(p2)) & (F(p3)) & (F(p4)))" "!((F(p1)) & (F(p2)) & (F(p3)))" "!((F(p1)) & (F(p2)))" ...
$ exit_status.deter : chr "ok" "ok" "ok" "ok" ...
$ exit_status.small : chr "ok" "ok" "ok" "ok" ...
$ exit_code.deter : int 0 0 0 0 0 0 0 0 0 0
$ exit_code.small : int 0 0 0 0 0 0 0 0 0 0
$ time.deter : num 0.0174 0.0149 0.0141 0.0136 0.0128 ...
$ time.small : num 0.0171 0.0155 0.0152 0.0146 0.0139 ...
$ time.deter : num 0.0172 0.0212 0.02 0.0191 0.0282 ...
$ time.small : num 0.0172 0.0221 0.0203 0.0195 0.0283 ...
$ states.deter : int 31 15 7 3 1 4 8 16 32 2
$ states.small : int 6 5 4 3 1 4 8 16 32 2
$ edges.deter : int 211 65 19 5 1 9 27 81 243 3
@ -855,7 +845,7 @@ compare the number of states produced by the two configurations of
=ltl2tgba= for each formula, we just need to plot column
=dt2$state.small= against =dt2$state.deter=.
#+BEGIN_SRC R :session :results output graphics :width 5 :height 5 :file ltlcross-r.svg :exports both
#+BEGIN_SRC R :results output graphics :width 5 :height 5 :file ltlcross-r.svg
library(ggplot2)
ggplot(dt2, aes(x=states.small, y=states.deter)) +
geom_abline(colour='white') + geom_point()
@ -868,10 +858,10 @@ ggplot(dt2, aes(x=states.small, y=states.deter)) +
We should probably print the formulas for the cases where the two
sizes differ.
#+BEGIN_SRC R :session :results output graphics :width 5 :height 5 :file ltlcross-r2.svg :exports both
#+BEGIN_SRC R :results output graphics :width 5 :height 5 :file ltlcross-r2.svg
ggplot(dt2, aes(x=states.small, y=states.deter)) +
geom_abline(colour='white') + geom_point() +
geom_text(data=subset(df2, states.small != states.deter),
geom_text(data=subset(dt2, states.small != states.deter),
aes(label=formula), hjust=0, nudge_x=.5)
#+END_SRC
@ -942,52 +932,47 @@ If =--save-bogus=OTHERFILENAME= is provided, every bogus formula found
during the process will be saved in =OTHERFILENAME=.
Example:
#+BEGIN_SRC sh :exports code :results verbatim
#+BEGIN_SRC sh :prologue "exec 2>&1" :epilogue true
ltlcross -f '(G!b & (!c | F!a)) | (c & Ga & Fb)' "modella %L %O" \
--save-bogus=bogus \
--grind=bogus-grind
#+END_SRC
#+BEGIN_SRC sh :exports results :results verbatim
ltlcross -f '(G!b & (!c | F!a)) | (c & Ga & Fb)' "modella %L %O" \
--save-bogus=bogus --grind=bogus-grind 2>&1
true
#+END_SRC
#+RESULTS:
#+begin_example
| & G ! p0 | ! p1 F ! p2 & & p1 G p2 F p0
Running [P0]: modella 'lcr-i0-FUPmeY' 'lcr-o0-F3bZRp'
Running [N0]: modella 'lcr-i0-ebjQwR' 'lcr-o0-20eIbj'
Running [P0]: modella 'lcr-i0-Nc8B1P' 'lcr-o0-CDjvYF'
Running [N0]: modella 'lcr-i0-Io4LVv' 'lcr-o0-C482Sl'
Performing sanity checks and gathering statistics...
error: P0*N0 is nonempty; both automata accept the infinite word:
cycle{!p0 & !p1}
Trying to find a bogus mutation of (G!b & (!c | F!a)) | (c & Ga & Fb)...
Mutation 1/22: & & p0 G p1 F p2
Running [P0]: modella 'lcr-i1-zXEyXK' 'lcr-o0-RsypJc'
Running [N0]: modella 'lcr-i1-Ux7xvE' 'lcr-o0-x19Gh6'
Running [P0]: modella 'lcr-i1-EmhjSb' 'lcr-o0-q1GzR1'
Running [N0]: modella 'lcr-i1-mwR1QR' 'lcr-o0-gEcuQH'
Performing sanity checks and gathering statistics...
Mutation 2/22: & G ! p0 | ! p1 F ! p2
Running [P0]: modella 'lcr-i2-syS74x' 'lcr-o0-wPRySZ'
Running [N0]: modella 'lcr-i2-x9DdGr' 'lcr-o0-fgHStT'
Running [P0]: modella 'lcr-i2-4UoNQx' 'lcr-o0-W9W6Qn'
Running [N0]: modella 'lcr-i2-h5IDRd' 'lcr-o0-VDFaS3'
Performing sanity checks and gathering statistics...
Mutation 3/22: | G ! p0 & & p1 G p2 F p0
Running [P0]: modella 'lcr-i3-rVOAil' 'lcr-o0-jU2i7M'
Running [N0]: modella 'lcr-i3-KATfWe' 'lcr-o0-2UOcLG'
Running [P0]: modella 'lcr-i3-bkvvTT' 'lcr-o0-wMAQUJ'
Running [N0]: modella 'lcr-i3-qoYoWz' 'lcr-o0-ILwXXp'
Performing sanity checks and gathering statistics...
error: P0*N0 is nonempty; both automata accept the infinite word:
cycle{!p0 & !p1}
Trying to find a bogus mutation of G!b | (c & Ga & Fb)...
Mutation 1/16: t
Running [P0]: modella 'lcr-i4-OJk2B8' 'lcr-o0-VVCSsA'
Running [N0]: modella 'lcr-i4-nKwTj2' 'lcr-o0-npMUau'
Running [P0]: modella 'lcr-i4-avS30f' 'lcr-o0-MYCa45'
Running [N0]: modella 'lcr-i4-vJss7V' 'lcr-o0-ItCKaM'
Performing sanity checks and gathering statistics...
Mutation 2/16: G ! p0
Running [P0]: modella 'lcr-i5-Waoe2V' 'lcr-o0-9wsyTn'
Running [N0]: modella 'lcr-i5-M0R2KP' 'lcr-o0-uhmxCh'
Running [P0]: modella 'lcr-i5-TG7leC' 'lcr-o0-N6UXhs'
Running [N0]: modella 'lcr-i5-KwJJli' 'lcr-o0-kbRvp8'
Performing sanity checks and gathering statistics...
Mutation 3/16: & & p0 G p1 F p2
@ -995,8 +980,8 @@ warning: This formula or its negation has already been checked.
Use --allow-dups if it should not be ignored.
Mutation 4/16: | G ! p0 & p1 F p0
Running [P0]: modella 'lcr-i6-OtIGuJ' 'lcr-o0-qBEQmb'
Running [N0]: modella 'lcr-i6-MGbcfD' 'lcr-o0-t93x74'
Running [P0]: modella 'lcr-i6-otaRtY' 'lcr-o0-bRLcyO'
Running [N0]: modella 'lcr-i6-3DMJCE' 'lcr-o0-v04gHu'
Performing sanity checks and gathering statistics...
error: P0*N0 is nonempty; both automata accept the infinite word:
cycle{!p0 & !p1}
@ -1011,38 +996,38 @@ warning: This formula or its negation has already been checked.
Use --allow-dups if it should not be ignored.
Mutation 3/10: & p0 F p1
Running [P0]: modella 'lcr-i7-4oa00w' 'lcr-o0-3IEsUY'
Running [N0]: modella 'lcr-i7-vyy5Nq' 'lcr-o0-nXOIHS'
Running [P0]: modella 'lcr-i7-gKcHMk' 'lcr-o0-UPD7Ra'
Running [N0]: modella 'lcr-i7-4HUKX0' 'lcr-o0-Dpno3Q'
Performing sanity checks and gathering statistics...
Mutation 4/10: | p0 G ! p1
Running [P0]: modella 'lcr-i8-Kt48Bk' 'lcr-o0-xeIzwM'
Running [N0]: modella 'lcr-i8-ye5are' 'lcr-o0-3QMMlG'
Running [P0]: modella 'lcr-i8-H6GH9G' 'lcr-o0-xyO1fx'
Running [N0]: modella 'lcr-i8-w3vxmn' 'lcr-o0-wgw3sd'
Performing sanity checks and gathering statistics...
Mutation 5/10: | G ! p0 F p0
Running [P0]: modella 'lcr-i9-Bpmah8' 'lcr-o0-38lycA'
Running [N0]: modella 'lcr-i9-cQJ771' 'lcr-o0-yUcH3t'
Running [P0]: modella 'lcr-i9-vt8eA3' 'lcr-o0-982qHT'
Running [N0]: modella 'lcr-i9-qrbNOJ' 'lcr-o0-ceD9Vz'
Performing sanity checks and gathering statistics...
Mutation 6/10: | ! p0 & p1 F p0
Running [P0]: modella 'lcr-i10-mYtDZV' 'lcr-o0-nCdAVn'
Running [N0]: modella 'lcr-i10-d1fIRP' 'lcr-o0-oAsQNh'
Running [P0]: modella 'lcr-i10-6upQ3p' 'lcr-o0-EStxbg'
Running [N0]: modella 'lcr-i10-7nUoj6' 'lcr-o0-e4DgrW'
Performing sanity checks and gathering statistics...
Mutation 7/10: | & p1 F p0 G p0
Running [P0]: modella 'lcr-i11-petsKJ' 'lcr-o0-Z3U4Gb'
Running [N0]: modella 'lcr-i11-bmFSDD' 'lcr-o0-P1DGA5'
Running [P0]: modella 'lcr-i11-ohXyzM' 'lcr-o0-bozRHC'
Running [N0]: modella 'lcr-i11-6wYkQs' 'lcr-o0-TCxOYi'
Performing sanity checks and gathering statistics...
Mutation 8/10: | & p0 p1 G ! p0
Running [P0]: modella 'lcr-i12-eUjByx' 'lcr-o0-DZAwwZ'
Running [N0]: modella 'lcr-i12-v3JCur' 'lcr-o0-IzWIsT'
Running [P0]: modella 'lcr-i12-51Vd88' 'lcr-o0-uWKDhZ'
Running [N0]: modella 'lcr-i12-0OkfrP' 'lcr-o0-aEdRAF'
Performing sanity checks and gathering statistics...
Mutation 9/10: | G ! p0 & p0 F p0
Running [P0]: modella 'lcr-i13-Sb2Arl' 'lcr-o0-kBwtqN'
Running [N0]: modella 'lcr-i13-Tctwpf' 'lcr-o0-hvIzoH'
Running [P0]: modella 'lcr-i13-vy57Kv' 'lcr-o0-lcfpVl'
Running [N0]: modella 'lcr-i13-D7SQ5b' 'lcr-o0-k8Hig2'
Performing sanity checks and gathering statistics...
error: P0*N0 is nonempty; both automata accept the infinite word:
cycle{!p0}
@ -1057,13 +1042,13 @@ warning: This formula or its negation has already been checked.
Use --allow-dups if it should not be ignored.
Mutation 3/7: & p0 F p0
Running [P0]: modella 'lcr-i14-iDAoo9' 'lcr-o0-6vSdoB'
Running [N0]: modella 'lcr-i14-WMIdo3' 'lcr-o0-NxEdov'
Running [P0]: modella 'lcr-i14-AvSorS' 'lcr-o0-AZkvCI'
Running [N0]: modella 'lcr-i14-Hd7LNy' 'lcr-o0-pM82Yo'
Performing sanity checks and gathering statistics...
Mutation 4/7: | p0 G ! p0
Running [P0]: modella 'lcr-i15-lS5FoX' 'lcr-o0-XFX8op'
Running [N0]: modella 'lcr-i15-8IdNpR' 'lcr-o0-0Bxrqj'
Running [P0]: modella 'lcr-i15-tygKaf' 'lcr-o0-YHFrm5'
Running [N0]: modella 'lcr-i15-GL9iyV' 'lcr-o0-riOaKL'
Performing sanity checks and gathering statistics...
Mutation 5/7: | G ! p0 F p0
@ -1071,13 +1056,13 @@ warning: This formula or its negation has already been checked.
Use --allow-dups if it should not be ignored.
Mutation 6/7: | ! p0 & p0 F p0
Running [P0]: modella 'lcr-i16-7boQrL' 'lcr-o0-wsIftd'
Running [N0]: modella 'lcr-i16-tk8OuF' 'lcr-o0-9wQow7'
Running [P0]: modella 'lcr-i16-M0RHWB' 'lcr-o0-iVlf9r'
Running [N0]: modella 'lcr-i16-WD4Xli' 'lcr-o0-Ez6Gy8'
Performing sanity checks and gathering statistics...
Mutation 7/7: | G p0 & p0 F p0
Running [P0]: modella 'lcr-i17-wnlkyz' 'lcr-o0-MAjgA1'
Running [N0]: modella 'lcr-i17-qFLnCt' 'lcr-o0-45gvEV'
Running [P0]: modella 'lcr-i17-F1BLLY' 'lcr-o0-Z9nQYO'
Running [N0]: modella 'lcr-i17-efo5bF' 'lcr-o0-fFzkpv'
Performing sanity checks and gathering statistics...
Smallest bogus mutation found for (G!b & (!c | F!a)) | (c & Ga & Fb) is G!c | (c & Fc).
@ -1086,7 +1071,7 @@ error: some error was detected during the above runs.
Check file bogus for problematic formulas.
#+end_example
#+BEGIN_SRC sh :exports both :results verbatim
#+BEGIN_SRC sh
cat bogus
#+END_SRC
@ -1096,7 +1081,7 @@ cat bogus
: G!b | (c & Fb)
: G!c | (c & Fc)
#+BEGIN_SRC sh :exports both :results verbatim
#+BEGIN_SRC sh
cat bogus-grind
#+END_SRC
@ -1112,15 +1097,6 @@ When checks are enabled, the negated formulas are intermixed with the
positives ones in the results. Therefore the =--no-check= option can
be used to gather statistics about a specific set of formulas.
# LocalWords: ltlcross num toc LTL Büchi LBTT Testbench PSL SRC sed
# LocalWords: automata LBT LBTT's ltl tgba GFa lck iDGV sA FYp BYY
# LocalWords: ClVQg wyErP UNE dQ coM tH eHPoQy goto ba lbt modella
# LocalWords: lbtt csv json randltl ltlfilt wm eGEYaZ nYpFBX fGdZQ
# LocalWords: CPs kXiZZS ILLzR wU CcMCaQ IOckzW tsT RZ TJXmT jb XRO
# LocalWords: nxqfd hS vNItGg acc scc nondetstates nondeterministic
# LocalWords: cvs LaTeX datacols len ith otimes ltlcheck eval setq
# LocalWords: setenv concat getenv
** =--verbose=
:PROPERTIES:
:CUSTOM_ID: verbose
@ -1134,21 +1110,17 @@ and =ltl3ba -H1= on the formula =FGa=. Note that =ltl2tgba= will
produce transition-based generalized Büchi automata, while =ltl3ba
-H1= produces co-Büchi alternating automata.
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :prologue "export SPOT_HOA_TOLERANT=1; exec 2>&1"
ltlcross -f 'FGa' ltl2tgba 'ltl3ba -H1' --determinize --verbose
#+END_SRC
#+BEGIN_SRC sh :results verbatim :exports results
SPOT_HOA_TOLERANT=1 ltlcross -f 'FGa' ltl2tgba 'ltl3ba -H1' --determinize --verbose 2>&1
#+END_SRC
#+RESULTS:
#+begin_example
F(G(a))
Running [P0]: ltl2tgba -H 'F(G(a))'>'lcr-o0-opbyhq'
Running [P1]: ltl3ba -H1 -f '<>([](a))'>'lcr-o1-aP47sS'
Running [N0]: ltl2tgba -H '!(F(G(a)))'>'lcr-o0-UV1eFk'
Running [N1]: ltl3ba -H1 -f '!(<>([](a)))'>'lcr-o1-bFSrTM'
Running [P0]: ltl2tgba -H 'F(G(a))'>'lcr-o0-cNwEjy'
Running [P1]: ltl3ba -H1 -f '<>([](a))'>'lcr-o1-WQo28q'
Running [N0]: ltl2tgba -H '!(F(G(a)))'>'lcr-o0-KT96Zj'
Running [N1]: ltl3ba -H1 -f '!(<>([](a)))'>'lcr-o1-WE1RXc'
info: collected automata:
info: P0 (2 st.,3 ed.,1 sets)
info: N0 (1 st.,2 ed.,1 sets) deterministic complete
@ -1214,21 +1186,17 @@ that the automaton =N0= is really the complement of =P0=. Similarly
Note that if we had not used the =--determinize= option, the procedure
would look slightly more complex:
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :prologue "export SPOT_HOA_TOLERANT=1; exec 2>&1"
ltlcross -f 'FGa' ltl2tgba 'ltl3ba -H1' --verbose
#+END_SRC
#+BEGIN_SRC sh :results verbatim :exports results
SPOT_HOA_TOLERANT=1 ltlcross -f 'FGa' ltl2tgba 'ltl3ba -H1' --verbose 2>&1
#+END_SRC
#+RESULTS:
#+begin_example
F(G(a))
Running [P0]: ltl2tgba -H 'F(G(a))'>'lcr-o0-cq9s5c'
Running [P1]: ltl3ba -H1 -f '<>([](a))'>'lcr-o1-Fb0iii'
Running [N0]: ltl2tgba -H '!(F(G(a)))'>'lcr-o0-X5dGvn'
Running [N1]: ltl3ba -H1 -f '!(<>([](a)))'>'lcr-o1-tLO5Ks'
Running [P0]: ltl2tgba -H 'F(G(a))'>'lcr-o0-Ot1KDa'
Running [P1]: ltl3ba -H1 -f '<>([](a))'>'lcr-o1-Kvzdfm'
Running [N0]: ltl2tgba -H '!(F(G(a)))'>'lcr-o0-X2dURx'
Running [N1]: ltl3ba -H1 -f '!(<>([](a)))'>'lcr-o1-wuLpzJ'
info: collected automata:
info: P0 (2 st.,3 ed.,1 sets)
info: N0 (1 st.,2 ed.,1 sets) deterministic complete
@ -1288,21 +1256,17 @@ implementation that should not be checked, and we just want to check
the output of =ltl2tgba= against this reference. See how the number
of tests performed has been reduced.
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :prologue "export SPOT_HOA_TOLERANT=1; exec 2>&1"
ltlcross -f 'FGa' ltl2tgba --reference 'ltl3ba -H1' --verbose
#+END_SRC
#+BEGIN_SRC sh :results verbatim :exports results
SPOT_HOA_TOLERANT=1 ltlcross -f 'FGa' ltl2tgba --reference 'ltl3ba -H1' --verbose 2>&1
#+END_SRC
#+RESULTS:
#+begin_example
F(G(a))
Running [P0]: ltl3ba -H1 -f '<>([](a))'>'lcr-o0-UanRv9'
Running [P1]: ltl2tgba -H 'F(G(a))'>'lcr-o1-43jbVn'
Running [N0]: ltl3ba -H1 -f '!(<>([](a)))'>'lcr-o0-TUeymC'
Running [N1]: ltl2tgba -H '!(F(G(a)))'>'lcr-o1-5PYsOQ'
Running [P0]: ltl3ba -H1 -f '<>([](a))'>'lcr-o0-hsnlkV'
Running [P1]: ltl2tgba -H 'F(G(a))'>'lcr-o1-R0jOmP'
Running [N0]: ltl3ba -H1 -f '!(<>([](a)))'>'lcr-o0-7GwxvJ'
Running [N1]: ltl2tgba -H '!(F(G(a)))'>'lcr-o1-5sgPFD'
info: collected automata:
info: P0 (2 st.,3 ed.,1 sets)
info: N0 (3 st.,5 ed.,1 sets) univ-edges complete
@ -1339,3 +1303,16 @@ info: consistency_check (P1,N1), state-space #0/1
No problem detected.
#+end_example
#+BEGIN_SRC sh :results silent :exports results
rm -f results.csv results.json ltlcross.csv bogus-grind bogus
#+END_SRC
# LocalWords: ltlcross num toc LTL Büchi LBTT Testbench PSL SRC sed
# LocalWords: automata LBT LBTT's ltl tgba GFa lck iDGV sA FYp BYY
# LocalWords: ClVQg wyErP UNE dQ coM tH eHPoQy goto ba lbt modella
# LocalWords: lbtt csv json randltl ltlfilt wm eGEYaZ nYpFBX fGdZQ
# LocalWords: CPs kXiZZS ILLzR wU CcMCaQ IOckzW tsT RZ TJXmT jb XRO
# LocalWords: nxqfd hS vNItGg acc scc nondetstates nondeterministic
# LocalWords: cvs LaTeX datacols len ith otimes ltlcheck eval setq
# LocalWords: setenv concat getenv

View file

@ -3,6 +3,7 @@
#+DESCRIPTION: Spot's wrapper for third-party LTL translators
#+INCLUDE: setup.org
#+HTML_LINK_UP: tools.html
#+PROPERTY: header-args:sh :results verbatim :exports both
This tool is a wrapper for tools that read LTL/PSL formulas and
(optionally) output automata.
@ -26,7 +27,7 @@ Büchi automaton produced by =ltl3ba=.
Here is the input file:
#+BEGIN_SRC sh :results silent :exports both
#+BEGIN_SRC sh :results silent
cat >sample.ltl <<EOF
1
1 U a
@ -58,7 +59,7 @@ is to pipe the output of =ltl3ba= through [[file:autfilt.org][=autfilt=]].
Here is how the shell command could look like:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltlfilt -F sample.ltl -s |
while read f; do
ltl3ba -f "$f" | autfilt --stats="$f,%s,%t"
@ -81,7 +82,7 @@ X[]!<>((a && ![]b) || (!a && []b)),4,10
Using =ltldo= the above command can be reduced to this:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltldo 'ltl3ba -f %s>%O' -F sample.ltl --stats='%f,%s,%t'
#+END_SRC
#+RESULTS:
@ -106,7 +107,7 @@ In fact, as we will discuss below, =ltl3ba= is a tool that =ltldo=
already knows about, so there is a shorter way to run the above
command:
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
ltldo ltl3ba -F sample.ltl --stats='%f,%s,%t'
#+END_SRC
#+RESULTS:
@ -129,8 +130,8 @@ Here is another example, where we use Spin to produce two automata in
the [[http://adl.github.io/hoaf/][HOA format]]. Spin has no support for HOA, but =ltldo= simply
converts the never claim produced by =spin= into this format.
#+BEGIN_SRC sh :results verbatim :exports both :wrap SRC hoa
ltldo -f a -f GFa 'spin -f %s>%O'
#+BEGIN_SRC sh :wrap SRC hoa
ltldo 'spin -f %s>%O' -f a -f GFa
#+END_SRC
#+RESULTS:
@ -177,7 +178,7 @@ simplified to just this:
The syntax for specifying how a tool should be called is the same as
in [[file:ltlcross.org][=ltlcross=]]. Namely, the following sequences are available.
#+BEGIN_SRC sh :results verbatim :exports results
#+BEGIN_SRC sh :exports results
ltldo --help | sed -n '/character sequences:/,/^$/p' | sed '1d;$d'
#+END_SRC
@ -195,7 +196,7 @@ filename using one of the sequence for that last line. For instance
we could simply run a formula though =echo= to compare different
output syntaxes:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltldo -f 'p0 U p1' -f 'GFp0' 'echo %f, %s, %l, %w'
#+END_SRC
#+RESULTS:
@ -211,7 +212,7 @@ executed on each formula in the same order.
A typical use-case is to compare statistics of different tools:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltldo -F sample.ltl 'spin -f %s>%O' 'ltl3ba -f %s>%O' --stats=%T,%f,%s,%e
#+END_SRC
@ -248,7 +249,7 @@ In the following example, we moved the formula used on its own line
using the trick that the command =echo %f= will not be subject to
=--stats= (since it does not declare any output automaton).
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltldo -F sample.ltl --stats=%T,%s,%e \
'echo "#" %f' '{spin}spin -f %s>%O' '{ltl3ba}ltl3ba -f %s>%O'
#+END_SRC
@ -299,7 +300,7 @@ There is a list of existing tools for which =ltldo= (and =ltlcross=)
have built-in specifications. This list can be printed using the
=--list-shorthands= option:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltldo --list-shorthands
#+END_SRC
#+RESULTS:
@ -327,22 +328,18 @@ will changed into
'{DRA} ~/mytools/ltl2dstar-0.5.2 --output-format=hoa %[MR]L %O'
#+end_example
Therefore you can type just
Therefore you can type the following to obtain a Dot output (as
requested with =-d=) for the neverclaim produced by =ltl2ba -f a=.
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :prologue export SPOT_DOTEXTRA= SPOT_DOTDEFAULT=
ltldo ltl2ba -f a -d
#+END_SRC
to obtain a Dot output (as requested with =-d=) for the neverclaim
produced by =ltl2ba -f a=.
#+BEGIN_SRC sh :results verbatim :exports results
SPOT_DOTEXTRA= ltldo ltl2ba -f a --dot=
#+END_SRC
#+RESULTS:
#+begin_example
digraph G {
digraph "" {
rankdir=LR
label="\n[Büchi]"
labelloc="t"
node [shape="circle"]
I [label="", style=invis, width=0]
I -> 0
@ -356,14 +353,13 @@ digraph G {
The =ltl2ba= argument passed to =ltldo= was interpreted as if you had
typed ={ltl2ba}ltl2ba -f %s>%O=.
The shorthand is only used if it is the first word of an command
The shorthand is only used if it is the first word of a command
string that does not use any =%= character. This makes it possible to
add options:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltldo ltl3ba 'ltl3ba -H2' -f GFa --stats='%T, %s states, %e edges'
#+END_SRC
#+RESULTS:
: ltl3ba, 2 states, 4 edges
: ltl3ba -H2, 1 states, 2 edges
@ -373,15 +369,10 @@ ltldo ltl3ba 'ltl3ba -H2' -f GFa --stats='%T, %s states, %e edges'
If you have ever tried to use =spin=, =ltl2ba=, or =ltl3ba=, to translate
a formula such as =[]!Error=, you have noticed that it does not work:
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :prologue "exec 2>&1" :epilogue true
spin -f '[]!Error'
#+END_SRC
#+RESULTS:
#+BEGIN_SRC sh :results verbatim :exports results
spin -f '[]!Error' 2>&1 || exit 0
#+END_SRC
#+RESULTS:
: tl_spin: expected predicate, saw 'E'
: tl_spin: []!Error
: -------------^
@ -391,14 +382,14 @@ only atomic propositions starting with a lowercase letter.
Running the same command through =ltldo= will work:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltldo spin -f '[]!Error' -s
#+END_SRC
#+RESULTS:
: never {
: accept_init:
: if
: :: ((!(Error))) -> goto accept_init
: :: (!(Error)) -> goto accept_init
: fi;
: }
@ -428,7 +419,7 @@ an LTL formula). In the following example, you can see that the
automaton uses the atomic proposition =Error=, but its name contains a
reference to =p0=.
#+BEGIN_SRC sh :results verbatim :exports both :wrap SRC hoa
#+BEGIN_SRC sh :wrap SRC hoa
ltldo 'ltl3ba -H' -f '[]!Error'
#+END_SRC
#+RESULTS:
@ -451,7 +442,7 @@ State: 0 "accept_init" {0}
If this is a problem, you can always force a new name with the
=--name= option:
#+BEGIN_SRC sh :results verbatim :exports both :wrap SRC hoa
#+BEGIN_SRC sh :wrap SRC hoa
ltldo 'ltl3ba -H' -f '[]!Error' --name='BA for %f'
#+END_SRC
@ -480,7 +471,7 @@ State: 0 "accept_init" {0}
Here is a formula on which different translators produce Büchi automata of
different sizes (states and edges):
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltldo ltl2ba ltl3ba 'ltl2tgba -s' -f 'F(a & Xa | FGa)' \
--stats='%T: %s st. (%n non-det.), %e ed.'
#+END_SRC
@ -494,7 +485,7 @@ Instead of outputting the result of the translation of each formula by each
translator, =ltldo= can also be configured to output the smallest
automaton obtained for each formula:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltldo ltl2ba ltl3ba 'ltl2tgba -s' -f 'F(a & Xa | FGa)' --smallest
#+END_SRC
@ -530,7 +521,7 @@ edges. If we desire the automaton that has the fewest states, and in
case of equality the smallest number of non-deterministic states, we
can use the following command instead.
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltldo ltl2ba ltl3ba 'ltl2tgba -s' -f 'F(a & Xa | FGa)' --smallest=%s,%n
#+END_SRC
@ -563,7 +554,7 @@ from Dwyer et al. (FMSP'98), and print which translator among
=ltl2ba=, =ltl3ba=, and =ltl2tgba -s= would produce the smallest
automaton.
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
genltl --dac=10..20 --format=%F:%L,%f |
ltldo -F-/2 ltl2ba ltl3ba 'ltl2tgba -s' --smallest --stats='%<,%T'
#+END_SRC
@ -589,7 +580,7 @@ or =ltl2tgba -s= are also producing automata of equal size.
To understand the above pipeline, remove the =ltldo= invocation. The
[[file:genltl.org][=genltl=]] command outputs this:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
genltl --dac=10..20 --format=%F:%L,%f
#+END_SRC
#+RESULTS:

View file

@ -3,6 +3,7 @@
#+DESCRIPTION: Spot command-line tool for filtering, tranforming, and converting LTL formulas.
#+INCLUDE: setup.org
#+HTML_LINK_UP: tools.html
#+PROPERTY: header-args:sh :results verbatim :exports both
This tool is a filter for LTL formulas. (It will also work with PSL
formulas.) It can be used to perform a number of tasks. Essentially:
@ -23,7 +24,7 @@ For instance the following will convert two LTL formulas expressed
using infix notation (with different names supported for the same
operators) and convert it into LBT's syntax.
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltlfilt -l -f 'p1 U (p2 & GFp3)' -f 'X<>[]p4'
#+END_SRC
#+RESULTS:
@ -33,7 +34,7 @@ ltlfilt -l -f 'p1 U (p2 & GFp3)' -f 'X<>[]p4'
Conversely, here is how to rewrite formulas expressed using the
LBT's Polish notation. Let's take the following four formulas
taken from examples distributed with =scheck=:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
cat >scheck.ltl<<EOF
! | G p0 & G p1 F p3
| | X p7 F p6 & | | t p3 p7 U | f p3 p3
@ -44,7 +45,7 @@ EOF
#+RESULTS:
These can be turned into something easier to read (to the human) with:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltlfilt --lbt-input -F scheck.ltl
#+END_SRC
#+RESULTS:
@ -58,7 +59,7 @@ ltlfilt --lbt-input -F scheck.ltl
The following options can be used to modify the formulas that have
been read.
#+BEGIN_SRC sh :results verbatim :exports results
#+BEGIN_SRC sh :exports results
ltlfilt --help | sed -n '/Transformation options.*:/,/^$/p' | sed '1d;$d'
#+END_SRC
#+RESULTS:
@ -95,7 +96,7 @@ ltlfilt --help | sed -n '/Transformation options.*:/,/^$/p' | sed '1d;$d'
As with [[file:randltl.org][=randltl=]], the =-r= option can be used to simplify formulas.
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltlfilt --lbt-input -F scheck.ltl -r
#+END_SRC
#+RESULTS:
@ -123,7 +124,7 @@ uses. The =--relabel=abc= will relabel all atomic propositions using
letters of the alphabet, while =--relabel=pnn= will use =p0=, =p1=,
etc. as in LBT's syntax.
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltlfilt --lbt-input -F scheck.ltl -r --relabel=abc
#+END_SRC
#+RESULTS:
@ -138,7 +139,7 @@ Note that the relabeling is reset between each formula: =p3= became
Another use of relabeling is to get rid of complex atomic propositions
such as the one shown when [[file:ioltl.org][presenting lenient mode]]:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltlfilt --lenient --relabel=pnn -f '(a < b) U (process[2]@ok)'
#+END_SRC
#+RESULTS:
@ -150,7 +151,7 @@ enabled by =--relabel-bool=abc= or =--relabel-book=pnn=. With this
option, Boolean subformulas that do not interfere with other
subformulas will be changed into atomic propositions. For instance:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltlfilt -f '(a & !b) & GF(a & !b) & FG(!c)' --relabel-bool=pnn
ltlfilt -f '(a & !b) & GF(a & !b) & FG(!c & a)' --relabel-bool=pnn
#+END_SRC
@ -176,7 +177,7 @@ to use =--nnf= so that =!FG(a -> b)= would become =GF(p0)=
as well. For instance here are some LTL formulas extracted from an
[[http://www.fi.muni.cz/~xrehak/publications/verificationresults.ps.gz][industrial project]]:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltlfilt --nnf -u --relabel-bool <<EOF
G (hfe_rdy -> F !hfe_req)
G (lup_sr_valid -> F lup_sr_clean )
@ -230,7 +231,7 @@ An option that can be used in combination with =--relabel= or
between old and new names to be printed as a set of =#define=
statements.
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltlfilt -f '(a & !b) & GF(a & !b) & FG(!c)' --relabel-bool=pnn --define --spin
#+END_SRC
@ -245,7 +246,7 @@ For instance the following sequence show how to use =ltl3ba= to create
a neverclaim for an LTL formula containing atomic propositions that
=ltl3ba= cannot parse:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltlfilt -f '"proc@loc1" U "proc@loc2"' --relabel=pnn --define=ltlex.def --spin |
ltl3ba -F - >ltlex.never
cat ltlex.def ltlex.never
@ -268,7 +269,7 @@ accept_all:
As a side note, the tool [[file:ltldo.org][=ltldo=]] might be a simpler answer to this syntactic problem:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltldo ltl3ba -f '"proc@loc1" U "proc@loc2"' --spin
#+END_SRC
#+RESULTS:
@ -292,7 +293,7 @@ separate page]].
=ltlfilt= supports many ways to filter formulas:
#+BEGIN_SRC sh :results verbatim :exports results
#+BEGIN_SRC sh :exports results
ltlfilt --help | sed -n '/Filtering options.*:/,/^$/p' | sed '1d;$d'
#+END_SRC
#+RESULTS:
@ -332,7 +333,7 @@ Most of the above options should be self-explanatory. For instance
the following command will extract all formulas from =scheck.ltl=
which do not represent guarantee properties.
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltlfilt --lbt-input -F scheck.ltl -v --guarantee
#+END_SRC
#+RESULTS:
@ -342,7 +343,7 @@ Combining =ltlfilt= with [[file:randltl.org][=randltl=]] makes it easier to gene
formulas that respect certain constraints. For instance let us
generate 10 formulas that are equivalent to =a U b=:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
randltl -n -1 a b | ltlfilt --equivalent-to 'a U b' -n 10
#+END_SRC
#+RESULTS:
@ -375,7 +376,7 @@ syntactically. We can generate some starting again with =randltl=,
then ignoring all syntactic safety formulas, and keeping only the
safety formulas in the remaining list.
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
randltl -r -n -1 a b | ltlfilt -v --syntactic-safety | ltlfilt --safety -n 10
#+END_SRC
#+RESULTS:
@ -397,7 +398,7 @@ Ga | (!b U !a)
about a single formula. For instance is =a U (b U a)= equivalent to
=b U a=?
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltlfilt -f 'a U (b U a)' --equivalent-to 'b U a'
#+END_SRC
#+RESULTS:
@ -410,7 +411,7 @@ status to 1, were the two formulas not equivalent.
Is the formula =F(a & X(!a & Gb))= stutter-invariant?
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltlfilt -f 'F(a & X(!a & Gb))' --stutter-invariant
#+END_SRC
#+RESULTS:
@ -420,7 +421,7 @@ Yes it is. And since it is stutter-invariant, there exist some
equivalent formulas that do not use =X= operator. The =--remove-x=
option gives one:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltlfilt -f 'F(a & X(!a & Gb))' --remove-x
#+END_SRC
#+RESULTS:
@ -429,7 +430,7 @@ ltlfilt -f 'F(a & X(!a & Gb))' --remove-x
We could even verify that the resulting horrible formula is equivalent
to the original one:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltlfilt -f 'F(a & X(!a & Gb))' --remove-x | ltlfilt --equivalent-to 'F(a & X(!a & Gb))'
#+END_SRC
#+RESULTS:
@ -447,7 +448,7 @@ the formula generated randomly can be reduced by trivial
simplifications such as =!!f= being rewritten to =f=, yielding
formulas of smaller sizes).
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
randltl -n -1 --tree-size=8 a b | ltlfilt --size=5 -n 10
#+END_SRC
@ -473,7 +474,7 @@ formulas: the complexity of the Boolean subformulas has little
influence on the overall translation. Here are 10 random formula with
Boolean-size 5:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
randltl -n -1 --tree-size=12 a b | ltlfilt --bsize=5 -n 10
#+END_SRC
@ -495,7 +496,7 @@ GF(1 U b)
The =--format= option can be used the alter the way formulas are output.
The list of supported =%=-escape sequences are recalled in the =--help= output:
#+BEGIN_SRC sh :results verbatim :exports results
#+BEGIN_SRC sh :exports results
ltlfilt --help | sed -n '/ sequences:/,/^$/p' | sed '1d;$d'
#+END_SRC
#+RESULTS:
@ -544,7 +545,7 @@ you could print only the line numbers containing formulas matching
some criterion. In the following, we print only the numbers of the
lines of =scheck.ltl= that contain guarantee formulas:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltlfilt --lbt-input -F scheck.ltl --guarantee --format=%L
#+END_SRC
#+RESULTS:
@ -555,7 +556,7 @@ ltlfilt --lbt-input -F scheck.ltl --guarantee --format=%L
We could also prefix each formula by its size, in order to sort
the file by formula size:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltlfilt --lbt-input scheck.ltl --format='%s,%f' | sort -n
#+END_SRC
@ -575,7 +576,7 @@ makes it very easy to partition a list of formulas in different files.
For instance here is how to split =scheck.ltl= according to formula
sizes.
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltlfilt --lbt-input scheck.ltl --output='scheck-%s.ltl'
wc -l scheck*.ltl
#+END_SRC
@ -587,7 +588,7 @@ wc -l scheck*.ltl
: 4 scheck.ltl
: 8 total
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
rm -f ltlex.def ltlex.never scheck.ltl
#+END_SRC

View file

@ -3,17 +3,21 @@
#+DESCRIPTION: Spot command-line tool for mutating LTL formulas.
#+INCLUDE: setup.org
#+HTML_LINK_UP: tools.html
#+PROPERTY: header-args:sh :results verbatim :exports both
This tool lists formulas that are similar to but simpler than a given
formula by applying simple mutations to it, like removing operands or
:results scalar: Is the same as :results verbatim.
:results table: Interprets the results as an Org This tool lists
formulas that are similar to but simpler than a given formula by
applying simple mutations to it, like removing operands or
operators. This is meant to be used with ltlcross to simplify a
formula that caused a problem before trying to debug it (see also
=ltlcross --grind=FILENAME=).
Here is a list of the different kind of mutations that can be applied:
Here is a list of the different kinds of mutations that can be applied:
#+BEGIN_SRC sh :results verbatim :exports results
ltlgrind --help | sed -n '/Transformation rules:/,/^$/p' | sed '1d;$d'
#+BEGIN_SRC sh :exports results
ltlgrind --help | sed -n '/Mutation rules.*:/,/^$/p' | sed '1d;$d'
#+END_SRC
#+RESULTS:
@ -28,7 +32,7 @@ ltlgrind --help | sed -n '/Transformation rules:/,/^$/p' | sed '1d;$d'
--rewrite-ops rewrite operators that have a semantically simpler
form: a U b becomes a W b, etc.
--simplify-bounds on a bounded unary operator, decrement one of the
bounds, or set min to 0 or max to unbounded.
bounds, or set min to 0 or max to unbounded
--split-ops when an operator can be expressed as a
conjunction/disjunction using simpler operators,
each term of the conjunction/disjunction is a
@ -40,7 +44,7 @@ ltlgrind --help | sed -n '/Transformation rules:/,/^$/p' | sed '1d;$d'
By default, all rules are applied. But if one or more rules are
specified, only those will be applied.
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltlgrind -f 'a U G(b <-> c)' --split-ops --rewrite-ops --remove-ops
#+END_SRC

View file

@ -3,6 +3,7 @@
#+DESCRIPTION: Spot command-line tool for synthesizing AIGER circuits from LTL/PSL formulas.
#+INCLUDE: setup.org
#+HTML_LINK_UP: tools.html
#+PROPERTY: header-args:sh :results verbatim :exports both
* Basic usage
@ -23,7 +24,7 @@ N}$ satisfies \phi.
The following example illustrates the synthesis of a controller acting as an
=AND= gate. We have two inputs =a= and =b= and one output =c=, and we want =c=
to always be the =AND= of the two inputs:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltlsynt --ins=a,b --outs=c -f 'G (a & b <=> c)'
#+END_SRC
@ -59,14 +60,12 @@ The following example illustrates the case of an unrealizable specification. As
=a= is an input proposition, there is no way to guarantee that it will
eventually hold.
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh :epilogue true
ltlsynt --ins=a --outs=b -f 'F a'
#+END_SRC
#+RESULTS:
#+begin_example
UNREALIZABLE
#+end_example
: UNREALIZABLE
By default, the controller is output in HOA format, but it can be output as an
@ -89,7 +88,7 @@ TLSF specification to an LTL formula.
The following four steps show you how a TLSF specification called spec.tlsf can
be synthesized using =syfco= and =ltlsynt=:
#+BEGIN_SRC sh
#+BEGIN_SRC sh :export code
LTL=$(syfco FILE -f ltlxba -m fully)
IN=$(syfco FILE -f ltlxba -m fully)
OUT=$(syfco FILE -f ltlxba -m fully)
@ -108,4 +107,3 @@ You can also ask =ltlsynt= to print to obtained parity game into
[[https://github.com/tcsprojects/pgsolver][PGSolver]] format, with the flag
=--print-pg=. Note that this flag deactivates the resolution of the parity
game, which is to be deferred to one of the solvers from PGSolver.

View file

@ -3,6 +3,7 @@
#+DESCRIPTION: Options for input and output of ω-automata in Spot's command-line tools
#+INCLUDE: setup.org
#+HTML_LINK_UP: tools.html
#+PROPERTY: header-args:sh :results verbatim :exports both
Spot supports different output syntaxes for automata. This page
documents the options, common to all tools where it makes sense, that
@ -12,7 +13,7 @@ are used to specify how to output of automata.
All tools that can output automata implement the following options:
#+BEGIN_SRC sh :results verbatim :exports results
#+BEGIN_SRC sh :exports results
ltl2tgba --help | sed -n '/Output format:/,/^$/p' | sed '1d;$d'
#+END_SRC
#+RESULTS:
@ -86,7 +87,7 @@ printer.
Here is an example where [[file:ltl2tgba.org][=ltl2tgba=]] is used to construct two automata:
one for =a U b= and one for =(Ga -> Gb) W c=.
#+BEGIN_SRC sh :results verbatim :exports both :wrap SRC hoa
#+BEGIN_SRC sh :wrap SRC hoa
ltl2tgba 'a U b' '(Ga -> Gb) W c'
#+END_SRC
#+RESULTS:
@ -140,7 +141,7 @@ The above output contains two automata, named after the formulas they
represent. Here is a picture of these two automata:
#+NAME: hoafex
#+BEGIN_SRC sh :results verbatim :exports none
#+BEGIN_SRC sh :exports none
ltl2tgba --dot=.cn '(Ga -> Gb) W c' 'a U b' | dot | gvpack |
perl -pe 's/\\\n//g;s/\\/\\\\/g;s/graph G/graph cluster/g'
#+END_SRC
@ -317,7 +318,7 @@ to use state-based acceptance whenever possible. Option =t= forces
transition-based acceptance. For instance compare this output to the
previous one:
#+BEGIN_SRC sh :results verbatim :exports both :wrap SRC hoa
#+BEGIN_SRC sh :wrap SRC hoa
ltl2tgba -Ht 'a U b'
#+END_SRC
#+RESULTS:
@ -343,7 +344,7 @@ State: 1
Option =m= uses mixed acceptance, i.e, some states might use
state-based acceptance while other will not:
#+BEGIN_SRC sh :results verbatim :exports both :wrap SRC hoa
#+BEGIN_SRC sh :wrap SRC hoa
ltl2tgba -Hm '(Ga -> Gb) W c'
#+END_SRC
#+RESULTS:
@ -383,7 +384,7 @@ the result should be used with line-based tools or embedded into a CSV
file... Here is an example using both transition-based acceptance,
and single-line output:
#+BEGIN_SRC sh :results verbatim :exports both :wrap SRC hoa
#+BEGIN_SRC sh :wrap SRC hoa
ltl2tgba -Htl 'a U b' '(Ga -> Gb) W c'
#+END_SRC
#+RESULTS:
@ -398,7 +399,7 @@ be requested explicitly using =-H1=. The main advantage of version
1.1, as far as Spot is concerned, is that some of negated properties
can be transmitted. For instance, compare
#+BEGIN_SRC sh :results verbatim :exports both :wrap SRC hoa
#+BEGIN_SRC sh :wrap SRC hoa
ltl2tgba -f GFa -f FGa -H1 --check | grep -E '^(HOA|properties|name):'
#+END_SRC
@ -416,7 +417,7 @@ properties: weak
versus
#+BEGIN_SRC sh :results verbatim :exports both :wrap SRC hoa
#+BEGIN_SRC sh :wrap SRC hoa
ltl2tgba -f GFa -f FGa -H1.1 --check | grep -E '^(HOA|properties|name):'
#+END_SRC
@ -444,7 +445,7 @@ represented in the first version.
The [[http://www.tcs.hut.fi/Software/lbtt/doc/html/Format-for-automata.html][LBTT]] output has two flavors: state-based (which is used to output
Büchi automata or monitors) or transition-based (for TGBA).
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltl2tgba --ba --lbtt 'p0 U p1'
#+END_SRC
#+RESULTS:
@ -460,7 +461,7 @@ ltl2tgba --ba --lbtt 'p0 U p1'
If you want to request transition-based output even for Büchi automata,
use =--lbtt=t=.
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltl2tgba --ba --lbtt=t 'p0 U p1'
#+END_SRC
@ -481,7 +482,7 @@ case other atomic propositions are used, Spot output them in double
quotes. This other extension of the format is also supported by
[[http://www.ltl2dstar.de/][ltl2dstar]].
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltl2tgba --ba --lbtt 'a U b'
#+END_SRC
@ -500,7 +501,7 @@ ltl2tgba --ba --lbtt 'a U b'
Spin [[http://spinroot.com/spin/Man/never.html][never claims]] can be requested using =-s= or =--spin=. They can only
represent Büchi automata, so these options imply =--ba=.
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltl2tgba -s 'a U b'
#+END_SRC
@ -519,7 +520,7 @@ Recent versions of Spin (starting with Spin 6.2.4) output never claims
in a slightly different style that can be requested using either
=-s6= or =--spin=6=:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltl2tgba -s6 'a U b'
#+END_SRC
@ -543,38 +544,35 @@ of Promela syntax.)
The =-d= or =--dot= option causes automata to be output in GraphViz's
format.
#+BEGIN_SRC sh :results verbatim :exports code
#+NAME: oaut-dot1
#+BEGIN_SRC sh :prologue export SPOT_DOTEXTRA= SPOT_DOTDEFAULT=
ltl2tgba '(Ga -> Gb) W c' -d
#+END_SRC
#+NAME: oaut-dot1
#+BEGIN_SRC sh :results verbatim :exports results
SPOT_DOTEXTRA= ltl2tgba '(Ga -> Gb) W c' --dot=
#+END_SRC
#+RESULTS: oaut-dot1
#+begin_example
digraph G {
digraph "(Gb | F!a) W c" {
rankdir=LR
label="Inf(0)\n[Büchi]"
labelloc="t"
node [shape="circle"]
I [label="", style=invis, width=0]
I -> 1
I -> 0
0 [label="0"]
0 -> 0 [label="b\n{0}"]
0 -> 0 [label="!a & !c\n{0}"]
0 -> 1 [label="c"]
0 -> 2 [label="a & b & !c"]
0 -> 3 [label="a & !c"]
1 [label="1"]
1 -> 0 [label="a & b & !c"]
1 -> 1 [label="!a & !c\n{0}"]
1 -> 2 [label="a & !c"]
1 -> 3 [label="c"]
1 -> 1 [label="1\n{0}"]
2 [label="2"]
2 -> 1 [label="!a & !c\n{0}"]
2 -> 2 [label="a & !c"]
2 -> 3 [label="!a & c"]
2 -> 4 [label="a & c"]
2 -> 2 [label="b\n{0}"]
3 [label="3"]
3 -> 3 [label="1\n{0}"]
3 -> 0 [label="!a & !c\n{0}"]
3 -> 1 [label="!a & c"]
3 -> 3 [label="a & !c"]
3 -> 4 [label="a & c"]
4 [label="4"]
4 -> 3 [label="!a"]
4 -> 1 [label="!a"]
4 -> 4 [label="a"]
}
#+end_example
@ -609,62 +607,13 @@ option =f(FONT)= is used to select a fontname: it is often necessary
when =b= is used to ensure the characters ⓿, ❶, etc. are all selected
from the same font.
#+BEGIN_SRC sh :results verbatim :exports code
#+NAME: oaut-dot2
#+BEGIN_SRC sh :prologue export SPOT_DOTEXTRA=
ltl2tgba --dot=vcsna '(Ga -> Gb) W c'
#+END_SRC
#+RESULTS:
#+begin_example
digraph G {
label="(Gb | F!a) W c\nInf(0)\n[Büchi]"
labelloc="t"
node [shape="circle"]
edge[arrowhead=vee, arrowsize=.7]
I [label="", style=invis, height=0]
I -> 0
subgraph cluster_0 {
color=green
label=""
1 [label="1"]
}
subgraph cluster_1 {
color=green
label=""
2 [label="2"]
}
subgraph cluster_2 {
color=red
label=""
4 [label="4"]
}
subgraph cluster_3 {
color=green
label=""
0 [label="0"]
3 [label="3"]
}
0 -> 0 [label="!a & !c\n{0}"]
0 -> 1 [label="c"]
0 -> 2 [label="a & b & !c"]
0 -> 3 [label="a & !c"]
1 -> 1 [label="1\n{0}"]
2 -> 2 [label="b\n{0}"]
3 -> 0 [label="!a & !c\n{0}"]
3 -> 1 [label="!a & c"]
3 -> 3 [label="a & !c"]
3 -> 4 [label="a & c"]
4 -> 1 [label="!a"]
4 -> 4 [label="a"]
}
#+end_example
#+NAME: oaut-dot2
#+BEGIN_SRC sh :results verbatim :exports none
SPOT_DOTEXTRA= ltl2tgba --dot=vcsna '(Ga -> Gb) W c'
#+END_SRC
#+RESULTS: oaut-dot2
#+begin_example
digraph G {
digraph "(Gb | F!a) W c" {
label="(Gb | F!a) W c\nInf(0)\n[Büchi]"
labelloc="t"
node [shape="circle"]
@ -728,7 +677,7 @@ The strongly connected components are displayed using the following colors:
Here is an example involving all colors:
#+NAME: oaut-dot3
#+BEGIN_SRC sh :results verbatim :exports none
#+BEGIN_SRC sh :exports none
SPOT_DOTEXTRA= autfilt --dot=cas <<EOF
HOA: v1
States: 10
@ -866,7 +815,7 @@ The dot output can also be customized via two environment variables:
this documentation are generated with the following environment
variables set:
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
export SPOT_DOTDEFAULT='Brf(Lato)C(#ffffa0)'
export SPOT_DOTEXTRA='edge[arrowhead=vee, arrowsize=.7]'
#+END_SRC
@ -936,7 +885,7 @@ Caveats:
of =dot2tex= was fixed in 2014, but at the time of writing
(summer 2017) no new release of =dot2tex= has been made. To work around this,
make sure you install =dot2tex= from its git repository:
#+BEGIN_SRC sh
#+BEGIN_SRC sh :exports code
git clone https://github.com/kjellmf/dot2tex.git
cd dot2tex
sudo python setup.py install
@ -963,7 +912,7 @@ displayed when a tool is run with =--help=.
For instance here are the statistics available in [[file:randaut.org][=randaut=]]:
#+BEGIN_SRC sh :results verbatim :exports results
#+BEGIN_SRC sh :exports results
randaut --help | sed -n '/ sequences:/,/^$/p' | sed '1d;$d'
#+END_SRC
#+RESULTS:
@ -972,13 +921,22 @@ randaut --help | sed -n '/ sequences:/,/^$/p' | sed '1d;$d'
%a number of acceptance sets
%c, %[LETTERS]c number of SCCs; you may filter the SCCs to count
using the following LETTERS, possibly
concatenated: (a) accepting, (r) rejecting, (v)
trivial, (t) terminal, (w) weak, (iw) inherently
weak. Use uppercase letters to negate them.
concatenated: (a) accepting, (r) rejecting, (c)
complete, (v) trivial, (t) terminal, (w) weak,
(iw) inherently weak. Use uppercase letters to
negate them.
%d 1 if the output is deterministic, 0 otherwise
%e number of edges
%e number of reachable edges
%F seed number
%g acceptance condition (in HOA syntax)
%g, %[LETTERS]g acceptance condition (in HOA syntax); add brackets
to print an acceptance name instead and LETTERS to
tweak the format: (0) no parameters, (a)
accentuated, (b) abbreviated, (d) style used in
dot output, (g) no generalized parameter, (l)
recognize Street-like and Rabin-like, (m) no main
parameter, (p) no parity parameter, (o) name
unknown acceptance as 'other', (s) shorthand for
'lo0'.
%h the automaton in HOA format on a single line (use
%[opt]h to specify additional options as in
--hoa=opt)
@ -992,9 +950,22 @@ randaut --help | sed -n '/ sequences:/,/^$/p' | sed '1d;$d'
LETTERS to restrict to(u) user time, (s) system
time, (p) parent process, or (c) children
processes.
%s number of states
%t number of transitions
%s number of reachable states
%t number of reachable transitions
%u, %[e]u number of states (or [e]dges) with universal
branching
%u, %[LETTER]u 1 if the automaton contains some universal
branching (or a number of [s]tates or [e]dges with
universal branching)
%w one word accepted by the output automaton
%x, %[LETTERS]x number of atomic propositions declared in the
automaton; add LETTERS to list atomic
propositions with (n) no quoting, (s) occasional
double-quotes with C-style escape, (d)
double-quotes with C-style escape, (c)
double-quotes with CSV-style escape, (p) between
parentheses, any extra non-alphanumeric character
will be used to separate propositions
#+end_example
In most tools =%F= and =%L= are the input filename and line number,
@ -1005,7 +976,7 @@ For instance let's generate 1000 random automata with 100 states and
density 0.2, and just count the number of edges in each automaton. Then
use =R= to summarize the distribution of these values:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
randaut -e0.2 -Q100 -n1000 a --stats %e > size.csv
Rscript -e "summary(read.csv('size.csv', header=FALSE, col.names='edges'))"
#+END_SRC
@ -1031,19 +1002,19 @@ edges should be $20.8\times100=2080$.
Two of the statistics are related to time: =%r= displays wall-clock
time, while =%R= displays CPU-time.
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
genltl --or-gf=1..8 | ltl2tgba --high --stats='%f,%r,%R'
#+END_SRC
#+RESULTS:
: GFp1,0.000502296,0
: GF(p1 | p2),0.000796475,0
: GF(p1 | p2 | p3),0.00215579,0
: GF(p1 | p2 | p3 | p4),0.00441474,0
: GF(p1 | p2 | p3 | p4 | p5),0.00980961,0.01
: GF(p1 | p2 | p3 | p4 | p5 | p6),0.0255462,0.03
: GF(p1 | p2 | p3 | p4 | p5 | p6 | p7),0.121033,0.12
: GF(p1 | p2 | p3 | p4 | p5 | p6 | p7 | p8),0.624101,0.62
: GFp1,0.00100355,0
: GF(p1 | p2),0.00137515,0
: GF(p1 | p2 | p3),0.00331282,0.01
: GF(p1 | p2 | p3 | p4),0.00526782,0
: GF(p1 | p2 | p3 | p4 | p5),0.00895499,0.01
: GF(p1 | p2 | p3 | p4 | p5 | p6),0.0223277,0.02
: GF(p1 | p2 | p3 | p4 | p5 | p6 | p7),0.0936452,0.09
: GF(p1 | p2 | p3 | p4 | p5 | p6 | p7 | p8),0.480063,0.48
Note that =%r= is implemented using the most precise clock available
and usually has nano-second precision, while =%R= uses the =times()=
@ -1070,29 +1041,28 @@ Here is an example where we use =ltldo= to benchmark the (default)
each option the overall wall-clock time, CPU-time spent in =ltldo=,
and CPU-time spent in =ltl2tgba=:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
genltl --or-gf=1..8 |
ltldo '{high}ltl2tgba' '{low}ltl2tgba --low' --stats='%T,%f,%r,%[p]R,%[c]R'
#+END_SRC
#+RESULTS:
#+begin_example
high,GFp1,0.0495443,0,0.02
low,GFp1,0.0427718,0,0.03
high,GFp1 | GFp2,0.0449237,0,0.03
low,GFp1 | GFp2,0.0429886,0,0.03
high,GFp1 | GFp2 | GFp3,0.0477704,0.01,0.03
low,GFp1 | GFp2 | GFp3,0.0294271,0,0.01
high,GFp1 | GFp2 | GFp3 | GFp4,0.0250874,0,0.02
low,GFp1 | GFp2 | GFp3 | GFp4,0.0203729,0,0.01
high,GFp1 | GFp2 | GFp3 | GFp4 | GFp5,0.0318887,0,0.03
low,GFp1 | GFp2 | GFp3 | GFp4 | GFp5,0.0207457,0,0.01
high,GFp1 | GFp2 | GFp3 | GFp4 | GFp5 | GFp6,0.0612968,0,0.05
low,GFp1 | GFp2 | GFp3 | GFp4 | GFp5 | GFp6,0.0145482,0,0.01
high,GFp1 | GFp2 | GFp3 | GFp4 | GFp5 | GFp6 | GFp7,0.130631,0,0.12
low,GFp1 | GFp2 | GFp3 | GFp4 | GFp5 | GFp6 | GFp7,0.0151502,0,0.01
high,GFp1 | GFp2 | GFp3 | GFp4 | GFp5 | GFp6 | GFp7 | GFp8,0.595865,0,0.59
low,GFp1 | GFp2 | GFp3 | GFp4 | GFp5 | GFp6 | GFp7 | GFp8,0.0160234,0,0.01
high,GFp1,0.0409265,0,0.05
low,GFp1,0.0199356,0,0.02
high,GFp1 | GFp2,0.0145994,0,0.02
low,GFp1 | GFp2,0.0143211,0,0.01
high,GFp1 | GFp2 | GFp3,0.0155654,0,0.03
low,GFp1 | GFp2 | GFp3,0.014428,0,0.01
high,GFp1 | GFp2 | GFp3 | GFp4,0.0173471,0,0.02
low,GFp1 | GFp2 | GFp3 | GFp4,0.0143645,0,0.02
high,GFp1 | GFp2 | GFp3 | GFp4 | GFp5,0.0214066,0,0.03
low,GFp1 | GFp2 | GFp3 | GFp4 | GFp5,0.0147305,0,0
high,GFp1 | GFp2 | GFp3 | GFp4 | GFp5 | GFp6,0.0386194,0,0.05
low,GFp1 | GFp2 | GFp3 | GFp4 | GFp5 | GFp6,0.0140456,0,0.02
high,GFp1 | GFp2 | GFp3 | GFp4 | GFp5 | GFp6 | GFp7,0.108726,0,0.1
low,GFp1 | GFp2 | GFp3 | GFp4 | GFp5 | GFp6 | GFp7,0.0137925,0,0.02
high,GFp1 | GFp2 | GFp3 | GFp4 | GFp5 | GFp6 | GFp7 | GFp8,0.49704,0,0.5
low,GFp1 | GFp2 | GFp3 | GFp4 | GFp5 | GFp6 | GFp7 | GFp8,0.0218286,0,0.03
#+end_example
* Naming automata
@ -1106,17 +1076,18 @@ tools have no default name. This name can be changed using the
=--stats=.
#+NAME: oaut-name
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
ltl2tgba --name='TGBA for %f' --dot=n 'a U b'
#+END_SRC
#+RESULTS: oaut-name
#+begin_example
digraph G {
digraph "TGBA for a U b" {
rankdir=LR
label="TGBA for a U b"
label="TGBA for a U b\n[Büchi]"
labelloc="t"
node[style=filled, fillcolor="#ffffa0"] edge[arrowhead=vee, arrowsize=.7]
node [shape="circle"]
node[fontsize=12] fontsize=12 stylesheet="spot.css" edge[arrowhead=vee, arrowsize=.7, fontsize=12]
I [label="", style=invis, width=0]
I -> 1
0 [label="0", peripheries=2]
@ -1150,7 +1121,7 @@ retaining only the names (i.e. formulas) of the automata with 3
states, and finally restricting the output to the first 5 matches
using =autfilt -n5=.
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
randltl -n -1 a b |
ltl2tgba |
autfilt --states=3 --stats='!(%M)' |
@ -1172,13 +1143,13 @@ capable of [[file:csv.org][reading from a CSV file]] (=-F-/2= instructs =ltl2tgb
read the standard input as if it was a CSV file, and to process its
second column):
#+BEGIN_SRC sh :results verbatim :exports both
randltl -n -1 a b | # generate a stream of random LTL formulas
ltl2tgba -F- --stats='%s,!(%f)' | # for each formula output "states,negated formula"
grep '^3,' | # keep only formulas with 3 states
ltl2tgba -F-/2 --stats='%s,%f' | # for each negated formula output "states,formula"
grep '^3,' | # keep only negated formulas with 3 states
head -n5 | cut -d, -f2 # return the five first formulas
#+BEGIN_SRC sh
randltl -n -1 a b | # generate a stream of random LTL formulas
ltl2tgba -F- --stats='%s,!(%f)' | # for each formula output "states,negated formula"
grep '^3,' | # keep only formulas with 3 states
ltl2tgba -F-/2 --stats='%s,%f' | # for each negated formula output "states,formula"
grep '^3,' | # keep only negated formulas with 3 states
head -n5 | cut -d, -f2 # return the five first formulas
#+END_SRC
#+RESULTS:
@ -1192,13 +1163,6 @@ Note that the =-F-= argument in the first call to =ltl2tgba= is
superfluous as the tool default to reading from its standard input.
But we put it there for symmetry with the second call.
# LocalWords: num toc html syntaxes ltl tgba sed utf UTF lbtt SCCs
# LocalWords: GraphViz's hoaf HOA LBTT's neverclaim ba SPOT's Gb cn
# LocalWords: GraphViz autfilt acc Buchi hoafex gvpack perl pe bb
# LocalWords: labelloc rankdir subgraph lp pos invis gv png cmdline
# LocalWords: Tpng txt Hs Hm CSV Htl LBT dstar init goto fi Tpdf XF
# LocalWords: oaut vcsn randaut nondeterministic filename csv hoa
# LocalWords: varphi lnot GFb FG
* Naming output
By default, all output is sent to standard output, so you can either
@ -1212,7 +1176,7 @@ For instance =%d= is replaced by 0 or 1 depending on whether the
automaton is deterministic. We can generate 20 random automata, and
output them in two files depending on their determinism:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
randaut -n 20 -Q2 -e1 1 -o out-det%d.hoa
autfilt -c out-det0.hoa # Count of non-deterministic automata
autfilt -c out-det1.hoa # Count of deterministic automata
@ -1229,7 +1193,7 @@ untouched. For instance if we run the above commands again, but
forcing [[file:randaut.org][=randaut=]] to output 20 *deterministic* automata, it may look
like we produced more than 20 automata:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
randaut -D -n 20 -Q2 -e1 1 -o out-det%d.hoa
autfilt -c out-det0.hoa # Count of non-deterministic automata
autfilt -c out-det1.hoa # Count of deterministic automata
@ -1245,10 +1209,20 @@ previous execution, while =out-det1.hoa= has been overwritten.
In the case where you want to append to a file instead of overwriting
it, prefix the output filename with =>>= as in
: randaut -D -n 20 -Q2 1 -o '>>out-det%d.hoa'
#+BEGIN_SRC sh :exports code
randaut -D -n 20 -Q2 1 -o '>>out-det%d.hoa'
#+END_SRC
(You need the quotes so that the shell does not interpret =>>=.)
#+BEGIN_SRC sh :results silent :exports results
rm -f out-det0.hoa out-det1.hoa
#+END_SRC
# LocalWords: num toc html syntaxes ltl tgba sed utf UTF lbtt SCCs
# LocalWords: GraphViz's hoaf HOA LBTT's neverclaim ba SPOT's Gb cn
# LocalWords: GraphViz autfilt acc Buchi hoafex gvpack perl pe bb
# LocalWords: labelloc rankdir subgraph lp pos invis gv png cmdline
# LocalWords: Tpng txt Hs Hm CSV Htl LBT dstar init goto fi Tpdf XF
# LocalWords: oaut vcsn randaut nondeterministic filename csv hoa
# LocalWords: varphi lnot GFb FG

View file

@ -3,6 +3,7 @@
#+DESCRIPTION: Spot command-line tool for generating random ω-automata.
#+INCLUDE: setup.org
#+HTML_LINK_UP: tools.html
#+PROPERTY: header-args:sh :results verbatim :exports code
The =randaut= tool generates random (connected) automata.
@ -11,64 +12,9 @@ acceptance sets, and using a set of atomic propositions you have to
supply.
#+NAME: randaut1
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh
randaut a b --dot
#+END_SRC
#+RESULTS: randaut1
#+begin_example
digraph G {
rankdir=LR
node [shape="circle"]
fontname="Lato"
node [fontname="Lato"]
edge [fontname="Lato"]
node[style=filled, fillcolor="#ffffa0"] edge[arrowhead=vee, arrowsize=.7]
I [label="", style=invis, width=0]
I -> 0
0 [label=<0>]
0 -> 8 [label=<!a &amp; !b>]
0 -> 3 [label=<!a &amp; !b>]
0 -> 4 [label=<!a &amp; !b>]
1 [label=<1>]
1 -> 7 [label=<a &amp; b>]
1 -> 0 [label=<a &amp; b>]
1 -> 6 [label=<a &amp; !b>]
2 [label=<2>]
2 -> 4 [label=<!a &amp; !b>]
2 -> 0 [label=<a &amp; !b>]
2 -> 5 [label=<a &amp; !b>]
2 -> 9 [label=<!a &amp; b>]
3 [label=<3>]
3 -> 2 [label=<a &amp; b>]
3 -> 9 [label=<a &amp; !b>]
3 -> 3 [label=<a &amp; !b>]
4 [label=<4>]
4 -> 0 [label=<!a &amp; !b>]
4 -> 7 [label=<!a &amp; b>]
5 [label=<5>]
5 -> 3 [label=<a &amp; !b>]
5 -> 1 [label=<!a &amp; b>]
5 -> 7 [label=<!a &amp; !b>]
5 -> 9 [label=<!a &amp; b>]
5 -> 5 [label=<!a &amp; !b>]
6 [label=<6>]
6 -> 8 [label=<a &amp; b>]
6 -> 5 [label=<a &amp; !b>]
6 -> 2 [label=<a &amp; !b>]
7 [label=<7>]
7 -> 8 [label=<!a &amp; !b>]
7 -> 9 [label=<a &amp; b>]
7 -> 0 [label=<!a &amp; b>]
7 -> 1 [label=<!a &amp; !b>]
7 -> 4 [label=<a &amp; b>]
8 [label=<8>]
8 -> 1 [label=<a &amp; b>]
8 -> 3 [label=<!a &amp; b>]
9 [label=<9>]
9 -> 1 [label=<!a &amp; b>]
9 -> 3 [label=<a &amp; !b>]
}
#+end_example
#+BEGIN_SRC dot :file randaut1.svg :var txt=randaut1 :exports results
$txt
@ -95,30 +41,10 @@ In particular =-e0= will cause all states to have 1 successors, and
=-e1= will cause all states to be interconnected.
#+NAME: randaut2
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh
randaut -Q3 -e0 2 --dot
#+END_SRC
#+RESULTS: randaut2
#+begin_example
digraph G {
rankdir=LR
node [shape="circle"]
fontname="Lato"
node [fontname="Lato"]
edge [fontname="Lato"]
node[style=filled, fillcolor="#ffffa0"] edge[arrowhead=vee, arrowsize=.7]
I [label="", style=invis, width=0]
I -> 0
0 [label=<0>]
0 -> 2 [label=<!p0 &amp; !p1>]
1 [label=<1>]
1 -> 1 [label=<!p0 &amp; !p1>]
2 [label=<2>]
2 -> 1 [label=<!p0 &amp; !p1>]
}
#+end_example
#+BEGIN_SRC dot :file randaut2.svg :var txt=randaut2 :exports results
$txt
#+END_SRC
@ -126,36 +52,10 @@ $txt
[[file:randaut2.svg]]
#+NAME: randaut3
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh
randaut -Q3 -e1 2 --dot
#+END_SRC
#+RESULTS: randaut3
#+begin_example
digraph G {
rankdir=LR
node [shape="circle"]
fontname="Lato"
node [fontname="Lato"]
edge [fontname="Lato"]
node[style=filled, fillcolor="#ffffa0"] edge[arrowhead=vee, arrowsize=.7]
I [label="", style=invis, width=0]
I -> 0
0 [label=<0>]
0 -> 2 [label=<!p0 &amp; !p1>]
0 -> 0 [label=<!p0 &amp; !p1>]
0 -> 1 [label=<!p0 &amp; !p1>]
1 [label=<1>]
1 -> 1 [label=<p0 &amp; p1>]
1 -> 2 [label=<p0 &amp; !p1>]
1 -> 0 [label=<p0 &amp; !p1>]
2 [label=<2>]
2 -> 1 [label=<!p0 &amp; !p1>]
2 -> 0 [label=<p0 &amp; !p1>]
2 -> 2 [label=<p0 &amp; !p1>]
}
#+end_example
#+BEGIN_SRC dot :file randaut3.svg :var txt=randaut3 :exports results
$txt
#+END_SRC
@ -170,7 +70,7 @@ The generation of the acceptance sets abn is controlled with the following four
- =-A ACCEPTANCE= (or =--acceptance=ACCEPTANCE=) controls both the acceptance condition,
and the number of associated acceptance sets. The =ACCEPTANCE= argument is documented
in =--help= as follows:
#+BEGIN_SRC sh :results verbatim :exports results
#+BEGIN_SRC sh :exports results
randaut --help | sed -n '/^ \(ACCEPTANCE\|RANGE\)/,/^$/p'
#+END_SRC
@ -221,34 +121,10 @@ ans =-s= (or =--spin=) implies =-B=.
#+NAME: randaut4
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh
randaut -Q3 -e0.5 -A3 -a0.5 2 --dot
#+END_SRC
#+RESULTS: randaut4
#+begin_example
digraph G {
rankdir=LR
node [shape="circle"]
fontname="Lato"
node [fontname="Lato"]
edge [fontname="Lato"]
node[style=filled, fillcolor="#ffffa0"] edge[arrowhead=vee, arrowsize=.7]
I [label="", style=invis, width=0]
I -> 0
0 [label="0"]
0 -> 1 [label=<!p0 &amp; !p1>]
0 -> 0 [label=<!p0 &amp; !p1<br/><font color="#FAA43A">❷</font>>]
1 [label="1"]
1 -> 1 [label=<!p0 &amp; p1<br/><font color="#5DA5DA">⓿</font><font color="#F17CB0">❶</font>>]
1 -> 2 [label=<!p0 &amp; p1<br/><font color="#F17CB0">❶</font>>]
2 [label="2"]
2 -> 1 [label=<!p0 &amp; p1<br/><font color="#5DA5DA">⓿</font>>]
2 -> 0 [label=<p0 &amp; p1<br/><font color="#5DA5DA">⓿</font>>]
2 -> 2 [label=<!p0 &amp; p1<br/><font color="#5DA5DA">⓿</font>>]
}
#+end_example
#+BEGIN_SRC dot :file randaut4.svg :var txt=randaut4 :exports results
$txt
#+END_SRC
@ -257,7 +133,7 @@ $txt
#+NAME: randaut5
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh
randaut -Q3 -e0.4 -B -a0.7 2 --dot
#+END_SRC
@ -292,46 +168,10 @@ $txt
[[file:randaut5.svg]]
#+NAME: randaut5b
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh
randaut -Q6 -e0.4 -S -a.2 -A 'Streett 1..3' 2 --dot
#+END_SRC
#+RESULTS: randaut5b
#+begin_example
digraph G {
rankdir=LR
label=<(Fin(<font color="#5DA5DA">⓿</font>) | Inf(<font color="#F17CB0">❶</font>)) &amp; (Fin(<font color="#FAA43A">❷</font>) | Inf(<font color="#B276B2">❸</font>))>
labelloc="t"
node [shape="circle"]
fontname="Lato"
node [fontname="Lato"]
edge [fontname="Lato"]
node[style=filled, fillcolor="#ffffa0"] edge[arrowhead=vee, arrowsize=.7]
I [label="", style=invis, width=0]
I -> 0
0 [label=<0>]
0 -> 2 [label=<!p0 &amp; !p1>]
0 -> 1 [label=<!p0 &amp; !p1>]
0 -> 3 [label=<!p0 &amp; !p1>]
1 [label=<1>]
1 -> 5 [label=<!p0 &amp; p1>]
2 [label=<2<br/><font color="#5DA5DA">⓿</font><font color="#FAA43A">❷</font>>]
2 -> 1 [label=<!p0 &amp; p1>]
2 -> 2 [label=<!p0 &amp; !p1>]
2 -> 4 [label=<p0 &amp; p1>]
3 [label=<3>]
3 -> 2 [label=<!p0 &amp; !p1>]
3 -> 3 [label=<!p0 &amp; p1>]
4 [label=<4>]
4 -> 0 [label=<!p0 &amp; !p1>]
4 -> 5 [label=<!p0 &amp; p1>]
5 [label=<5<br/><font color="#F17CB0">❶</font><font color="#FAA43A">❷</font>>]
5 -> 1 [label=<p0 &amp; p1>]
5 -> 2 [label=<!p0 &amp; !p1>]
5 -> 3 [label=<p0 &amp; p1>]
}
#+end_example
#+BEGIN_SRC dot :file randaut5b.svg :var txt=randaut5b :exports results
$txt
#+END_SRC
@ -345,61 +185,10 @@ specify a precise parity acceptance such as =parity min even 3=, or
give =randaut= some freedom, as in this example.
#+NAME: randaut5c
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh
randaut -Q10 -S --colored -A 'parity rand rand 3..4' 2 --dot
#+END_SRC
#+RESULTS: randaut5c
#+begin_example
digraph G {
rankdir=LR
label=<Inf(<font color="#5DA5DA">⓿</font>) | (Fin(<font color="#F17CB0">❶</font>) &amp; (Inf(<font color="#FAA43A">❷</font>) | Fin(<font color="#B276B2">❸</font>)))>
labelloc="t"
node [shape="circle"]
fontname="Lato"
node [fontname="Lato"]
edge [fontname="Lato"]
node[style=filled, fillcolor="#ffffa0"] edge[arrowhead=vee, arrowsize=.7]
I [label="", style=invis, width=0]
I -> 0
0 [label=<0<br/><font color="#F17CB0">❶</font>>]
0 -> 2 [label=<!p0 &amp; !p1>]
0 -> 8 [label=<!p0 &amp; !p1>]
0 -> 0 [label=<p0 &amp; !p1>]
0 -> 6 [label=<!p0 &amp; p1>]
1 [label=<1<br/><font color="#B276B2">❸</font>>]
1 -> 5 [label=<!p0 &amp; !p1>]
1 -> 9 [label=<!p0 &amp; p1>]
2 [label=<2<br/><font color="#FAA43A">❷</font>>]
2 -> 4 [label=<p0 &amp; p1>]
2 -> 5 [label=<!p0 &amp; !p1>]
3 [label=<3<br/><font color="#5DA5DA">⓿</font>>]
3 -> 6 [label=<p0 &amp; !p1>]
3 -> 1 [label=<!p0 &amp; p1>]
4 [label=<4<br/><font color="#5DA5DA">⓿</font>>]
4 -> 6 [label=<!p0 &amp; !p1>]
4 -> 1 [label=<p0 &amp; p1>]
5 [label=<5<br/><font color="#5DA5DA">⓿</font>>]
5 -> 0 [label=<!p0 &amp; !p1>]
5 -> 8 [label=<p0 &amp; !p1>]
5 -> 7 [label=<!p0 &amp; !p1>]
6 [label=<6<br/><font color="#5DA5DA">⓿</font>>]
6 -> 2 [label=<!p0 &amp; !p1>]
6 -> 3 [label=<!p0 &amp; !p1>]
7 [label=<7<br/><font color="#FAA43A">❷</font>>]
7 -> 3 [label=<!p0 &amp; p1>]
7 -> 1 [label=<!p0 &amp; p1>]
8 [label=<8<br/><font color="#5DA5DA">⓿</font>>]
8 -> 3 [label=<!p0 &amp; p1>]
8 -> 4 [label=<p0 &amp; !p1>]
8 -> 2 [label=<p0 &amp; !p1>]
8 -> 0 [label=<!p0 &amp; p1>]
9 [label=<9<br/><font color="#F17CB0">❶</font>>]
9 -> 0 [label=<p0 &amp; p1>]
9 -> 6 [label=<p0 &amp; !p1>]
}
#+end_example
#+BEGIN_SRC dot :file randaut5c.svg :var txt=randaut5c :exports results
$txt
#+END_SRC
@ -421,34 +210,10 @@ sum of all these formulas is $\top$. The resulting automaton is
therefore deterministic and complete.
#+NAME: randaut6
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh
randaut -D -Q3 -e0.6 -A2 -a0.5 2 --dot
#+END_SRC
#+RESULTS: randaut6
#+begin_example
digraph G {
rankdir=LR
node [shape="circle"]
fontname="Lato"
node [fontname="Lato"]
edge [fontname="Lato"]
node[style=filled, fillcolor="#ffffa0"] edge[arrowhead=vee, arrowsize=.7]
I [label="", style=invis, width=0]
I -> 0
0 [label="0"]
0 -> 1 [label=<p0>]
0 -> 2 [label=<!p0>]
1 [label="1"]
1 -> 2 [label=<p0<br/><font color="#F17CB0">❶</font>>]
1 -> 0 [label=<!p0<br/><font color="#5DA5DA">⓿</font>>]
2 [label="2"]
2 -> 2 [label=<!p0 &amp; p1<br/><font color="#5DA5DA">⓿</font>>]
2 -> 0 [label=<!p0 &amp; !p1<br/><font color="#F17CB0">❶</font>>]
2 -> 1 [label=<p0<br/><font color="#5DA5DA">⓿</font>>]
}
#+end_example
#+BEGIN_SRC dot :file randaut6.svg :var txt=randaut6 :exports results
$txt
#+END_SRC
@ -476,19 +241,24 @@ following generates 20 automatas, but store them in different files
according to the acceptance condition. The format =%g= represent the
formula for the acceptance condition and would not make a nice
filename, but =%[s]g= is a short name for that acceptance condition
(its is replaced by "other" if Spot does not know better).
(its is replaced by "other" if Spot does not know better). We use
=-Hl= to output one automaton per line, so that =wc -l= will count
automata.
#+BEGIN_SRC sh :results verbatim :exports both
randaut -n20 -Q10 -A 'random 3' 2 -o 'randaut-%[s]g.hoa'
#+BEGIN_SRC sh :exports both
randaut -n20 -Q10 -A 'random 3' 2 -Hl -o 'randaut-%[s]g.hoa'
wc -l randaut-*.hoa
#+END_SRC
#+RESULTS:
: 222 randaut-Rabin-like.hoa
: 380 randaut-Streett-like.hoa
: 100 randaut-generalized-Buchi.hoa
: 249 randaut-other.hoa
: 951 total
: 1 randaut-Fin-less.hoa
: 4 randaut-Rabin-like.hoa
: 7 randaut-Streett-like.hoa
: 2 randaut-generalized-Buchi.hoa
: 1 randaut-generalized-Rabin.hoa
: 1 randaut-generalized-Streett.hoa
: 4 randaut-other.hoa
: 20 total
#+BEGIN_SRC sh :results silent :exports results
rm -f rautaut-*.hoa
@ -515,7 +285,7 @@ options discussed [[file:oaut.org::#default-dot][on another page]], while '=s='
displayed.)
#+NAME: randaut7
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh
randaut -n -1 --colored -A'parity min odd 4' a b |
autfilt --sccs=5 --trivial-sccs=1 --rejecting-sccs=1 \
--inherently-weak-sccs=2 --weak-sccs=1 -n 1 --dot=.s

View file

@ -3,6 +3,7 @@
#+DESCRIPTION: Spot command-line tool for generating random LTL formulas.
#+INCLUDE: setup.org
#+HTML_LINK_UP: tools.html
#+PROPERTY: header-args:sh :results verbatim :exports both
This tool generates random formulas. By default, it will generate one
random LTL formula using atomic propositions supplied on the
@ -12,44 +13,55 @@ formulas instead, but let us first focus on LTL generation.
For instance to obtain fave random LTL formula over the propositions
=a=, =b=, or =c=, use:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
randltl -n5 a b c
#+END_SRC
#+RESULTS:
: 1
: !(!((a U Gb) U b) U GFa)
: GF((b R !a) U (Xc M 1))
: (b <-> Xc) xor Fb
: FXb R (a R (1 U b))
: 0
: 0 R b
: F(XG(F!b M Fb) W (b R a))
: F(a R !c)
: G(a | Fb) W (FGb R !b)
Note that the result does not always use all atomic propositions.
If you do not care about how the atomic propositions are named,
you can give a nonnegative number instead:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
randltl -n5 3
#+END_SRC
#+RESULTS:
: 1
: !(!((p0 U Gp1) U p1) U GFp0)
: GF((p1 R !p0) U (Xp2 M 1))
: (p1 <-> Xp2) xor Fp1
: FXp1 R (p0 R (1 U p1))
: 0
: 0 R p1
: F(XG(F!p1 M Fp1) W (p1 R p0))
: F(p0 R !p2)
: G(p0 | Fp1) W (FGp1 R !p1)
The syntax of the formula output can be changed using the
[[file:ioltl.org][common output options]]:
#+BEGIN_SRC sh :results verbatim :exports results
#+BEGIN_SRC sh :exports results
randltl --help | sed -n '/Output options:/,/^$/p' | sed '1d;$d'
#+END_SRC
#+RESULTS:
: -8, --utf8 output using UTF-8 characters
: -l, --lbt output in LBT's syntax
: -p, --full-parentheses output fully-parenthesized formulas
: -s, --spin output in Spin's syntax
: --spot output in Spot's syntax (default)
: --wring output in Wring's syntax
#+begin_example
-0, --zero-terminated-output separate output formulas with \0 instead of \n
(for use with xargs -0)
-8, --utf8 output using UTF-8 characters
--format=FORMAT, --stats=FORMAT
specify how each line should be output (default:
"%f")
-l, --lbt output in LBT's syntax
--latex output using LaTeX macros
-o, --output=FORMAT send output to a file named FORMAT instead of
standard output. The first formula sent to a file
truncates it unless FORMAT starts with '>>'.
-p, --full-parentheses output fully-parenthesized formulas
-s, --spin output in Spin's syntax
--spot output in Spot's syntax (default)
--wring output in Wring's syntax
#+end_example
When you select Spin's or Wring's syntax, operators =W= and =M= are
automatically rewritten using =U= and =R= (written =V= for Spin).
@ -57,7 +69,7 @@ When you select LBT's syntax, you should name you atomic propositions
like =p0=, =p1=, etc... (Atomic proposition named differently will be
output by Spot in double-quotes, but this is not supported by LBT.)
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
randltl -l 12
randltl -8 12
randltl -s 12
@ -65,10 +77,10 @@ randltl --wring 12
#+END_SRC
#+RESULTS:
: V ! X ^ G p4 M p10 F ! p11 V G p3 p5
: ¬○(□p4⊕(p10 M ◇¬p11)) R (□p3 R p5)
: !X(([]p4 && !(<>!p11 U (p10 && <>!p11))) || (![]p4 && (<>!p11 U (p10 && <>!p11)))) V ([]p3 V p5)
: (!(X((G(p4=1)) ^ ((F(p11=0)) U ((p10=1) * (F(p11=0))))))) R ((G(p3=1)) R (p5=1))
: V f W V G p5 p7 p10
: 0 R ((□p5 R p7) W p10)
: false V (p10 V (p10 || ([]p5 V p7)))
: (FALSE) R ((p10=1) R ((p10=1) + ((G(p5=1)) R (p7=1))))
As you might guess from the above result, for a given set of atomic
propositions (and on the same computer) the generated formula will
@ -78,18 +90,18 @@ can be changed using the =--seed= option. For instance the following
three commands:
#+NAME: result-seed
#+BEGIN_SRC sh :results verbatim :exports both
randltl a b c
randltl --seed=123 a b c
randltl --seed=0 a b c
#+BEGIN_SRC sh
randltl a b c d
randltl --seed=4 a b c d
randltl --seed=0 a b c d
#+END_SRC
Will give three formulas in which the first and last are identical:
#+RESULTS: result-seed
: 1
: b W 0
: 1
: Xb R ((Gb R c) W d)
: Gd
: Xb R ((Gb R c) W d)
When generating random formulas, we usually want large quantity of
them. Rather than running =randltl= several times with different
@ -119,15 +131,15 @@ Initially, the random generator selects a tree size for the formula.
The default size is =15=, but it can be changed using the =--tree-size=
option. For instance in the following, for each formula the tree size
will be chosen randomly in the range =22..30=.
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
randltl -n 5 a b c --tree-size=22..30
#+END_SRC
#+RESULTS:
: (((b xor c) xor (a U (Gc M c))) | (!b xor (a M b))) W (b & Fc)
: c R (!Fa M Xc)
: !(FGc <-> (c <-> Ga)) -> ((Ga W Fa) M F(c W a))
: G(((a xor Fc) W (G(a | b) R (b <-> !b))) <-> (b M 1))
: 0
: !((c xor Gb) -> !Fb) xor !(Gc M 1)
: 1
: (a | ((c | G(!a W (!a W b))) W (b & (c M b)))) <-> (b R c)
The tree size is just the number of nodes in the syntax tree of the
formula during its construction. However because Spot automatically
@ -145,15 +157,15 @@ Stronger simplifications may be requested using the =-r= option, that
implements many rewritings that helps Spot translators algorithms (so
beware that using =-r= reduces the randomness of the output).
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
randltl -n 5 a b c --tree-size=22..30 -r
#+END_SRC
#+RESULTS:
: 1
: c R (G!a M Xc)
: Fa | (FGc & ((c & Ga) | (!c & F!a))) | (GF!c & ((c & F!a) | (!c & Ga)))
: G((Fb & G((a & G!c) | (!a & Fc))) | (G!b & F((a & Fc) | (!a & G!c))))
: 0
: ((G!b | (!c & F!b) | (c & Gb)) & GF!c) | (Fb & ((!c & Gb) | (c & F!b)) & FGc)
: (b R c) | (!a & ((!c & F(a & !b)) M (!c W !b)))
: XGa
: 1
The generator build the syntax tree recursively from its root, by
considering all operators that could be used for a given tree size (for
@ -163,7 +175,7 @@ being selected is this priority over the sum of the priorities of all
considered operators. The default priorities for each operator can
be seen with =--dump-priorities=:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
randltl a b c --dump-priorities
#+END_SRC
#+RESULTS:
@ -199,15 +211,15 @@ disable some of the operators by giving them a null priority. The
following example disables 6 operators, and augments the priority of
=U= to 3 to favor its occurrence.
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
randltl -n 5 a b c --ltl-priorities 'xor=0,implies=0,equiv=0,W=0,M=0,X=0,U=3'
#+END_SRC
#+RESULTS:
: 1
: 1 U b
: 0
: F!((b U !a) U Gc)
: !b U G(b R c)
: b
: 1
: !F(1 U ((a U c) U b))
: 1 U G!b
When using =-r= to simplify generated formulas, beware that these
rewritings may use operators that you disabled during the initial
@ -221,27 +233,27 @@ is generated for a subset of the atomic propositions and "ANDed" to
the random formula. The =--tree-size= option has no influence on the
weak-fairness formula appended.
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
randltl -n 5 a b c --weak-fairness
#+END_SRC
#+RESULTS:
: GFb
: ((b | XXa) M Ga) & GFa & GFc
: GFb & GFc & !(!((a U Gb) U b) U GFa)
: GFb & GFa & GFc & F(!X!b U (!c M 1))
: GFb & GFa & GFc & Xc
: 0
: (!Fb | F!Fc) & GFa & GFb & GFc
: GFa & GFb & GFc & F(a xor b)
: (a | b) & GFa & GFb & GFc & (Ga -> Gc)
: GFa & GFb & GFc & (GXb U (Fc U (Fc | (a R b))))
Boolean formulas may be output with the =-B= option:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
randltl -B -n 5 a b c
#+END_SRC
#+RESULTS:
: !b
: b & !b
: b
: !c xor (!a xor b)
: !a -> (!c <-> (b xor !(a xor !b)))
: !(b -> !c)
: c xor (b | c)
: !(a & (a xor b))
: 0
: !b -> c
In that case, priorities should be set with =--boolean-priorities=.
@ -251,21 +263,21 @@ random PSL formula may produce many LTL formulas that do not use any
PSL operator (this is even more so the case when simplifications are
enabled with =-r=).
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
randltl -P -n 5 a b c
#+END_SRC
#+RESULTS:
: 1
: a R c
: F({[*0] | {{[*0] | a[*]}}[*]}[]-> 0)
: (a | ((a U c) M a)) M 1
: 0
: b
: !(a W b)
: 1
: (a U !b) <-> (!a -> Gb)
As shown with the =--dump-priorities= output below, tweaking the
priorities used to generated PSL formulas requires three different
options:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
randltl -P a b c --dump-priorities
#+END_SRC
#+RESULTS:
@ -295,6 +307,8 @@ eword 1
boolform 1
star 1
star_b 1
fstar 1
fstar_b 1
and 1
andNLM 1
or 1

View file

@ -3,6 +3,7 @@
#+DESCRIPTION: Spot command-line tools for minimizing ω-automata
#+INCLUDE: setup.org
#+HTML_LINK_UP: tools.html
#+PROPERTY: header-args:sh :results verbatim :exports both
#+NAME: version
#+BEGIN_SRC sh :exports none
@ -50,7 +51,7 @@ Let us first state a few facts about this minimization procedure.
* How to change the SAT solver used
By default Spot uses PicoSAT call_version()[:results raw]), this SAT-solver
By default Spot uses PicoSAT call_version()[:results raw], this SAT-solver
is built into the Spot library, so that no temporary files are used to
store the problem.
@ -59,7 +60,7 @@ SAT solver used by Spot. This variable should describe a shell command
to run the SAT-solver on an input file called =%I= so that a model satisfying
the formula will be written in =%O=. For instance to use [[http://www.labri.fr/perso/lsimon/glucose/][Glucose 3.0]], instead
of the builtin version of PicoSAT, define
#+BEGIN_SRC sh
#+BEGIN_SRC sh :exports code
export SPOT_SATSOLVER='glucose -verb=0 -model %I >%O'
#+END_SRC
We assume the SAT solver follows the input/output conventions of the
@ -80,14 +81,14 @@ automaton.
However =-D= is not a guarantee to obtain a deterministic automaton,
even if one exists. For instance, =-D= fails to produce a
deterministic automaton for =GF(a <-> XXb)=. Instead we get a 9-state
deterministic automaton for =a U X(b | GF!b)=. Instead we get a 4-state
non-deterministic automaton.
#+BEGIN_SRC sh :results verbatim :exports both
ltl2tgba -D 'GF(a <-> XXb)' --stats='states=%s, det=%d'
#+BEGIN_SRC sh
ltl2tgba -D 'a U X(b | GF!b)' --stats='states=%s, det=%d'
#+END_SRC
#+RESULTS:
: states=9, det=0
: states=4, det=0
Option =-x tba-det= enables an additional
determinization procedure, that would otherwise not be used by =-D=
@ -98,60 +99,27 @@ acceptance conditions, it will be degeneralized first.
On our example, =-x tba-det= successfully produces a deterministic
TBA, but a non-minimal one:
#+BEGIN_SRC sh :results verbatim :exports both
ltl2tgba -D -x tba-det 'GF(a <-> XXb)' --stats='states=%s, det=%d'
#+BEGIN_SRC sh
ltl2tgba -D -x tba-det 'a U X(b | GF!b)' --stats='states=%s, det=%d'
#+END_SRC
#+RESULTS:
: states=7, det=1
: states=9, det=1
Option =-x sat-minimize= will turn-on SAT-based minimization. It also
implies =-x tba-det=, so there is no need to supply both options.
#+BEGIN_SRC sh :results verbatim :exports both
ltl2tgba -D -x sat-minimize 'GF(a <-> XXb)' --stats='states=%s, det=%d'
#+BEGIN_SRC sh
ltl2tgba -D -x sat-minimize 'a U X(b | GF!b)' --stats='states=%s, det=%d'
#+END_SRC
#+RESULTS:
: states=4, det=1
: states=5, det=1
We can draw it:
#+NAME: gfaexxb3
#+BEGIN_SRC sh :results verbatim :exports code
ltl2tgba -D -x sat-minimize 'GF(a <-> XXb)' -d
#+BEGIN_SRC sh :exports code
ltl2tgba -D -x sat-minimize 'a U X(b | GF!b)' -d
#+END_SRC
#+RESULTS: gfaexxb3
#+begin_example
digraph G {
rankdir=LR
node [shape="circle"]
fontname="Lato"
node [fontname="Lato"]
edge [fontname="Lato"]
node[style=filled, fillcolor="#ffffa0"] edge[arrowhead=vee, arrowsize=.7]
I [label="", style=invis, width=0]
I -> 0
0 [label="0"]
0 -> 1 [label=<!a &amp; !b<br/><font color="#5DA5DA">⓿</font>>]
0 -> 2 [label=<!a &amp; b>]
0 -> 3 [label=<a &amp; b>]
0 -> 3 [label=<a &amp; !b<br/><font color="#5DA5DA">⓿</font>>]
1 [label="1"]
1 -> 0 [label=<a &amp; b>]
1 -> 0 [label=<a &amp; !b<br/><font color="#5DA5DA">⓿</font>>]
1 -> 1 [label=<!a &amp; b>]
1 -> 1 [label=<!a &amp; !b<br/><font color="#5DA5DA">⓿</font>>]
2 [label="2"]
2 -> 0 [label=<a &amp; !b>]
2 -> 1 [label=<!a &amp; b<br/><font color="#5DA5DA">⓿</font>>]
2 -> 1 [label=<!a &amp; !b>]
2 -> 3 [label=<a &amp; b<br/><font color="#5DA5DA">⓿</font>>]
3 [label="3"]
3 -> 2 [label=<!a &amp; b<br/><font color="#5DA5DA">⓿</font>>]
3 -> 2 [label=<!a &amp; !b>]
3 -> 3 [label=<a &amp; b<br/><font color="#5DA5DA">⓿</font>>]
3 -> 3 [label=<a &amp; !b>]
}
#+end_example
#+BEGIN_SRC dot :file gfaexxb3.svg :var txt=gfaexxb3 :exports results
$txt
@ -166,46 +134,8 @@ result will of course be slightly bigger.
#+NAME: gfaexxb4
#+BEGIN_SRC sh :results verbatim :exports code
ltl2tgba -BD -x sat-minimize 'GF(a <-> XXb)' -d
ltl2tgba -BD -x sat-minimize 'a U X(b | GF!b)' -d
#+END_SRC
#+RESULTS: gfaexxb4
#+begin_example
digraph G {
rankdir=LR
node [shape="circle"]
fontname="Lato"
node [fontname="Lato"]
edge [fontname="Lato"]
node[style=filled, fillcolor="#ffffa0"] edge[arrowhead=vee, arrowsize=.7]
I [label="", style=invis, width=0]
I -> 0
0 [label="0"]
0 -> 0 [label=<!a &amp; b>]
0 -> 1 [label=<!b>]
0 -> 2 [label=<a &amp; b>]
1 [label="1", peripheries=2]
1 -> 4 [label=<!a>]
1 -> 5 [label=<a>]
2 [label="2"]
2 -> 1 [label=<!b>]
2 -> 4 [label=<!a &amp; b>]
2 -> 5 [label=<a &amp; b>]
3 [label="3", peripheries=2]
3 -> 0 [label=<!a>]
3 -> 1 [label=<a &amp; !b>]
3 -> 2 [label=<a &amp; b>]
4 [label="4"]
4 -> 0 [label=<!a &amp; !b>]
4 -> 1 [label=<a &amp; b>]
4 -> 2 [label=<a &amp; !b>]
4 -> 3 [label=<!a &amp; b>]
5 [label="5"]
5 -> 1 [label=<a &amp; b>]
5 -> 3 [label=<!a &amp; b>]
5 -> 4 [label=<!a &amp; !b>]
5 -> 5 [label=<a &amp; !b>]
}
#+end_example
#+BEGIN_SRC dot :file gfaexxb4.svg :var txt=gfaexxb4 :exports results
$txt
@ -214,10 +144,11 @@ $txt
[[file:gfaexxb4.svg]]
There are cases where =ltl2tgba='s =tba-det= algorithm fails to produce a deterministic automaton.
In that case, SAT-based minimization is simply skipped. For instance:
There are cases where =ltl2tgba='s =tba-det= algorithm fails to
produce a deterministic automaton. In that case, SAT-based
minimization is simply skipped. For instance:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltl2tgba -D -x sat-minimize 'G(F(!b & (X!a M (F!a & F!b))) U !b)' --stats='states=%s, det=%d'
#+END_SRC
#+RESULTS:
@ -234,7 +165,7 @@ The first is purely syntactic. If a formula belongs to the class of
without being syntactic recurrences.) [[file:ltlfilt.org][=ltlfilt=]] can be instructed to
print only formulas that are syntactic recurrences:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltlfilt --syntactic-recurrence -f 'G(F(!b & (X!a M (F!a & F!b))) U !b)'
#+END_SRC
#+RESULTS:
@ -247,7 +178,7 @@ converting a deterministic Rabin automaton using [[file:dstar2tgba.org][=dstar2t
output is guaranteed to be deterministic if and only if the input DRA
expresses a recurrence property.
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltlfilt --remove-wm -f 'G(F(!b & (X!a M (F!a & F!b))) U !b)' -l |
ltl2dstar --ltl2nba=spin:ltl2tgba@-Ds - - |
dstar2tgba -D --stats='input(states=%S) output(states=%s, acc-sets=%a, det=%d)'
@ -274,7 +205,7 @@ As far as SAT-based minimization goes, =dstar2tgba= will take the same
options as =ltl2tgba=. For instance we can see that the smallest DTBA
has call_size(arg="%s -x sat-minimize")[:results raw] states:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltlfilt --remove-wm -f 'G(F(!b & (X!a M (F!a & F!b))) U !b)' -l |
ltl2dstar --ltl2nba=spin:ltl2tgba@-Ds - - |
dstar2tgba -D -x sat-minimize --stats='input(states=%S) output(states=%s, acc-sets=%a, det=%d)'
@ -284,8 +215,9 @@ dstar2tgba -D -x sat-minimize --stats='input(states=%S) output(states=%s, acc-se
* More acceptance sets
The formula "=G(F(!b & (X!a M (F!a & F!b))) U !b)=" can in fact be minimized into an
even smaller automaton if we use multiple acceptance sets.
The formula "=G(F(!b & (X!a M (F!a & F!b))) U !b)=" can in fact be
minimized into an even smaller automaton if we use multiple acceptance
sets.
Unfortunately because =dstar2tgba= does not know the formula being
translated, and it always convert a DRA into a DBA (with a single
@ -294,7 +226,7 @@ more acceptance sets could be useful to further minimize it. This
number of acceptance sets can however be specified on the command-line
with option =-x sat-acc=M=. For instance:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltlfilt --remove-wm -f 'G(F(!b & (X!a M (F!a & F!b))) U !b)' -l |
ltl2dstar --ltl2nba=spin:ltl2tgba@-Ds - - |
dstar2tgba -D -x sat-minimize,sat-acc=2 --stats='input(states=%S) output(states=%s, acc-sets=%a, det=%d)'
@ -408,51 +340,16 @@ acceptance.
For our example, let us first generate a deterministic Rabin
automaton with [[http://www.ltl2dstar.de/][=ltl2dstar=]].
#+BEGIN_SRC sh :results silent :exports both
#+BEGIN_SRC sh :results silent
ltlfilt -f 'FGa | FGb' -l |
ltl2dstar --ltl2nba=spin:ltl2tgba@-Ds --output-format=hoa - - > output.hoa
#+END_SRC
Let's draw it:
#+NAME: autfiltsm1
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
autfilt output.hoa --dot
#+END_SRC
#+RESULTS: autfiltsm1
#+begin_example
digraph G {
rankdir=LR
label=<(Fin(<font color="#5DA5DA">⓿</font>) &amp; Inf(<font color="#F17CB0">❶</font>)) | (Fin(<font color="#FAA43A">❷</font>) &amp; Inf(<font color="#B276B2">❸</font>))>
labelloc="t"
node [shape="circle"]
fontname="Lato"
node [fontname="Lato"]
edge [fontname="Lato"]
node[style=filled, fillcolor="#ffffa0"] edge[arrowhead=vee, arrowsize=.7]
I [label="", style=invis, width=0]
I -> 0
0 [label=<0<br/><font color="#5DA5DA">⓿</font><font color="#FAA43A">❷</font>>]
0 -> 0 [label=<!a &amp; !b>]
0 -> 1 [label=<a &amp; !b>]
0 -> 2 [label=<!a &amp; b>]
0 -> 3 [label=<a &amp; b>]
1 [label=<1<br/><font color="#F17CB0">❶</font><font color="#FAA43A">❷</font>>]
1 -> 0 [label=<!a &amp; !b>]
1 -> 1 [label=<a &amp; !b>]
1 -> 2 [label=<!a &amp; b>]
1 -> 3 [label=<a &amp; b>]
2 [label=<2<br/><font color="#5DA5DA">⓿</font><font color="#B276B2">❸</font>>]
2 -> 0 [label=<!a &amp; !b>]
2 -> 1 [label=<a &amp; !b>]
2 -> 2 [label=<!a &amp; b>]
2 -> 3 [label=<a &amp; b>]
3 [label=<3<br/><font color="#F17CB0">❶</font><font color="#B276B2">❸</font>>]
3 -> 0 [label=<!a &amp; !b>]
3 -> 1 [label=<a &amp; !b>]
3 -> 2 [label=<!a &amp; b>]
3 -> 3 [label=<a &amp; b>]
}
#+end_example
#+BEGIN_SRC dot :file autfiltsm1.svg :var txt=autfiltsm1 :exports results
$txt
@ -466,7 +363,7 @@ transition-based version (the output may change depending on the SAT
solver used):
#+NAME: autfiltsm2
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
autfilt --sat-minimize output.hoa --dot
#+END_SRC
@ -479,7 +376,7 @@ $txt
We can also attempt to build a state-based version with
#+NAME: autfiltsm3
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
autfilt -S --sat-minimize output.hoa --dot
#+END_SRC
@ -500,32 +397,10 @@ You can however force a specific acceptance to be used as output.
Let's try with generalized co-Büchi for instance:
#+NAME: autfiltsm4
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
autfilt -S --sat-minimize='acc="generalized-co-Buchi 2"' output.hoa --dot
#+END_SRC
#+RESULTS: autfiltsm4
#+begin_example
digraph G {
rankdir=LR
label=<Fin(<font color="#5DA5DA">⓿</font>)|Fin(<font color="#F17CB0">❶</font>)>
labelloc="t"
node [shape="circle"]
fontname="Lato"
node [fontname="Lato"]
edge [fontname="Lato"]
node[style=filled, fillcolor="#ffffa0"] edge[arrowhead=vee, arrowsize=.7]
I [label="", style=invis, width=0]
I -> 0
0 [label=<0<br/><font color="#5DA5DA">⓿</font>>]
0 -> 0 [label=<a>]
0 -> 1 [label=<!a>]
1 [label=<1<br/><font color="#F17CB0">❶</font>>]
1 -> 0 [label=<!b>]
1 -> 1 [label=<b>]
}
#+end_example
#+BEGIN_SRC dot :file autfiltsm4.svg :var txt=autfiltsm4 :exports results
$txt
#+END_SRC
@ -539,7 +414,7 @@ give an acceptance formula in the [[http://adl.github.io/hoaf/#acceptance][HOA s
attempt to create a co-Büchi automaton with
#+NAME: autfiltsm5
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
autfilt -S --sat-minimize='acc="Fin(0)"' output.hoa --dot
#+END_SRC
#+RESULTS: autfiltsm5
@ -571,32 +446,11 @@ Here is an example demonstrating the case where the input automaton is
smaller than the output. Let's take this small TGBA as input:
#+NAME: autfiltsm6
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
ltl2tgba 'GFa & GFb' >output2.hoa
autfilt output2.hoa --dot
#+END_SRC
#+RESULTS: autfiltsm6
#+begin_example
digraph G {
rankdir=LR
label=<Inf(<font color="#5DA5DA">⓿</font>)&amp;Inf(<font color="#F17CB0">❶</font>)>
labelloc="t"
node [shape="circle"]
fontname="Lato"
node [fontname="Lato"]
edge [fontname="Lato"]
node[style=filled, fillcolor="#ffffa0"] edge[arrowhead=vee, arrowsize=.7]
I [label="", style=invis, width=0]
I -> 0
0 [label="0"]
0 -> 0 [label=<a &amp; b<br/><font color="#5DA5DA">⓿</font><font color="#F17CB0">❶</font>>]
0 -> 0 [label=<!a &amp; !b>]
0 -> 0 [label=<!a &amp; b<br/><font color="#F17CB0">❶</font>>]
0 -> 0 [label=<a &amp; !b<br/><font color="#5DA5DA">⓿</font>>]
}
#+end_example
#+BEGIN_SRC dot :file autfiltsm6.svg :var txt=autfiltsm6 :exports results
$txt
#+END_SRC
@ -607,10 +461,10 @@ $txt
If we attempt to minimize it into a transition-based Büchi automaton,
with fewer states, it will fail, output no result, and return with a
non-zero exit code (because no automata where output).
non-zero exit code (because no automata were output).
#+NAME: autfiltsm7
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
autfilt --sat-minimize='acc="Buchi"' output2.hoa
echo $?
#+END_SRC
@ -620,7 +474,7 @@ echo $?
However if we allow more states, it will work:
#+NAME: autfiltsm8
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
autfilt --sat-minimize='acc="Buchi",max-states=3' output2.hoa --dot
#+END_SRC
@ -692,7 +546,7 @@ Compare the following, where parity acceptance is used, but the
automaton is not colored:
#+NAME: autfiltsm9
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
autfilt -S --sat-minimize='acc="parity max even 3"' output2.hoa --dot
#+END_SRC
@ -707,7 +561,7 @@ $txt
belong to exactly one acceptance set:
#+NAME: autfiltsm10
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :exports code
autfilt -S --sat-minimize='acc="parity max even 3",colored' output2.hoa --dot
#+END_SRC
@ -724,22 +578,31 @@ If the environment variable =SPOT_SATLOG= is set to the name of a
file, the minimization function will append statistics about each of
its iterations in this file.
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
rm -f stats.csv
export SPOT_SATLOG=stats.csv
ltlfilt -f 'Ga R (F!b & (c U b))' -l |
ltl2dstar --ltl2nba=spin:ltl2tgba@-Ds - - |
dstar2tgba -D -x sat-minimize,sat-acc=2 --stats='input(states=%S) output(states=%s, acc-sets=%a, det=%d)'
echo ==== stats.csv ====
cat stats.csv
#+END_SRC
#+RESULTS:
: input(states=11) output(states=5, acc-sets=2, det=1)
: ==== stats.csv ====
: input.states,target.states,reachable.states,edges,transitions,variables,clauses,enc.user,enc.sys,sat.user,sat.sys,automaton
: 10,5,,,,13600,1543042,59,3,187,0,
: 10,7,7,33,56,26656,4247441,162,7,775,0,"HOA: v1 States: 7 Start: 0 AP: 3 ""a"" ""b"" ""c"" acc-name: generalized-Buchi 2 Acceptance: 2 Inf(0)&Inf(1) properties: trans-labels explicit-labels trans-acc complete deterministic --BODY-- State: 0 [!0&!1&2] 0 {1} [!0&1] 0 {0} [!0&!1&!2] 1 {0} [0&!1&!2] 1 [0&!1&2] 2 {1} [0&1&!2] 4 [0&1&2] 4 {0} State: 1 [0&!1] 1 {0} [!0&!1&!2 | 0&1] 1 [!0&1 | !0&2] 3 {0} State: 2 [!0&!1&2] 0 {1} [!0&1] 0 {0 1} [!0&!1&!2] 1 [0&!1&2] 2 [0&!1&!2] 3 {1} [0&1] 5 {0 1} State: 3 [!1&!2] 3 [1 | 2] 3 {0} State: 4 [!0&!1&2] 0 {0 1} [!0&1] 0 {0} [!0&!1&!2] 1 [0&1] 4 {0} [0&!1&2] 5 {0} [0&!1&!2] 6 State: 5 [!0&1 | !0&2] 0 {0 1} [!0&!1&!2] 1 [0&1 | 0&2] 5 {0 1} [0&!1&!2] 6 {0} State: 6 [!0&!1&!2] 1 [!0&1&!2] 1 {0 1} [!0&1&2] 1 {1} [!0&!1&2] 3 {0 1} [0] 6 {0 1} --END--"
: 7,6,6,26,48,10512,1376507,50,0,269,0,"HOA: v1 States: 6 Start: 0 AP: 3 ""a"" ""b"" ""c"" acc-name: generalized-Buchi 2 Acceptance: 2 Inf(0)&Inf(1) properties: trans-labels explicit-labels trans-acc complete deterministic --BODY-- State: 0 [!0&!1&2] 0 {1} [!0&1] 0 {0} [!0&!1&!2] 1 [0&!1&!2] 1 {0 1} [0&!1&2] 2 {1} [0&1] 3 {0} State: 1 [t] 1 State: 2 [!0&!1&2] 0 {1} [!0&1] 0 {0} [!1&!2] 1 [0&!1&2] 2 {1} [0&1] 4 {1} State: 3 [!0&!1&2] 0 {1} [!0&1] 0 [!0&!1&!2] 1 [0&1] 3 [0&!1&2] 4 {1} [0&!1&!2] 5 {1} State: 4 [!0&!1&2 | !0&1&!2] 0 {0 1} [!0&1&2] 0 {0} [!0&!1&!2] 1 [0&1 | 0&2] 4 {0 1} [0&!1&!2] 5 State: 5 [!0&!1&!2] 1 [!0&1 | !0&2] 1 {0 1} [0] 5 {0 1} --END--"
Here is the contents of the =stats.csv= file:
#+begin_src sh :exports results :results output raw
sed '1a\
|-|
s/^/|/
s/$/|/
s/,/|/g
s/"HOA:.*--END--"/HOA:.../' stats.csv
#+end_src
#+RESULTS:
| input.states | target.states | reachable.states | edges | transitions | variables | clauses | enc.user | enc.sys | sat.user | sat.sys | automaton |
|--------------+---------------+------------------+-------+-------------+-----------+---------+----------+---------+----------+---------+-----------|
| 8 | 4 | | | | 5120 | 446320 | 22 | 1 | 17 | 0 | |
| 8 | 6 | 6 | 29 | 48 | 11520 | 1515749 | 50 | 4 | 234 | 0 | HOA:... |
| 8 | 5 | | | | 8000 | 874992 | 29 | 0 | 67 | 0 | |
The generated CSV file use the following columns:
- =input.states=: the number of states of the reference automaton at this step
@ -759,14 +622,17 @@ file follows RFC4180 in escaping double-quote by doubling them.
In the above example, the DRA produced by =ltl2dstar= had 11 states.
In the first line of the =stats.csv= file, you can see the
minimization function had a 10-state input, which means that
=dstar2tgba= first reduced the 11-state (complete) DRA into a 10-state
(complete) DBA before calling the SAT-based minimization. This first
line shows the SAT-based minimization for a (complete) 5-state DTGBA
and failing to find one. Then on the next line it looks for a 7-state
solution, finds one. Finally, it finds a (complete) 6-state solution,
now using the 7-state version as reference automaton to further
simplify the problem.
minimization function had a 8-state input, which means that
=dstar2tgba= first reduced the 11-state (complete) DRA into a 8-state
(complete) DBA before calling the SAT-based minimization (the fact
that the input was reduced to a *DBA* is not very obvious from this
trace), This first line shows the SAT-based minimization for a
(complete) 5-state DTGBA and failing to find one. Then on the next
line it looks for a 6-state solution, finds one. Finally, it looks
for a 5-state solution, and cannot find one. The reason the 5-state
attempt uses the 8-state automaton as input rather than the 6-state
automaton is because the 8-state automaton uses 1 acceptance states
(it's a DBA) while the 6-state automaton uses 2.
The final output is reported with 5 states, because by default we
output trim automata. If the =--complete= option had been given, the

View file

@ -1,4 +1,4 @@
#+OPTIONS: H:2 num:nil toc:t html-postamble:nil
#+OPTIONS: H:2 num:nil toc:t html-postamble:nil ^:nil
#+EMAIL: spot@lrde.epita.fr
#+HTML_LINK_HOME: index.html
#+MACRO: SPOTVERSION 2.7.2

View file

@ -3,6 +3,7 @@
#+DESCRIPTION: List of all the command-line tools installed by Spot {{{SPOTVERSION}}}
#+INCLUDE: setup.org
#+HTML_LINK_UP: index.html
#+PROPERTY: header-args:sh :results verbatim :exports both
This document introduces command-line tools that are installed with
the Spot library. We give some examples to highlight possible
@ -17,7 +18,7 @@ commands issued to the shell are formatted like this with a cyan line
on the left:
#+NAME: helloworld
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
echo Hello World
#+END_SRC
@ -97,6 +98,11 @@ lead to some academic publication, please consider citing Spot. Our
Additionally, the man pages of these tools also contains additional
references about the algorithms or data sources used.
If you did some benchmark comparison against Spot, or if you built a
tool above features provided by Spot, please make it clear what
version of Spot you are using. Spot is improved regularly, and
results might be different with another version.
# LocalWords: num toc helloworld SRC LTL PSL randltl ltlfilt genltl
# LocalWords: scalable ltl tgba Büchi automata tgta ltlcross eval
# LocalWords: setenv concat getenv setq

View file

@ -3,6 +3,9 @@
#+DESCRIPTION: Code example for parsing and printing formulas in Spot
#+INCLUDE: setup.org
#+HTML_LINK_UP: tut.html
#+PROPERTY: header-args:sh :results verbatim :exports both
#+PROPERTY: header-args:python :results output :exports both
#+PROPERTY: header-args:C+++ :results verbatim :exports both
Our first task is to read formulas and print them in another syntax.
@ -15,7 +18,7 @@ of LBT, you should use [[file:ioltl.org][=--lbt-input=]]. The output syntax is
using different options such as (=--spin=, =--lbt=, =--latex=, etc.).
Full parentheses can also be requested using =-p=.
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltlfilt -f '[]<>p0 || <>[]p1'
formula='& & G p0 p1 p2'
ltlfilt --lbt-input -f "$formula" --latex
@ -39,7 +42,7 @@ other syntaxes.)
Here are the same operations in Python
#+BEGIN_SRC python :results output :exports both
#+BEGIN_SRC python
import spot
print(spot.formula('[]<>p0 || <>[]p1'))
f = spot.formula('& & G p0 p1 p2')
@ -70,7 +73,7 @@ above in the python bindings. Here parse errors would be returned as
exceptions.
#+NAME: 1stex
#+BEGIN_SRC C++ :results verbatim :exports both
#+BEGIN_SRC C++
#include <iostream>
#include <spot/tl/parse.hh>
#include <spot/tl/print.hh>
@ -113,7 +116,7 @@ parser. Additionally, this give you control over how to print errors.
Here is how to call the infix parser explicitly:
#+BEGIN_SRC C++ :results verbatim :exports both
#+BEGIN_SRC C++
#include <string>
#include <iostream>
#include <spot/tl/parse.hh>
@ -157,7 +160,7 @@ about the extra parenthesis, but it will still return a formula that
is equivalent to =a U b=. You could decide to continue with the
"fixed" formula if you wish. Here is an example:
#+BEGIN_SRC C++ :results verbatim :exports both
#+BEGIN_SRC C++
#include <string>
#include <iostream>
#include <spot/tl/parse.hh>
@ -197,7 +200,7 @@ really cannot recover anything.
The only difference here is the call to =parse_prefix_ltl()= instead
of =parse_infix_psl()=.
#+BEGIN_SRC C++ :results verbatim :exports both
#+BEGIN_SRC C++
#include <string>
#include <iostream>
#include <spot/tl/parse.hh>
@ -241,7 +244,7 @@ down the line.
For instance, let's see what happens if a PSL formulas is passed to
=print_spin_ltl=:
#+BEGIN_SRC C++ :results verbatim :exports both
#+BEGIN_SRC C++
#include <string>
#include <iostream>
#include <spot/tl/parse.hh>
@ -270,7 +273,7 @@ If that is unwanted, here are two possible solutions.
The first is to simply diagnose non-LTL formulas.
#+BEGIN_SRC C++ :results verbatim :exports code
#+BEGIN_SRC C++ :exports code
#include <string>
#include <iostream>
#include <spot/tl/parse.hh>
@ -299,7 +302,7 @@ equivalent LTL formula. This does not always work, so you need to be
prepared to reject the formula anyway. In our example, we are lucky
(maybe because it was carefully chosen...):
#+BEGIN_SRC C++ :results verbatim :exports both
#+BEGIN_SRC C++
#include <string>
#include <iostream>
#include <spot/tl/parse.hh>
@ -342,7 +345,7 @@ syntax for atomic propositions supported by any tool. The usual
workaround in Spot is to double-quote any arbitrary atomic
proposition:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
echo compare
ltlfilt -f '"a > 4" U "b < 5"'
echo and
@ -363,7 +366,7 @@ it has an option for that. This is called /lenient parsing/: when the
parser finds a parenthetical block it does not understand, it simply
assume that this block represents an atomic proposition.
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltlfilt --lenient -f '(a > 4) U (b < 5)'
#+END_SRC
@ -373,7 +376,7 @@ ltlfilt --lenient -f '(a > 4) U (b < 5)'
Lenient parsing is risky, because any parenthesized sub-formula that
is a syntax-error will be treated as an atomic proposition:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltlfilt --lenient -f '(a U ) U c'
#+END_SRC
@ -388,7 +391,7 @@ Formulas have a custom format specification language that allows you
to easily change the way a formula should be output when using the
=format()= method of strings.
#+BEGIN_SRC python :results output :exports both
#+BEGIN_SRC python
import spot
formula = spot.formula('a U b U "$strange[0]=name"')
print("""\
@ -418,7 +421,7 @@ produced from the formula.
The complete list of specifier that apply to formulas can always be
printed with =help(spot.formula.__format__)=:
#+BEGIN_SRC python :results output :exports results
#+BEGIN_SRC python :exports results
import spot
help(spot.formula.__format__)
#+END_SRC

View file

@ -3,6 +3,9 @@
#+DESCRIPTION: Code example for relabeling formulas in Spot
#+INCLUDE: setup.org
#+HTML_LINK_UP: tut.html
#+PROPERTY: header-args:sh :results verbatim :exports both
#+PROPERTY: header-args:python :results output :exports both
#+PROPERTY: header-args:C+++ :results verbatim :exports both
The task is to read an LTL formula, relabel all (possibly
double-quoted) atomic propositions, and provide =#define= statements
@ -10,7 +13,7 @@ for each of these renamings, writing everything in Spin's syntax.
* Shell
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltlfilt -ps --relabel=pnn --define -f '"Proc@Here" U ("var > 10" | "var < 4")'
#+END_SRC
@ -26,7 +29,7 @@ translator) using a formula with complex atomic propositions it cannot
parse. Then you can pass the rewritten formula to =ltl2ba=, and
prepend all those =#define= to its output. For instance:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltlfilt -ps --relabel=pnn --define=tmp.defs -f '"Proc@Here" U ("var > 10" | "var < 4")' >tmp.ltl
cat tmp.defs; ltl2ba -F tmp.ltl
rm tmp.defs tmp.ltl
@ -38,7 +41,7 @@ rm tmp.defs tmp.ltl
#define p1 (var < 4)
#define p2 (var > 10)
never { /* (p0) U ((p1) || (p2))
*/
,*/
T0_init:
if
:: (p0) -> goto T0_init
@ -51,8 +54,8 @@ accept_all:
Aside: another way to work around syntax limitations of tools is to
use [[file:ltldo.org][=ltldo=]]. On the above example, =ltldo ltl2ba -f '"Proc@Here" U
("var > 10" | "var < 4")' -s= would produce a never clam with the
correct atomic proposition, even though =ltl2ba= cannot parse them.
("var > 10" | "var < 4")' -s= would produce a never claim with the
correct atomic propositions, even though =ltl2ba= cannot parse them.
* Python
@ -60,13 +63,13 @@ The =spot.relabel= function takes an optional third parameter that
should be a =relabeling_map=. If supplied, this map is filled with
pairs of atomic propositions of the form (new-name, old-name).
#+BEGIN_SRC python :results output :exports both
#+BEGIN_SRC python
import spot
m = spot.relabeling_map()
g = spot.relabel('"Proc@Here" U ("var > 10" | "var < 4")', spot.Pnn, m)
for newname, oldname in m.items():
print("#define {} ({})".format(newname.to_str(), oldname.to_str('spin', True)))
print(g.to_str('spin', True))
print("#define {} ({})".format(newname.to_str(), oldname.to_str('spin', True)))
print(g.to_str('spin', True))
#+END_SRC
#+RESULTS:
@ -79,7 +82,7 @@ print(g.to_str('spin', True))
The =spot::relabeling_map= is just implemented as a =std::map=.
#+BEGIN_SRC C++ :results verbatim :exports both
#+BEGIN_SRC C++
#include <string>
#include <iostream>
#include <spot/tl/parse.hh>
@ -124,7 +127,7 @@ The =spot::relabeling_map= is just implemented as a =std::map=.
Instead of relabeling each atomic proposition, you could decide to
relabel each Boolean sub-expression:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltlfilt -ps --relabel-bool=pnn --define -f '"Proc@Here" U ("var > 10" | "var < 4")'
#+END_SRC
@ -140,7 +143,7 @@ ltlfilt -ps --relabel-bool=pnn --define -f '"Proc@Here" U ("var > 10" | "var < 4
because that would hide the fact that both =p0= and =p1= check for
=a=. Instead we get this:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltlfilt -ps --relabel-bool=pnn --define -f 'a U (a & b)'
#+END_SRC

View file

@ -3,6 +3,8 @@
#+DESCRIPTION: Code example for constructing and transforming formulas in Spot
#+INCLUDE: setup.org
#+HTML_LINK_UP: tut.html
#+PROPERTY: header-args:python :results output :exports both
#+PROPERTY: header-args:C+++ :results verbatim :exports both
This page explains how to build formulas and how to iterate over their
syntax trees.
@ -29,7 +31,7 @@ as in =formula::And({arg1, arg2, arg3})=.
Here is the list of supported operators:
#+BEGIN_SRC C++
#+BEGIN_SRC C++ :exports code
// atomic proposition
formula::ap(string)
// constants
@ -88,7 +90,7 @@ Building a formula using these operators is quite straightforward.
The second part of the following example shows how to print some
detail of the top-level operator in the formula.
#+BEGIN_SRC C++ :results verbatim :exports both
#+BEGIN_SRC C++
#include <iostream>
#include <spot/tl/formula.hh>
#include <spot/tl/print.hh>
@ -136,7 +138,7 @@ detail of the top-level operator in the formula.
The Python equivalent is similar:
#+BEGIN_SRC python :results output :exports both
#+BEGIN_SRC python
import spot
# Build FGa -> (GFb & GFc)
@ -199,7 +201,7 @@ that tells whether a formula contains a =F= or =G= operator) to save
time time by not exploring further.
#+NAME: gcount_cpp
#+BEGIN_SRC C++ :results verbatim :exports both
#+BEGIN_SRC C++
#include <iostream>
#include <spot/tl/formula.hh>
#include <spot/tl/print.hh>
@ -247,7 +249,7 @@ Here is a demonstration of how to exchange all =F= and =G= operators
in a formula:
#+NAME: xchg_fg_cpp
#+BEGIN_SRC C++ :results verbatim :exports both
#+BEGIN_SRC C++
#include <iostream>
#include <spot/tl/formula.hh>
#include <spot/tl/print.hh>
@ -275,7 +277,7 @@ in a formula:
}
#+END_SRC
#+RESULTS:
#+RESULTS: xchg_fg_cpp
: before: FGa -> (GFb & GF(b & c & d))
: after: GFa -> (FGb & FG(b & c & d))
@ -292,7 +294,7 @@ For instance instead of having a lambda capturing the [[gcount_cpp][=gcount=
variable in the first example]], we could pass a reference to this
variable:
#+BEGIN_SRC C++ :results verbatim :exports both
#+BEGIN_SRC C++
#include <iostream>
#include <spot/tl/formula.hh>
#include <spot/tl/print.hh>
@ -327,7 +329,7 @@ the case of =map=. Let's write a variant of our [[xchg_fg_cpp][=xchg_fg()= exam
that counts the number of exchanges performed. First, we do it
without lambda:
#+BEGIN_SRC C++ :results verbatim :exports both
#+BEGIN_SRC C++
#include <iostream>
#include <spot/tl/formula.hh>
#include <spot/tl/print.hh>
@ -372,7 +374,7 @@ capture itself. A solution is to use =std::function= but that has a
large penalty cost. We can work around that by assuming that that
address will be passed as an argument (=self=) to the lambda:
#+BEGIN_SRC C++ :results verbatim :exports both
#+BEGIN_SRC C++
#include <iostream>
#include <spot/tl/formula.hh>
#include <spot/tl/print.hh>
@ -416,7 +418,7 @@ The Python version of the above two examples uses a very similar
syntax. Python only supports a very limited form of lambda
expressions, so we have to write a standard function instead:
#+BEGIN_SRC python :results output :exports both
#+BEGIN_SRC python
import spot
gcount = 0
@ -450,7 +452,7 @@ b & c & d
Here is the =F= and =G= exchange:
#+BEGIN_SRC python :results output :exports both
#+BEGIN_SRC python
import spot
def xchg_fg(i):

View file

@ -3,6 +3,9 @@
#+DESCRIPTION: Code example for testing the equivalence of two LTL or PSL formulas
#+INCLUDE: setup.org
#+HTML_LINK_UP: tut.html
#+PROPERTY: header-args:sh :results verbatim :exports both
#+PROPERTY: header-args:python :results output :exports both
#+PROPERTY: header-args:C+++ :results verbatim :exports both
This page shows how to test whether two LTL/PSL formulas are
equivalent, i.e., if they denote the same languages.
@ -13,7 +16,7 @@ Using a =ltlfilt= you can use =--equivalent-to=f= to filter a list of
LTL formula and retain only those equivalent to =f=. So this gives an easy
way to test the equivalence of two formulas:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltlfilt -f '(a U b) U a' --equivalent-to 'b U a'
#+END_SRC
#+RESULTS:
@ -23,7 +26,7 @@ Since the input formula was output, it means it is equivalent to =b U
a=. You may want to add =-c= to count the number of formula output if
you prefer a 1/0 answer:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltlfilt -c -f '(a U b) U a' --equivalent-to 'b U a'
#+END_SRC
#+RESULTS:
@ -55,7 +58,7 @@ and $A_g\otimes A_{\lnot f}$ are empty.
We could also write this check by doing [[file:tut10.org][the translation]] and emptiness
check ourselves. For instance:
#+BEGIN_SRC python :results output :exports both
#+BEGIN_SRC python
import spot
def implies(f, g):
@ -76,7 +79,7 @@ print("Equivalent" if equiv(f, g) else "Not equivalent")
This can also be done via a =language_containment_checker= object:
#+BEGIN_SRC python :results output :exports both
#+BEGIN_SRC python
import spot
f = spot.formula("(a U b) U a")
g = spot.formula("b U a")
@ -97,7 +100,7 @@ Here are possible C++ implementations using either =are_equivalent()=
or the =language_containment_checker=. Note that the
=are_equivalent()= function also work with automata.
#+BEGIN_SRC C++ :results verbatim :exports both
#+BEGIN_SRC C++
#include <iostream>
#include <spot/tl/parse.hh>
#include <spot/twaalgos/contains.hh>
@ -113,18 +116,18 @@ int main()
#+RESULTS:
: Equivalent
#+BEGIN_SRC C++ :results verbatim :exports both
#include <iostream>
#include <spot/tl/parse.hh>
#include <spot/tl/contain.hh>
#+BEGIN_SRC C++
#include <iostream>
#include <spot/tl/parse.hh>
#include <spot/tl/contain.hh>
int main()
{
spot::formula f = spot::parse_formula("(a U b) U a");
spot::formula g = spot::parse_formula("b U a");
spot::language_containment_checker c;
std::cout << (c.equal(f, g) ? "Equivalent\n" : "Not equivalent\n");
}
int main()
{
spot::formula f = spot::parse_formula("(a U b) U a");
spot::formula g = spot::parse_formula("b U a");
spot::language_containment_checker c;
std::cout << (c.equal(f, g) ? "Equivalent\n" : "Not equivalent\n");
}
#+END_SRC
#+RESULTS:

View file

@ -3,12 +3,15 @@
#+DESCRIPTION: Code example for translating formulas in Spot
#+INCLUDE: setup.org
#+HTML_LINK_UP: tut.html
#+PROPERTY: header-args:sh :results verbatim :exports both
#+PROPERTY: header-args:python :results output :exports both
#+PROPERTY: header-args:C+++ :results verbatim :exports both
Here is how to translate an LTL (or PSL) formula into a never claim.
* Shell
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltl2tgba --spin 'GFa -> GFb'
#+END_SRC
@ -17,23 +20,23 @@ ltl2tgba --spin 'GFa -> GFb'
never { /* F(GFb | G!a) */
T0_init:
if
:: ((!(a))) -> goto accept_S0
:: ((true)) -> goto T0_init
:: ((b)) -> goto accept_S2
:: (true) -> goto T0_init
:: (b) -> goto accept_S1
:: (!(a)) -> goto accept_S2
fi;
accept_S0:
accept_S1:
if
:: ((!(a))) -> goto accept_S0
:: (b) -> goto accept_S1
:: (!(b)) -> goto T0_S3
fi;
accept_S2:
if
:: ((b)) -> goto accept_S2
:: ((!(b))) -> goto T0_S3
:: (!(a)) -> goto accept_S2
fi;
T0_S3:
if
:: ((b)) -> goto accept_S2
:: ((!(b))) -> goto T0_S3
:: (b) -> goto accept_S1
:: (!(b)) -> goto T0_S3
fi;
}
#+end_example
@ -47,7 +50,7 @@ method that can output in one of the supported syntaxes.
So the translation is actually a one-liner in Python:
#+BEGIN_SRC python :results output :exports both
#+BEGIN_SRC python
import spot
print(spot.formula('GFa -> GFb').translate('BA').to_str('spin'))
#+END_SRC
@ -57,23 +60,23 @@ print(spot.formula('GFa -> GFb').translate('BA').to_str('spin'))
never {
T0_init:
if
:: ((!(a))) -> goto accept_S0
:: ((true)) -> goto T0_init
:: ((b)) -> goto accept_S2
:: (true) -> goto T0_init
:: (b) -> goto accept_S1
:: (!(a)) -> goto accept_S2
fi;
accept_S0:
accept_S1:
if
:: ((!(a))) -> goto accept_S0
:: (b) -> goto accept_S1
:: (!(b)) -> goto T0_S3
fi;
accept_S2:
if
:: ((b)) -> goto accept_S2
:: ((!(b))) -> goto T0_S3
:: (!(a)) -> goto accept_S2
fi;
T0_S3:
if
:: ((b)) -> goto accept_S2
:: ((!(b))) -> goto T0_S3
:: (b) -> goto accept_S1
:: (!(b)) -> goto T0_S3
fi;
}
@ -83,7 +86,7 @@ The above line can actually be made a bit shorter, because
=translate()= can also be used as a function (as opposed to a method)
that takes a formula (possibly as a string) as first argument:
#+BEGIN_SRC python :results output :exports both
#+BEGIN_SRC python
import spot
print(spot.translate('GFa -> GFb', 'BA').to_str('spin'))
#+END_SRC
@ -93,23 +96,23 @@ print(spot.translate('GFa -> GFb', 'BA').to_str('spin'))
never {
T0_init:
if
:: ((!(a))) -> goto accept_S0
:: ((true)) -> goto T0_init
:: ((b)) -> goto accept_S2
:: (true) -> goto T0_init
:: (b) -> goto accept_S1
:: (!(a)) -> goto accept_S2
fi;
accept_S0:
accept_S1:
if
:: ((!(a))) -> goto accept_S0
:: (b) -> goto accept_S1
:: (!(b)) -> goto T0_S3
fi;
accept_S2:
if
:: ((b)) -> goto accept_S2
:: ((!(b))) -> goto T0_S3
:: (!(a)) -> goto accept_S2
fi;
T0_S3:
if
:: ((b)) -> goto accept_S2
:: ((!(b))) -> goto T0_S3
:: (b) -> goto accept_S1
:: (!(b)) -> goto T0_S3
fi;
}
@ -127,7 +130,7 @@ various preferences (like small or deterministic) or characteristic
(complete, unambiguous) for the resulting automaton. Finally, the
output as a never claim is done via the =print_never_claim= function.
#+BEGIN_SRC C++ :results verbatim :exports both
#+BEGIN_SRC C++
#include <iostream>
#include <spot/tl/parse.hh>
#include <spot/twaalgos/translate.hh>
@ -151,22 +154,22 @@ output as a never claim is done via the =print_never_claim= function.
never {
T0_init:
if
:: (p1) -> goto accept_S0
:: (true) -> goto T0_init
:: (p0) -> goto accept_S2
:: (p0) -> goto accept_S1
:: (p1) -> goto accept_S2
fi;
accept_S0:
accept_S1:
if
:: (p1) -> goto accept_S0
:: (p0) -> goto accept_S1
:: (!(p0)) -> goto T0_S3
fi;
accept_S2:
if
:: (p0) -> goto accept_S2
:: (!(p0)) -> goto T0_S3
:: (p1) -> goto accept_S2
fi;
T0_S3:
if
:: (p0) -> goto accept_S2
:: (p0) -> goto accept_S1
:: (!(p0)) -> goto T0_S3
fi;
}
@ -176,7 +179,7 @@ T0_S3:
The Python version of =translate()= is documented as follows:
#+BEGIN_SRC python :results output :exports both
#+BEGIN_SRC python :exports results
import spot
help(spot.translate)
#+END_SRC
@ -185,22 +188,30 @@ help(spot.translate)
#+begin_example
Help on function translate in module spot:
translate(formula, *args)
translate(formula, *args, dict=<spot.impl.bdd_dict; proxy of <Swig Object of type 'std::shared_ptr< spot::bdd_dict > *' at 0x7f1f9541c090> >, xargs=None)
Translate a formula into an automaton.
Keep in mind that pref expresses just a preference that may not be
satisfied.
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 'TGBA', 'BA', or 'Monitor', 'generic',
'parity', 'parity min odd', 'parity min even',
'parity max odd', 'parity max even' (type of automaton to
build), 'coBuchi'
- 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)
- any combination of 'Complete', 'Unambiguous',
'StateBasedAcceptance' (or 'SBAcc' for short), and
'Colored' (only for parity acceptance)
The default correspond to 'tgba', 'small' and 'high'.
The default corresponds to 'tgba', 'small' and 'high'.
Additional options can be supplied using a `spot.option_map`, or a
string (that will be converted to `spot.option_map`), as the `xargs`
argument. This is similar to the `-x` option of command-line tools;
so check out the spot-x(7) man page for details.
#+end_example

View file

@ -3,6 +3,9 @@
#+DESCRIPTION: Code example for using Spot to translating formulas in monitors
#+INCLUDE: setup.org
#+HTML_LINK_UP: tut.html
#+PROPERTY: header-args:sh :results verbatim :exports both
#+PROPERTY: header-args:python :results output :exports both
#+PROPERTY: header-args:C+++ :results verbatim :exports both
A monitor is a special type of automaton that is supposed to /monitor/
a running system and move accordingly. A monitor detects an error
@ -13,7 +16,7 @@ For instance here is a monitor that checks that *yellow* never occurs
immediately after *red*.
#+NAME: tut11a
#+BEGIN_SRC sh :results verbatim :exports none
#+BEGIN_SRC sh :exports none
ltl2tgba -D -M '!F(red & Xyellow)' -d
#+END_SRC
@ -39,7 +42,7 @@ that case a violation should be reported.
To build the above deterministic monitor using [[file:ltl2tgba.org][=ltl2tgba=]], we simply
pass option =-M= (for monitor) and =-D= (for deterministic).
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltl2tgba -D -M '!F(red & X(yellow))'
#+END_SRC
@ -69,7 +72,7 @@ The code is very similar to [[file:tut10.org][our previous example of building a
claim]] except that we explicitly require a deterministic monitor and
output in the [[file:hoa.org][HOA format]].
#+BEGIN_SRC python :results output :exports both
#+BEGIN_SRC python
import spot
print(spot.translate('!F(red & X(yellow))', 'monitor', 'det').to_str('HOA'))
#+END_SRC
@ -97,7 +100,7 @@ State: 1
The code very similar to [[file:tut10.org][the never claim example]].
#+BEGIN_SRC C++ :results verbatim :exports both
#+BEGIN_SRC C++
#include <iostream>
#include <spot/tl/parse.hh>
#include <spot/twaalgos/translate.hh>
@ -154,7 +157,7 @@ In the [[file:hierarchy.org][hierarchy of temporal properties]], the properties
monitorable correspond to the class of [[file:hierarchy.org::#safety][safety properties]]. You can
check that an LTL formula is a safety by using:
#+BEGIN_SRC sh :results verbatim :exports both
#+BEGIN_SRC sh
ltlfilt --count --safety -f '!F(red & X(yellow))'
#+END_SRC
@ -173,22 +176,16 @@ red light will be on until the green light is on, we would use the
following formula: =G(press -> red U green)=. Unfortunately it is not
a safety property:
#+BEGIN_SRC sh :results verbatim :exports code
#+BEGIN_SRC sh :epilogue true
ltlfilt --count --safety -f 'G(press -> red U green)'
#+END_SRC
#+BEGIN_SRC sh :results verbatim :exports results
ltlfilt --count --safety -f 'G(press -> red U green)'
true
#+END_SRC
#+RESULTS:
: 0
Nonetheless, we can still build a monitor for it:
#+NAME: tut11b
#+BEGIN_SRC sh :results verbatim :exports none
#+BEGIN_SRC sh :exports none
ltl2tgba -D -M 'G(press -> red U green)' -d
#+END_SRC
#+BEGIN_SRC dot :file tut11b.svg :var txt=tut11b :exports results
@ -233,7 +230,7 @@ The following code shows how to implement the above five steps in C++
without using =spot::translator=. Unless you plan to customize some
of these steps, we recommend you use =spot::translator= instead.
#+BEGIN_SRC C++ :results verbatim :exports both
#+BEGIN_SRC C++
#include <iostream>
#include <spot/tl/parse.hh>
#include <spot/twaalgos/ltl2tgba_fm.hh>

View file

@ -3,20 +3,23 @@
#+DESCRIPTION: Code example for using Spot to translate LTLf formulas
#+INCLUDE: setup.org
#+HTML_LINK_UP: tut.html
#+PROPERTY: header-args:sh :results verbatim :exports both
#+PROPERTY: header-args:python :results output :exports both
#+PROPERTY: header-args:C+++ :results verbatim :exports both
The LTL operators used by Spot are defined over infinite words, and
the various type of automata supported are all \omega-automata, i.e.,
automata over infinite words.
#+name: from_ltlf
#+begin_src sh :exports none :var f="bug"
ltlfilt --from-ltlf -f "$f"
#+end_src
However there is a trick we can use in case we want to use Spot to
build a finite automaton that recognize some LTLf (i.e. LTL with
finite semantics) property. The plan is as follows:
#+name: from_ltlf
#+begin_src sh :results verbatim :exports none :var f="bug"
ltlfilt --from-ltlf -f "$f"
#+end_src
1. Have Spot read the input formula as if it were LTL.
2. Rewrite this formula in a way that embeds the semantics of LTLf in
LTL. First, introduce a new atomic proposition =alive= that will
@ -27,7 +30,7 @@ ltlfilt --from-ltlf -f "$f"
call_from_ltlf(f="(a U b) & Fc").
3. Convert the resulting formula into a Büchi automaton:
#+name: tut12a
#+begin_src sh :results verbatim :exports none
#+begin_src sh :exports none
ltlfilt --from-ltlf -f "(a U b) & Fc" | ltl2tgba -B -d
#+end_src
#+BEGIN_SRC dot :file tut12a.svg :var txt=tut12a :exports results
@ -38,7 +41,7 @@ ltlfilt --from-ltlf -f "$f"
4. Remove the =alive= property, and, while we are at it, simplify the
Büchi automaton:
#+name: tut12b
#+begin_src sh :results verbatim :exports none
#+begin_src sh :exports none
ltlfilt --from-ltlf -f "(a U b) & Fc" | ltl2tgba -B | autfilt --remove-ap=alive -B --small -d
#+end_src
#+BEGIN_SRC dot :file tut12b.svg :var txt=tut12b :exports results
@ -68,7 +71,7 @@ an atomic proposition from an automaton can be done using [[file:autfilt.org][=a
automaton). Interpreting the resulting Büchi automaton as a finite
automaton is out of scope for Spot.
#+begin_src sh :exports both :results verbatim
#+begin_src sh
ltlfilt --from-ltlf -f "(a U b) & Fc" |
ltl2tgba -B |
autfilt --remove-ap=alive -B --small
@ -115,7 +118,7 @@ simplifications. (Note that =postprocess()= is already called by
=translate()=, but in this case removing the atomic proposition allows
more simplification opportunities.)
#+begin_src python :results output :exports both
#+begin_src python
import spot
# Translate LTLf to Büchi.
aut = spot.from_ltlf('(a U b) & Fc').translate('ba')
@ -163,37 +166,37 @@ The Python functions =translate()= and =postprocess()= are convenient
wrappers around the =spot::translator= and =spot::postprocessor=
objects that we need to use here.
#+begin_src cpp :results verbatim :exports both
#include <iostream>
#include <spot/tl/parse.hh>
#include <spot/tl/ltlf.hh>
#include <spot/twaalgos/translate.hh>
#include <spot/twaalgos/hoa.hh>
#include <spot/twaalgos/remprop.hh>
#+begin_src C++
#include <iostream>
#include <spot/tl/parse.hh>
#include <spot/tl/ltlf.hh>
#include <spot/twaalgos/translate.hh>
#include <spot/twaalgos/hoa.hh>
#include <spot/twaalgos/remprop.hh>
int main()
{
spot::parsed_formula pf = spot::parse_infix_psl("(a U b) & Fc");
if (pf.format_errors(std::cerr))
return 1;
int main()
{
spot::parsed_formula pf = spot::parse_infix_psl("(a U b) & Fc");
if (pf.format_errors(std::cerr))
return 1;
spot::translator trans;
trans.set_type(spot::postprocessor::BA);
trans.set_pref(spot::postprocessor::Small);
spot::twa_graph_ptr aut = trans.run(spot::from_ltlf(pf.f));
spot::translator trans;
trans.set_type(spot::postprocessor::BA);
trans.set_pref(spot::postprocessor::Small);
spot::twa_graph_ptr aut = trans.run(spot::from_ltlf(pf.f));
spot::remove_ap rem;
rem.add_ap("alive");
aut = rem.strip(aut);
spot::remove_ap rem;
rem.add_ap("alive");
aut = rem.strip(aut);
spot::postprocessor post;
post.set_type(spot::postprocessor::BA);
post.set_pref(spot::postprocessor::Small); // or ::Deterministic
aut = post.run(aut);
spot::postprocessor post;
post.set_type(spot::postprocessor::BA);
post.set_pref(spot::postprocessor::Small); // or ::Deterministic
aut = post.run(aut);
print_hoa(std::cout, aut) << '\n';
return 0;
}
print_hoa(std::cout, aut) << '\n';
return 0;
}
#+end_src
#+RESULTS:

View file

@ -3,12 +3,15 @@
#+DESCRIPTION: Code example for parsing and printing ω-automata in Spot
#+INCLUDE: setup.org
#+HTML_LINK_UP: tut.html
#+PROPERTY: header-args:sh :results verbatim :exports both
#+PROPERTY: header-args:python :results output :exports both
#+PROPERTY: header-args:C+++ :results verbatim :exports both
The goal is to start from a never claim, as produced by Spin, e.g.:
#+BEGIN_SRC sh :results verbatim :exports both
spin -f '[]<>foo U bar' > tut20.never
cat tut20.never
#+BEGIN_SRC sh
spin -f '[]<>foo U bar' > tut20.never
cat tut20.never
#+END_SRC
#+RESULTS:
@ -52,12 +55,12 @@ write will read any of those formats.
This is very simple: [[file:autfilt.org][=autfilt=]] can read automata in any of the
supported formats, and outputs it in the HOA format by default:
#+BEGIN_SRC sh :results verbatim :exports both :wrap SRC hoa
#+BEGIN_SRC sh :wrap SRC hoa
autfilt tut20.never
#+END_SRC
#+RESULTS:
#+BEGIN_SRC hoa
#+begin_SRC hoa
HOA: v1
States: 5
Start: 0
@ -81,7 +84,7 @@ State: 4
[1] 3
[t] 4
--END--
#+END_SRC
#+end_SRC
* Python
@ -89,13 +92,13 @@ Another one-liner. The =spot.automaton()= function reads a single
automaton, and each automaton has a =to_str()= method that can print
in =hoa=, =lbtt=, =spin= (for never claim) or =dot=.
#+BEGIN_SRC python :results output :exports both :wrap SRC hoa
#+BEGIN_SRC python :wrap SRC hoa
import spot
print(spot.automaton('tut20.never').to_str('hoa'))
#+END_SRC
#+RESULTS:
#+BEGIN_SRC hoa
#+begin_SRC hoa
HOA: v1
States: 5
Start: 0
@ -119,7 +122,7 @@ State: 4
[1] 3
[t] 4
--END--
#+END_SRC
#+end_SRC
* C++
@ -134,7 +137,7 @@ you), and =aut= is the actual automaton. The parser usually tries to
recover from errors, so =aut= may not be null even if =errors= is
non-empty.
#+BEGIN_SRC C++ :results verbatim :exports both :wrap SRC hoa
#+BEGIN_SRC C++ :wrap SRC hoa
#include <string>
#include <iostream>
#include <spot/parseaut/public.hh>
@ -159,7 +162,7 @@ non-empty.
#+END_SRC
#+RESULTS:
#+BEGIN_SRC hoa
#+begin_SRC hoa
HOA: v1
States: 5
Start: 0
@ -183,7 +186,7 @@ State: 4
[1] 3
[t] 4
--END--
#+END_SRC
#+end_SRC
In the Spot representation of automata, transitions guards are
represented by BDDs. The role of the =bdd_dict= object is to keep
@ -222,14 +225,14 @@ wrapper that instantiates an =automaton_stream_parser= and calls its
In Python, you can easily iterate over a file containing multiple
automata by doing:
#+BEGIN_SRC python :results output :exports code :wrap SRC hoa
#+BEGIN_SRC python :wrap SRC hoa
import spot
for aut in spot.automata('tut20.never'):
print(aut.to_str('hoa'))
#+END_SRC
#+RESULTS:
#+BEGIN_SRC hoa
#+begin_SRC hoa
HOA: v1
States: 5
Start: 0
@ -253,7 +256,7 @@ State: 4
[1] 3
[t] 4
--END--
#+END_SRC
#+end_SRC
In fact =spot.automaton()= is just a wrapper around =spot.automata()=
to return only the first automaton.
@ -265,7 +268,7 @@ accept three types of arguments:
be any shell expression, and must have '=|=' as their last
character. For instance here is how to convert Spin's output into
LBTT's formula without using temporary files.
#+BEGIN_SRC python :results output :exports both
#+BEGIN_SRC python
import spot
print(spot.automaton('spin -f "[]<>p0" |').to_str('lbtt'))
#+END_SRC
@ -285,7 +288,7 @@ print(spot.automaton('spin -f "[]<>p0" |').to_str('lbtt'))
to describe an automaton (or multiple automata) and is
passed directly to the parser:
#+BEGIN_SRC python :results output :exports both
#+BEGIN_SRC python
import spot
print(spot.automaton("""
HOA: v1
@ -306,7 +309,7 @@ State: 1 {0}
: never {
: T0_init:
: if
: :: ((a)) -> goto accept_all
: :: (a) -> goto accept_all
: fi;
: accept_all:
: skip

View file

@ -3,6 +3,9 @@
#+DESCRIPTION: Code example for iterating over ω-automata in Spot
#+INCLUDE: setup.org
#+HTML_LINK_UP: tut.html
#+PROPERTY: header-args:sh :results verbatim :exports both
#+PROPERTY: header-args:python :results output :exports both
#+PROPERTY: header-args:C+++ :results verbatim :exports both
This example demonstrates how to iterate over an automaton in C++ and
Python. This case uses automata stored entirely in memory as a graph:
@ -26,14 +29,14 @@ First let's create an example automaton in HOA format. We use =-U= to
request unambiguous automata, as this allows us to demonstrate how
property bits are used.
#+BEGIN_SRC sh :results verbatim :exports both :wrap SRC hoa
#+BEGIN_SRC sh :wrap SRC hoa
ltl2tgba -U 'Fa | G(Fb&Fc)' | tee tut21.hoa
#+END_SRC
#+RESULTS:
#+BEGIN_SRC hoa
#+begin_SRC hoa
HOA: v1
name: "Fa | G(Fb & Fc)"
States: 4
name: "F(a | G(Fb & Fc))"
States: 17
Start: 0
AP: 3 "a" "b" "c"
acc-name: generalized-Buchi 2
@ -44,19 +47,102 @@ properties: stutter-invariant
State: 0
[0] 1
[!0] 2
[!0] 3
[!0&1&2] 3
[!0&!1&2] 4
[!0&!2] 5
[!0&!2] 6
State: 1
[t] 1 {0 1}
State: 2
[0] 1
[!0] 2
[!1&!2] 2
[!1&2] 2 {1}
[1&!2] 2 {0}
[1&2] 2 {0 1}
State: 3
[!0&1&2] 3 {0 1}
[!0&!1&2] 3 {1}
[!0&1&!2] 3 {0}
[!0&!1&!2] 3
[!0&1&2] 3
[!0&!1&2] 4
[!0&!2] 5
[!0&!2] 6
[0&!2] 7
[0&!1&2] 8
[0&1&2] 9
[0&!1&2] 10
[0&1&!2] 11
[0&!1&!2] 12
[0&!1&!2] 13
State: 4
[!0&1&2] 3
[!0&!1&2] 4
[!0&!2] 5
[!0&1&!2] 6
[0&1&!2] 7
[0&!1] 8
[0&1&2] 9
[0&!1&2] 10
[0&1&!2] 11
[0&!1&!2] 12
[0&!1&!2] 14
[!0&!1&!2] 15
State: 5
[!0&1&2] 3
[!0&!1&2] 4
[!0&!2] 5
[0&!1&2] 8
[0&1&2] 9
[0&!1&2] 10
[0&1&!2] 11
[0&!1&!2] 12
[0&!1&!2] 13
State: 6
[!0&!2] 6
[0&!2] 7
State: 7
[!2] 7 {0 1}
State: 8
[!1] 8 {0 1}
State: 9
[!2] 7
[!1&2] 8
[1&2] 9
[!1&2] 10
[1&!2] 11
[!1&!2] 12
[!1&!2] 13
State: 10
[1&!2] 7
[1&2] 9
[!1&2] 10
[1&!2] 11
[!1&!2] 12
[!1&!2] 14
State: 11
[!1&2] 8
[1&2] 9
[!1&2] 10
[1&!2] 11
[!1&!2] 12
[!1&!2] 13
State: 12
[1&2] 9
[!1&2] 10
[1&!2] 11
[!1&!2] 12
State: 13
[!1&2] 8
[!1&!2] 13
State: 14
[1&!2] 7
[!1&!2] 14
State: 15
[!0&1&!2] 6
[0&1&!2] 7
[0&!1&!2] 14
[!0&!1&!2] 15
[0&!1&!2] 16
State: 16
[!1&!2] 16 {0 1}
--END--
#+END_SRC
#+end_SRC
* C++
@ -76,7 +162,7 @@ into a BDD, use the =bdd_dict::varnum()= method to obtain the
corresponding BDD variable number, and then use for instance
=bdd_ithvar()= to convert this BDD variable number into an actual BDD.
#+BEGIN_SRC C++ :results verbatim :exports both
#+BEGIN_SRC C++
#include <string>
#include <iostream>
#include <spot/parseaut/public.hh>
@ -163,12 +249,286 @@ corresponding BDD variable number, and then use for instance
#+END_SRC
#+RESULTS:
#+begin_example
Acceptance: Inf(0)&Inf(1)
Number of sets: 2
Number of states: 17
Number of edges: 80
Initial state: 0
Atomic propositions: a (=0) b (=1) c (=2)
Name: F(a | G(Fb & Fc))
Complete: no
Deterministic: no
Unambiguous: yes
State-Based Acc: maybe
Terminal: maybe
Weak: maybe
Inherently Weak: maybe
Stutter Invariant: yes
State 0:
edge(0 -> 1)
label = a
acc sets = {}
edge(0 -> 2)
label = !a
acc sets = {}
edge(0 -> 3)
label = !a & b & c
acc sets = {}
edge(0 -> 4)
label = !a & !b & c
acc sets = {}
edge(0 -> 5)
label = !a & !c
acc sets = {}
edge(0 -> 6)
label = !a & !c
acc sets = {}
State 1:
edge(1 -> 1)
label = 1
acc sets = {0,1}
State 2:
edge(2 -> 2)
label = !b & !c
acc sets = {}
edge(2 -> 2)
label = !b & c
acc sets = {1}
edge(2 -> 2)
label = b & !c
acc sets = {0}
edge(2 -> 2)
label = b & c
acc sets = {0,1}
State 3:
edge(3 -> 3)
label = !a & b & c
acc sets = {}
edge(3 -> 4)
label = !a & !b & c
acc sets = {}
edge(3 -> 5)
label = !a & !c
acc sets = {}
edge(3 -> 6)
label = !a & !c
acc sets = {}
edge(3 -> 7)
label = a & !c
acc sets = {}
edge(3 -> 8)
label = a & !b & c
acc sets = {}
edge(3 -> 9)
label = a & b & c
acc sets = {}
edge(3 -> 10)
label = a & !b & c
acc sets = {}
edge(3 -> 11)
label = a & b & !c
acc sets = {}
edge(3 -> 12)
label = a & !b & !c
acc sets = {}
edge(3 -> 13)
label = a & !b & !c
acc sets = {}
State 4:
edge(4 -> 3)
label = !a & b & c
acc sets = {}
edge(4 -> 4)
label = !a & !b & c
acc sets = {}
edge(4 -> 5)
label = !a & !c
acc sets = {}
edge(4 -> 6)
label = !a & b & !c
acc sets = {}
edge(4 -> 7)
label = a & b & !c
acc sets = {}
edge(4 -> 8)
label = a & !b
acc sets = {}
edge(4 -> 9)
label = a & b & c
acc sets = {}
edge(4 -> 10)
label = a & !b & c
acc sets = {}
edge(4 -> 11)
label = a & b & !c
acc sets = {}
edge(4 -> 12)
label = a & !b & !c
acc sets = {}
edge(4 -> 14)
label = a & !b & !c
acc sets = {}
edge(4 -> 15)
label = !a & !b & !c
acc sets = {}
State 5:
edge(5 -> 3)
label = !a & b & c
acc sets = {}
edge(5 -> 4)
label = !a & !b & c
acc sets = {}
edge(5 -> 5)
label = !a & !c
acc sets = {}
edge(5 -> 8)
label = a & !b & c
acc sets = {}
edge(5 -> 9)
label = a & b & c
acc sets = {}
edge(5 -> 10)
label = a & !b & c
acc sets = {}
edge(5 -> 11)
label = a & b & !c
acc sets = {}
edge(5 -> 12)
label = a & !b & !c
acc sets = {}
edge(5 -> 13)
label = a & !b & !c
acc sets = {}
State 6:
edge(6 -> 6)
label = !a & !c
acc sets = {}
edge(6 -> 7)
label = a & !c
acc sets = {}
State 7:
edge(7 -> 7)
label = !c
acc sets = {0,1}
State 8:
edge(8 -> 8)
label = !b
acc sets = {0,1}
State 9:
edge(9 -> 7)
label = !c
acc sets = {}
edge(9 -> 8)
label = !b & c
acc sets = {}
edge(9 -> 9)
label = b & c
acc sets = {}
edge(9 -> 10)
label = !b & c
acc sets = {}
edge(9 -> 11)
label = b & !c
acc sets = {}
edge(9 -> 12)
label = !b & !c
acc sets = {}
edge(9 -> 13)
label = !b & !c
acc sets = {}
State 10:
edge(10 -> 7)
label = b & !c
acc sets = {}
edge(10 -> 9)
label = b & c
acc sets = {}
edge(10 -> 10)
label = !b & c
acc sets = {}
edge(10 -> 11)
label = b & !c
acc sets = {}
edge(10 -> 12)
label = !b & !c
acc sets = {}
edge(10 -> 14)
label = !b & !c
acc sets = {}
State 11:
edge(11 -> 8)
label = !b & c
acc sets = {}
edge(11 -> 9)
label = b & c
acc sets = {}
edge(11 -> 10)
label = !b & c
acc sets = {}
edge(11 -> 11)
label = b & !c
acc sets = {}
edge(11 -> 12)
label = !b & !c
acc sets = {}
edge(11 -> 13)
label = !b & !c
acc sets = {}
State 12:
edge(12 -> 9)
label = b & c
acc sets = {}
edge(12 -> 10)
label = !b & c
acc sets = {}
edge(12 -> 11)
label = b & !c
acc sets = {}
edge(12 -> 12)
label = !b & !c
acc sets = {}
State 13:
edge(13 -> 8)
label = !b & c
acc sets = {}
edge(13 -> 13)
label = !b & !c
acc sets = {}
State 14:
edge(14 -> 7)
label = b & !c
acc sets = {}
edge(14 -> 14)
label = !b & !c
acc sets = {}
State 15:
edge(15 -> 6)
label = !a & b & !c
acc sets = {}
edge(15 -> 7)
label = a & b & !c
acc sets = {}
edge(15 -> 14)
label = a & !b & !c
acc sets = {}
edge(15 -> 15)
label = !a & !b & !c
acc sets = {}
edge(15 -> 16)
label = a & !b & !c
acc sets = {}
State 16:
edge(16 -> 16)
label = !b & !c
acc sets = {0,1}
#+end_example
* Python
Here is the very same example, but written in Python:
#+BEGIN_SRC python :results output :exports both
#+BEGIN_SRC python
import spot
@ -215,12 +575,12 @@ Here is the very same example, but written in Python:
#+begin_example
Acceptance: Inf(0)&Inf(1)
Number of sets: 2
Number of states: 4
Number of states: 17
Initial states: 0
Atomic propositions: a (=0) b (=1) c (=2)
Name: Fa | G(Fb & Fc)
Name: F(a | G(Fb & Fc))
Deterministic: no
Unambiguous: maybe
Unambiguous: yes
State-Based Acc: maybe
Terminal: maybe
Weak: maybe
@ -234,35 +594,257 @@ State 0:
label = !a
acc sets = {}
edge(0 -> 3)
label = !a
label = !a & b & c
acc sets = {}
edge(0 -> 4)
label = !a & !b & c
acc sets = {}
edge(0 -> 5)
label = !a & !c
acc sets = {}
edge(0 -> 6)
label = !a & !c
acc sets = {}
State 1:
edge(1 -> 1)
label = 1
acc sets = {0,1}
State 2:
edge(2 -> 1)
label = a
edge(2 -> 2)
label = !b & !c
acc sets = {}
edge(2 -> 2)
label = !a
acc sets = {}
label = !b & c
acc sets = {1}
edge(2 -> 2)
label = b & !c
acc sets = {0}
edge(2 -> 2)
label = b & c
acc sets = {0,1}
State 3:
edge(3 -> 3)
label = !a & b & c
acc sets = {0,1}
edge(3 -> 3)
acc sets = {}
edge(3 -> 4)
label = !a & !b & c
acc sets = {1}
edge(3 -> 3)
acc sets = {}
edge(3 -> 5)
label = !a & !c
acc sets = {}
edge(3 -> 6)
label = !a & !c
acc sets = {}
edge(3 -> 7)
label = a & !c
acc sets = {}
edge(3 -> 8)
label = a & !b & c
acc sets = {}
edge(3 -> 9)
label = a & b & c
acc sets = {}
edge(3 -> 10)
label = a & !b & c
acc sets = {}
edge(3 -> 11)
label = a & b & !c
acc sets = {}
edge(3 -> 12)
label = a & !b & !c
acc sets = {}
edge(3 -> 13)
label = a & !b & !c
acc sets = {}
State 4:
edge(4 -> 3)
label = !a & b & c
acc sets = {}
edge(4 -> 4)
label = !a & !b & c
acc sets = {}
edge(4 -> 5)
label = !a & !c
acc sets = {}
edge(4 -> 6)
label = !a & b & !c
acc sets = {0}
edge(3 -> 3)
acc sets = {}
edge(4 -> 7)
label = a & b & !c
acc sets = {}
edge(4 -> 8)
label = a & !b
acc sets = {}
edge(4 -> 9)
label = a & b & c
acc sets = {}
edge(4 -> 10)
label = a & !b & c
acc sets = {}
edge(4 -> 11)
label = a & b & !c
acc sets = {}
edge(4 -> 12)
label = a & !b & !c
acc sets = {}
edge(4 -> 14)
label = a & !b & !c
acc sets = {}
edge(4 -> 15)
label = !a & !b & !c
acc sets = {}
State 5:
edge(5 -> 3)
label = !a & b & c
acc sets = {}
edge(5 -> 4)
label = !a & !b & c
acc sets = {}
edge(5 -> 5)
label = !a & !c
acc sets = {}
edge(5 -> 8)
label = a & !b & c
acc sets = {}
edge(5 -> 9)
label = a & b & c
acc sets = {}
edge(5 -> 10)
label = a & !b & c
acc sets = {}
edge(5 -> 11)
label = a & b & !c
acc sets = {}
edge(5 -> 12)
label = a & !b & !c
acc sets = {}
edge(5 -> 13)
label = a & !b & !c
acc sets = {}
State 6:
edge(6 -> 6)
label = !a & !c
acc sets = {}
edge(6 -> 7)
label = a & !c
acc sets = {}
State 7:
edge(7 -> 7)
label = !c
acc sets = {0,1}
State 8:
edge(8 -> 8)
label = !b
acc sets = {0,1}
State 9:
edge(9 -> 7)
label = !c
acc sets = {}
edge(9 -> 8)
label = !b & c
acc sets = {}
edge(9 -> 9)
label = b & c
acc sets = {}
edge(9 -> 10)
label = !b & c
acc sets = {}
edge(9 -> 11)
label = b & !c
acc sets = {}
edge(9 -> 12)
label = !b & !c
acc sets = {}
edge(9 -> 13)
label = !b & !c
acc sets = {}
State 10:
edge(10 -> 7)
label = b & !c
acc sets = {}
edge(10 -> 9)
label = b & c
acc sets = {}
edge(10 -> 10)
label = !b & c
acc sets = {}
edge(10 -> 11)
label = b & !c
acc sets = {}
edge(10 -> 12)
label = !b & !c
acc sets = {}
edge(10 -> 14)
label = !b & !c
acc sets = {}
State 11:
edge(11 -> 8)
label = !b & c
acc sets = {}
edge(11 -> 9)
label = b & c
acc sets = {}
edge(11 -> 10)
label = !b & c
acc sets = {}
edge(11 -> 11)
label = b & !c
acc sets = {}
edge(11 -> 12)
label = !b & !c
acc sets = {}
edge(11 -> 13)
label = !b & !c
acc sets = {}
State 12:
edge(12 -> 9)
label = b & c
acc sets = {}
edge(12 -> 10)
label = !b & c
acc sets = {}
edge(12 -> 11)
label = b & !c
acc sets = {}
edge(12 -> 12)
label = !b & !c
acc sets = {}
State 13:
edge(13 -> 8)
label = !b & c
acc sets = {}
edge(13 -> 13)
label = !b & !c
acc sets = {}
State 14:
edge(14 -> 7)
label = b & !c
acc sets = {}
edge(14 -> 14)
label = !b & !c
acc sets = {}
State 15:
edge(15 -> 6)
label = !a & b & !c
acc sets = {}
edge(15 -> 7)
label = a & b & !c
acc sets = {}
edge(15 -> 14)
label = a & !b & !c
acc sets = {}
edge(15 -> 15)
label = !a & !b & !c
acc sets = {}
edge(15 -> 16)
label = a & !b & !c
acc sets = {}
State 16:
edge(16 -> 16)
label = !b & !c
acc sets = {0,1}
#+end_example
#+BEGIN_SRC sh :results silent :exports results
rm -f tut21.hoa
#+END_SRC

View file

@ -3,6 +3,8 @@
#+DESCRIPTION: Code example for constructing ω-automata in Spot
#+INCLUDE: setup.org
#+HTML_LINK_UP: tut.html
#+PROPERTY: header-args:python :results output :exports both :wrap SRC hoa
#+PROPERTY: header-args:C+++ :results verbatim :exports both :wrap SRC hoa
This example demonstrates how to create an automaton and then print it.
@ -19,7 +21,7 @@ automata in Spot.
:CUSTOM_ID: cpp
:END:
#+BEGIN_SRC C++ :results verbatim :exports both :wrap SRC hoa
#+BEGIN_SRC C++
#include <iostream>
#include <spot/twaalgos/hoa.hh>
#include <spot/twa/twagraph.hh>
@ -63,7 +65,7 @@ automata in Spot.
#+END_SRC
#+RESULTS:
#+BEGIN_SRC hoa
#+begin_SRC hoa
HOA: v1
States: 3
Start: 0
@ -80,11 +82,11 @@ State: 1
State: 2
[0 | 1] 1 {0 1}
--END--
#+END_SRC
#+end_SRC
** Python
#+BEGIN_SRC python :results output :exports both :wrap SRC hoa
#+BEGIN_SRC python
import spot
import buddy
@ -124,7 +126,7 @@ State: 2
#+END_SRC
#+RESULTS:
#+BEGIN_SRC hoa
#+begin_SRC hoa
HOA: v1
States: 3
Start: 0
@ -141,7 +143,7 @@ State: 1
State: 2
[0 | 1] 1 {0 1}
--END--
#+END_SRC
#+end_SRC
* Büchi automaton, with state-based acceptance
:PROPERTIES:
@ -172,7 +174,7 @@ whenever possible".
** C++
#+BEGIN_SRC C++ :results verbatim :exports both :wrap SRC hoa
#+BEGIN_SRC C++
#include <iostream>
#include <spot/twaalgos/hoa.hh>
#include <spot/twa/twagraph.hh>
@ -240,7 +242,7 @@ State: 2
** Python
#+BEGIN_SRC python :results output :exports both :wrap SRC hoa
#+BEGIN_SRC python
import spot
import buddy
@ -313,7 +315,7 @@ Arbitrary acceptance condition can be set with =set_acceptance=.
** C++
#+BEGIN_SRC C++ :results verbatim :exports both :wrap SRC hoa
#+BEGIN_SRC C++
#include <iostream>
#include <spot/twaalgos/hoa.hh>
#include <spot/twa/twagraph.hh>
@ -362,7 +364,7 @@ State: 2
** Python
#+BEGIN_SRC python :results output :exports both :wrap SRC hoa
#+BEGIN_SRC python
import spot
import buddy
@ -384,3 +386,22 @@ State: 2
print(aut.to_str('hoa'))
#+END_SRC
#+RESULTS:
#+begin_SRC hoa
HOA: v1
States: 3
Start: 0
AP: 2 "p1" "p2"
Acceptance: 3 (Inf(0) & Fin(1)) | Fin(2)
properties: trans-labels explicit-labels trans-acc
--BODY--
State: 0
[0] 1
State: 1
[0&1] 1 {0}
[1] 2 {1}
State: 2
[0 | 1] 1 {0 2}
--END--
#+end_SRC

View file

@ -3,12 +3,15 @@
#+DESCRIPTION: Code example for constructing alternating ω-automata in Spot
#+INCLUDE: setup.org
#+HTML_LINK_UP: tut.html
#+PROPERTY: header-args:sh :results verbatim :exports both
#+PROPERTY: header-args:python :results output :exports both
#+PROPERTY: header-args:C+++ :results verbatim :exports both
This example demonstrates how to create the following alternating
co-Büchi automaton (recognizing =GFa=) and then print it.
#+NAME: tut23-dot
#+BEGIN_SRC sh :results verbatim :exports none :var txt=tut23-cpp
#+BEGIN_SRC sh :exports none :var txt=tut23-cpp
autfilt --dot <<EOF
$txt
EOF
@ -33,7 +36,7 @@ edges (declared with =new_edge()=) and universal edges (declared with
:END:
#+NAME: tut23-cpp
#+BEGIN_SRC C++ :results verbatim :exports both :wrap SRC hoa
#+BEGIN_SRC C++ :wrap SRC hoa
#include <iostream>
#include <spot/twaalgos/hoa.hh>
#include <spot/twa/twagraph.hh>
@ -80,15 +83,15 @@ edges (declared with =new_edge()=) and universal edges (declared with
#+END_SRC
#+RESULTS: tut23-cpp
#+BEGIN_SRC hoa
#+begin_SRC hoa
HOA: v1
States: 3
Start: 0
AP: 1 "a"
acc-name: co-Buchi
Acceptance: 1 Fin(0)
properties: univ-branch trans-labels explicit-labels trans-acc complete
properties: deterministic
properties: trans-labels explicit-labels trans-acc complete
properties: deterministic univ-branch
--BODY--
State: 0
[0] 0
@ -99,11 +102,11 @@ State: 1
State: 2
[t] 2
--END--
#+END_SRC
#+end_SRC
* Python
#+BEGIN_SRC python :results output :exports both :wrap SRC hoa
#+BEGIN_SRC python :wrap SRC hoa
import spot
import buddy

View file

@ -3,6 +3,8 @@
#+DESCRIPTION: Code example for iterating of alternating ω-automata in Spot
#+INCLUDE: setup.org
#+HTML_LINK_UP: tut.html
#+PROPERTY: header-args:python :results output :exports both
#+PROPERTY: header-args:C+++ :results verbatim :noweb strip-export
Alternating automata can be explored in a very similar way as
non-alternating automata. Most of the code from our [[file:tut21.org][custom automaton
@ -54,7 +56,7 @@ and that we run the following code, similar to what we did in the
[[file:tut21.org][custom automaton printer]].
#+NAME: nonalt-body
#+BEGIN_SRC C++
#+BEGIN_SRC C++ :export code
std::cout << "Initial state: " << aut->get_init_state_number() << '\n';
const spot::bdd_dict_ptr& dict = aut->get_dict();
@ -98,7 +100,7 @@ for (unsigned s = 0; s < n; ++s)
#+END_SRC
#+NAME: nonalt-one
#+BEGIN_SRC C++ :exports none :noweb strip-export :results verbatim
#+BEGIN_SRC C++ :exports none
<<nonalt-main>>
void custom_print(spot::twa_graph_ptr& aut)
{
@ -136,7 +138,7 @@ unconditionally. In this example, we simply call =is_univ_dest()= to
decide whether to enclose the destinations in braces.
#+NAME: nonalt-body2
#+BEGIN_SRC C++
#+BEGIN_SRC C++ :export code
unsigned init = aut->get_init_state_number();
std::cout << "Initial state:";
if (aut->is_univ_dest(init))
@ -169,7 +171,7 @@ decide whether to enclose the destinations in braces.
#+END_SRC
#+NAME: nonalt-two
#+BEGIN_SRC C++ :exports none :noweb strip-export :results verbatim
#+BEGIN_SRC C++ :exports none
<<nonalt-main>>
void custom_print(spot::twa_graph_ptr& aut)
{
@ -187,27 +189,27 @@ decide whether to enclose the destinations in braces.
Here is the Python version of this code:
#+BEGIN_SRC python :results output :exports both
import spot
#+BEGIN_SRC python
import spot
aut = spot.automaton("tut24.hoa")
aut = spot.automaton("tut24.hoa")
bdict = aut.get_dict()
init = aut.get_init_state_number()
ui = aut.is_univ_dest(init)
print("Initial states: {}{}{}".format("{ " if ui else "",
" ".join(map(str, aut.univ_dests(init))),
" }" if ui else ""))
for s in range(0, aut.num_states()):
print("State {}:".format(s))
for t in aut.out(s):
ud = aut.is_univ_dest(t)
print(" edge({} -> {}{}{})".format(t.src,
"{ " if ud else "",
" ".join(map(str, aut.univ_dests(t))),
" }" if ud else ""))
print(" label =", spot.bdd_format_formula(bdict, t.cond))
print(" acc sets =", t.acc)
bdict = aut.get_dict()
init = aut.get_init_state_number()
ui = aut.is_univ_dest(init)
print("Initial states: {}{}{}".format("{ " if ui else "",
" ".join(map(str, aut.univ_dests(init))),
" }" if ui else ""))
for s in range(0, aut.num_states()):
print("State {}:".format(s))
for t in aut.out(s):
ud = aut.is_univ_dest(t)
print(" edge({} -> {}{}{})".format(t.src,
"{ " if ud else "",
" ".join(map(str, aut.univ_dests(t))),
" }" if ud else ""))
print(" label =", spot.bdd_format_formula(bdict, t.cond))
print(" acc sets =", t.acc)
#+END_SRC
#+RESULTS:

View file

@ -3,17 +3,18 @@
#+DESCRIPTION: Code example for converting ω-automata in Spot
#+INCLUDE: setup.org
#+HTML_LINK_UP: tut.html
#+PROPERTY: header-args:sh :results verbatim :exports both
#+PROPERTY: header-args:python :results output :exports both
#+PROPERTY: header-args:C+++ :results verbatim :exports both
Consider the following Rabin automaton, generated by =ltl2dstar=:
#+BEGIN_SRC sh :results silent :exports both
#+BEGIN_SRC sh :results silent
ltldo ltl2dstar -f 'F(Xp1 xor XXp1)' > tut30.hoa
#+END_SRC
#+RESULTS:
#+NAME: tut30in
#+BEGIN_SRC sh :results verbatim :exports none
#+BEGIN_SRC sh :exports none
autfilt tut30.hoa --dot
#+END_SRC
@ -39,11 +40,11 @@ not only be changed to Büchi, but simplification routines (useless
SCCs removal, simulation-based reductions, acceptance sets
simplifications, WDBA-minimization, ...) will also be applied.
#+BEGIN_SRC sh :results verbatim :exports both :wrap SRC hoa
#+BEGIN_SRC sh :wrap SRC hoa
autfilt -B -D tut30.hoa
#+END_SRC
#+RESULTS:
#+BEGIN_SRC hoa
#+begin_SRC hoa
HOA: v1
States: 5
Start: 1
@ -51,7 +52,7 @@ AP: 1 "p1"
acc-name: Buchi
Acceptance: 1 Inf(0)
properties: trans-labels explicit-labels state-acc complete
properties: deterministic weak
properties: deterministic very-weak
--BODY--
State: 0 {0}
[t] 0
@ -67,40 +68,13 @@ State: 4
[!0] 0
[0] 4
--END--
#+END_SRC
#+end_SRC
#+NAME: tut30out
#+BEGIN_SRC sh :results verbatim :exports none
#+BEGIN_SRC sh :exports none
autfilt -B -D -d tut30.hoa
#+END_SRC
#+RESULTS: tut30out
#+begin_example
digraph G {
rankdir=LR
node [shape="circle"]
fontname="Lato"
node [fontname="Lato"]
edge [fontname="Lato"]
node[style=filled, fillcolor="#ffffa0"] edge[arrowhead=vee, arrowsize=.7]
I [label="", style=invis, width=0]
I -> 1
0 [label="0", peripheries=2]
0 -> 0 [label=<1>]
1 [label="1"]
1 -> 2 [label=<1>]
2 [label="2"]
2 -> 3 [label=<!p1>]
2 -> 4 [label=<p1>]
3 [label="3"]
3 -> 0 [label=<p1>]
3 -> 3 [label=<!p1>]
4 [label="4"]
4 -> 0 [label=<!p1>]
4 -> 4 [label=<p1>]
}
#+end_example
#+BEGIN_SRC dot :file tut30out.svg :var txt=tut30out :exports results
$txt
#+END_SRC
@ -118,7 +92,7 @@ the result further.
The Python version uses the =postprocess()= routine:
#+BEGIN_SRC python :results output :exports both :wrap SRC hoa
#+BEGIN_SRC python :wrap SRC hoa
import spot
aut = spot.automaton('tut30.hoa').postprocess('BA', 'deterministic')
print(aut.to_str('hoa'))
@ -153,7 +127,7 @@ State: 4
The =postprocess()= function has an interface similar to
[[file:tut10.org][the =translate()= function discussed previously]]:
#+BEGIN_SRC python :results output :exports both
#+BEGIN_SRC python
import spot
help(spot.postprocess)
#+END_SRC
@ -162,7 +136,7 @@ help(spot.postprocess)
#+begin_example
Help on function postprocess in module spot:
postprocess(automaton, *args)
postprocess(automaton, *args, formula=None, xargs=None)
Post process an automaton.
This applies a number of simlification algorithms, depending on
@ -171,17 +145,29 @@ postprocess(automaton, *args)
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 'Generic', 'TGBA', 'BA', or 'Monitor',
'parity', 'parity min odd', 'parity min even',
'parity max odd', 'parity max even' (type of automaton to
build), 'coBuchi'
- 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)
- any combination of 'Complete', 'StateBasedAcceptance'
(or 'SBAcc' for short), and 'Colored (only for parity
acceptance)
The default corresponds to 'generic', 'small' and 'high'.
If a formula denoted by this automaton is known, pass it to as the
optional `formula` argument; it can help some algorithms by
providing an easy way to complement the automaton.
Additional options can be supplied using a `spot.option_map`, or a
string (that will be converted to `spot.option_map`), as the `xargs`
argument. This is similar to the `-x` option of command-line tools;
so check out the spot-x(7) man page for details.
#+end_example
@ -192,7 +178,7 @@ The C++ version of this code is a bit more verbose, because the
=postprocessor= object, configure it, and then call it for each
automaton to process.
#+BEGIN_SRC C++ :results verbatim :exports both :wrap SRC hoa
#+BEGIN_SRC C++ :wrap SRC hoa
#include <iostream>
#include <spot/parseaut/public.hh>
#include <spot/twaalgos/postproc.hh>
@ -219,7 +205,7 @@ automaton to process.
#+END_SRC
#+RESULTS:
#+BEGIN_SRC hoa
#+begin_SRC hoa
HOA: v1
States: 5
Start: 1
@ -227,7 +213,7 @@ AP: 1 "p1"
acc-name: Buchi
Acceptance: 1 Inf(0)
properties: trans-labels explicit-labels state-acc complete
properties: deterministic weak
properties: deterministic very-weak
--BODY--
State: 0 {0}
[t] 0
@ -243,8 +229,8 @@ State: 4
[!0] 0
[0] 4
--END--
#+END_SRC
#+end_SRC
#+BEGIN_SRC sh :results silent :exports results
#+BEGIN_SRC sh :results silent
rm -f tut30.hoa
#+END_SRC

View file

@ -3,6 +3,9 @@
#+DESCRIPTION: Code example for removing alternation in Spot
#+INCLUDE: setup.org
#+HTML_LINK_UP: tut.html
#+PROPERTY: header-args:sh :results verbatim :exports both
#+PROPERTY: header-args:python :results output :exports both
#+PROPERTY: header-args:C+++ :results verbatim :exports both
Consider the following alternating co-Büchi automaton (see [[file:tut23.org][how to
create it]]):
@ -30,7 +33,7 @@ State: 2
#+END_SRC
#+NAME: tut31dot
#+BEGIN_SRC sh :results verbatim :exports none :noweb strip-export
#+BEGIN_SRC sh :exports none :noweb strip-export
cat >tut31.hoa <<EOF
<<tut31in>>
EOF
@ -58,7 +61,7 @@ if the input is [[file:concepts.org::#property-flags][very-weak]].
We simply use =autfilt= with option =--tgba=:
#+BEGIN_SRC sh :results verbatim :exports both :wrap SRC hoa
#+BEGIN_SRC sh :wrap SRC hoa
autfilt --tgba tut31.hoa
#+END_SRC
#+RESULTS:
@ -82,7 +85,7 @@ State: 1
#+END_SRC
#+NAME: tut31out
#+BEGIN_SRC sh :results verbatim :exports none
#+BEGIN_SRC sh :exports none
autfilt --tgba -d tut31.hoa
#+END_SRC
@ -97,13 +100,13 @@ $txt
In the Python version we call =remove_alternation()=
#+BEGIN_SRC python :results output :exports both :wrap SRC hoa
#+BEGIN_SRC python :wrap SRC hoa
import spot
aut = spot.remove_alternation(spot.automaton('tut31.hoa'))
print(aut.to_str('hoa'))
#+END_SRC
#+RESULTS:
#+BEGIN_SRC hoa
#+begin_SRC hoa
HOA: v1
States: 2
Start: 0
@ -115,18 +118,18 @@ properties: deterministic
--BODY--
State: 0
[0] 0 {0}
[!0] 1 {0}
[!0] 1
State: 1
[0] 0 {0}
[!0] 1
--END--
#+END_SRC
#+end_SRC
* C++
The C++ version calls =remove_alternation()= too.
#+BEGIN_SRC C++ :results verbatim :exports both :wrap SRC hoa
#+BEGIN_SRC C++ :wrap SRC hoa
#include <iostream>
#include <spot/parseaut/public.hh>
#include <spot/twaalgos/alternation.hh>
@ -149,7 +152,7 @@ The C++ version calls =remove_alternation()= too.
#+END_SRC
#+RESULTS:
#+BEGIN_SRC hoa
#+begin_SRC hoa
HOA: v1
States: 2
Start: 0
@ -161,13 +164,13 @@ properties: deterministic
--BODY--
State: 0
[0] 0 {0}
[!0] 1 {0}
[!0] 1
State: 1
[0] 0 {0}
[!0] 1
--END--
#+END_SRC
#+end_SRC
#+BEGIN_SRC sh :results silent :exports results
#+BEGIN_SRC sh :results silent
rm -f tut31.hoa
#+END_SRC

View file

@ -3,6 +3,7 @@
#+DESCRIPTION: Explanation of the explicit and on-the-fly automata interfaces in Spot
#+INCLUDE: setup.org
#+HTML_LINK_UP: tut.html
#+PROPERTY: header-args:C+++ :results verbatim :exports both
When exploring automata (i.e., following its transition structure),
@ -164,7 +165,7 @@ just an index into the state vector of the underlying graph.
From a state number =s=, it is possible to iterate over all successors
by doing a =for= loop on =out(s)=, as in:
#+BEGIN_SRC C++ :results verbatim :exports both
#+BEGIN_SRC C++
#include <iostream>
#include <spot/twa/twagraph.hh>
#include <spot/tl/parse.hh>
@ -188,9 +189,9 @@ by doing a =for= loop on =out(s)=, as in:
#+END_SRC
#+RESULTS:
: 2->0
: 2->1
: 2->2
: 0->0
: 0->1
: 0->2
In the above lines, =aut->out(s)= delegates to
=aut->get_graphs().out(s)= and returns a =state_out<graph_t>=
@ -198,7 +199,7 @@ instance, which is a small temporary object masquerading as an STL
container with =begin()= and =end()= methods. The ranged-for loop
syntax of C++ works exactly as if we had typed
#+BEGIN_SRC C++
#+BEGIN_SRC C++ :exports code
// You could write this, but why not let the compiler do it for you?
// In any case, do not spell out the types of tmp and i, as those
// should be considered internal details.
@ -221,7 +222,7 @@ because the compiler will optimize this away.
In fact after operators are inlined and useless temporary variables
removed, the above loop compiles to something equivalent to this:
#+BEGIN_SRC C++
#+BEGIN_SRC C++ :exports code
// You could also write this lower-level version, and that sometimes
// helps (e.g., if you want to pause the loop and then resume it, as
// we will do later).
@ -252,7 +253,7 @@ we call =dfs_rec()= from the initial state, that function updates a
vector of visited states in order to not visit them twice, and recurse
on all successors of the given state.
#+BEGIN_SRC C++ :results verbatim :exports both
#+BEGIN_SRC C++
#include <iostream>
#include <spot/twa/twagraph.hh>
#include <spot/tl/parse.hh>
@ -301,7 +302,7 @@ on all successors of the given state.
accessible transitions in a "DFS-ish" way, but without producing
exactly the same output as above.
#+BEGIN_SRC C++ :results verbatim :exports both
#+BEGIN_SRC C++
#include <iostream>
#include <stack>
#include <spot/twa/twagraph.hh>
@ -379,7 +380,7 @@ to maintain a stack of edge numbers. Indeed, each edge
stores the number of the next edge leaving the same source
state, so this is enough to remember where we are.
#+BEGIN_SRC C++ :results verbatim :exports both
#+BEGIN_SRC C++
#include <iostream>
#include <stack>
#include <spot/twa/twagraph.hh>
@ -576,7 +577,7 @@ saving a =delete= and =new= pair.
To summarize, here is a crude loop over the successors of the initial
state:
#+BEGIN_SRC C++ :results verbatim :exports both
#+BEGIN_SRC C++
#include <iostream>
#include <spot/twa/twa.hh>
#include <spot/tl/parse.hh>
@ -608,9 +609,9 @@ state:
#+END_SRC
#+RESULTS:
: 2->0
: 2->1
: 2->2
: 0->0
: 0->1
: 0->2
Notice that a =twa_succ_iterator= allows iterating over outgoing
edges, but only offers access to =dst()=, =acc()=, and =cond()= for
@ -628,7 +629,7 @@ However =first()= and =next()= also return a Boolean stating whether
the loop could continue. This allows rewriting the above code as
follows:
#+BEGIN_SRC C++
#+BEGIN_SRC C++ :exports code
void example(spot::const_twa_ptr aut)
{
const spot::state* s = aut->get_init_state();
@ -653,7 +654,7 @@ so we halved to number of virtual calls.
Using C++11's ranged =for= loop, this example can be reduced to the
following equivalent code:
#+BEGIN_SRC C++ :results verbatim :exports both
#+BEGIN_SRC C++
#include <iostream>
#include <spot/twa/twa.hh>
#include <spot/tl/parse.hh>
@ -683,9 +684,9 @@ following equivalent code:
#+END_SRC
#+RESULTS:
: 2->0
: 2->1
: 2->2
: 0->0
: 0->1
: 0->2
This works in a similar way as =out(s)= in the explicit interface.
Calling =aut->succ(s)= creates a fake container
@ -703,7 +704,7 @@ track of the states to =destroy()= them only after we do not need them
anymore. This tracking can be done using the data structure we use to
remember what states we have already seen.
#+BEGIN_SRC C++ :results verbatim :exports both
#+BEGIN_SRC C++
#include <iostream>
#include <unordered_set>
#include <spot/twa/twa.hh>
@ -754,10 +755,10 @@ remember what states we have already seen.
#+END_SRC
#+RESULTS:
: 2->0
: 0->0
: 2->1
: 0->1
: 1->1
: 0->2
: 2->2
** Recursive DFS (v2)
@ -772,7 +773,7 @@ previously (in that case the passed state is destroyed). The
With this class, the recursive code can be simplified down to this:
#+BEGIN_SRC C++ :results verbatim :exports both
#+BEGIN_SRC C++
#include <iostream>
#include <spot/twa/twa.hh>
#include <spot/tl/parse.hh>
@ -809,10 +810,10 @@ With this class, the recursive code can be simplified down to this:
#+END_SRC
#+RESULTS:
: 2->0
: 0->0
: 2->1
: 0->1
: 1->1
: 0->2
: 2->2
Note how this completely hides all the calls to =state::destroy()=.
@ -826,7 +827,7 @@ For a non-recursive version, let us use a stack of
source, so we better store that in the stack as well if we want to
print it.
#+BEGIN_SRC C++ :results verbatim :exports both
#+BEGIN_SRC C++
#include <iostream>
#include <stack>
#include <spot/twa/twa.hh>
@ -883,8 +884,8 @@ print it.
#+END_SRC
#+RESULTS:
: 2->0
: 0->0
: 2->1
: 0->1
: 1->1
: 0->2
: 2->2

View file

@ -114,7 +114,7 @@ experience of updating a couple of projects that are using Spot.
If Spot 1.2.6 was installed in =/usr/local=, its headers are
in =/usr/local/include/spot=. One would to write include statements
such as
#+BEGIN_SRC c++
#+BEGIN_SRC C++
#include <tgba/tgba.hh>
#include <ltl/formula.hh>
#+END_SRC
@ -126,7 +126,7 @@ directory.
If Spot 2.0 is installed in =/usr/local=, its headers are still in
=/usr/local/include/spot= however the =spot/= directory is and should
always be used to refer to the header:
#+BEGIN_SRC c++
#+BEGIN_SRC C++
#include <spot/twa/twa.hh> // the new name of tgba/tgba.hh
#include <spot/tl/formula.hh> // the new name of ltl/formula.hh
#+END_SRC
@ -454,7 +454,7 @@ name:
handle those larger acceptance conditions, or restricted to
generalized Büchi acceptance. The typical way to ensure
that an =input= automaton has generalized Büchi acceptance is
#+BEGIN_SRC c++
#+BEGIN_SRC C++
if (!input->acc().is_generalized_buchi())
throw std::runtime_error
("myalgorithm() can only works with generalized Büchi acceptance");
@ -600,7 +600,6 @@ for (auto i: aut->succ(s))
* Various renamings
:PROPERTIES:
:CUSTOM_ID: renamings
:END:
@ -611,7 +610,7 @@ for (auto i: aut->succ(s))
| old name | new name | comment |
|-------------------------------------------------------------+---------------------------------------------+-----------------------------------------------------------|
| ~dstar_parse()~ | ~parse_aut()~ | single parser for all automata |
| ~dtgba_complement()~ | ~dtwa_complement()~ | |
| ~dtgba_complement()~ | ~dualize()~ | |
| ~dupexp_bfs()~ | | deleted |
| ~dupexp_dfs()~ | ~make_twa_graph()~ | |
| ~format_parse_aut_errors()~ | ~parsed_aut::format_errors()~ | |