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. #+DESCRIPTION: Spot command-line tool for cross-comparing the output of automaton processors.
#+INCLUDE: setup.org #+INCLUDE: setup.org
#+HTML_LINK_UP: tools.html #+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 =autcross= is a tool for cross-comparing the output of tools that
transform automata. It works similarly to [[file:ltlcross.org][=ltlcross=]] except 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 Each tool should be specified as a string that uses some of the
following character sequences: 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' autcross --help | sed -n '/character sequences:/,/^$/p' | sed '1d;$d'
#+END_SRC #+END_SRC
#+RESULTS: #+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 the syntax =ltl2dstar -B --complement-input=yes %H %O=. So to
compare the results of these two tools we could use: 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 | randaut -B -n 3 a b |
autcross 'autfilt --complement %H >%O' 'ltl2dstar --complement-input=yes -B %H %O' autcross 'autfilt --complement %H >%O' 'ltl2dstar --complement-input=yes -B %H %O'
#+END_SRC #+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: #+RESULTS:
#+begin_example #+begin_example
-:1.1-45.7 -:1.1-45.7
Running [A0]: autfilt --complement 'lcr-i0-Nr1xZO' >'lcr-o0-urHakt' Running [A0]: autfilt --complement 'lcr-i0-lOYLT5' >'lcr-o0-HB5WGO'
Running [A1]: ltl2dstar -B --complement-input=yes 'lcr-i0-mmkgH7' 'lcr-o1-ABdm4L' Running [A1]: ltl2dstar --complement-input=yes -B 'lcr-i0-UIX3wx' 'lcr-o1-f8abng'
Performing sanity checks and gathering statistics... Performing sanity checks and gathering statistics...
-:46.1-92.7 -:46.1-92.7
Running [A0]: autfilt --complement 'lcr-i1-5kMYrq' >'lcr-o0-9kvBP4' Running [A0]: autfilt --complement 'lcr-i1-Eq2WdZ' >'lcr-o0-CvfJ4H'
Running [A1]: ltl2dstar -B --complement-input=yes 'lcr-i1-lVlGfJ' 'lcr-o1-BexLFn' Running [A1]: ltl2dstar --complement-input=yes -B 'lcr-i1-736tYq' 'lcr-o1-YvkfS9'
Performing sanity checks and gathering statistics... Performing sanity checks and gathering statistics...
-:93.1-137.7 -:93.1-137.7
Running [A0]: autfilt --complement 'lcr-i2-rjvy61' >'lcr-o0-rKKlxG' Running [A0]: autfilt --complement 'lcr-i2-6ahOMS' >'lcr-o0-HdynHB'
Running [A1]: ltl2dstar -B --complement-input=yes 'lcr-i2-Musr0k' 'lcr-o1-LyAxtZ' Running [A1]: ltl2dstar --complement-input=yes -B 'lcr-i2-9PcREk' 'lcr-o1-XcblC3'
Performing sanity checks and gathering statistics... Performing sanity checks and gathering statistics...
No problem detected. No problem detected.
@ -87,12 +83,12 @@ No problem detected.
In this example, we generate 3 random Büchi automata (because 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 =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 the source location of that automaton (here =-= indicates that the
automaton is read from standard input, and this is followed by automaton is read from standard input, and this is followed by
=beginline.column-endline.colum= specifying the position of that =beginline.column-endline.colum= specifying the position of that
automaton in the input. If the automata had names, they would automaton in the input. If the automata had names, they would be
be displayed as well. displayed as well.
Then, each tool is called using temporary files to exchange the Then, each tool is called using temporary files to exchange the
automata, and the resulting automata are then compared. The last line 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 shorthands are available. Those can be listed with the
=--list-shorthands= option. =--list-shorthands= option.
#+BEGIN_SRC sh :results verbatim :exports both #+BEGIN_SRC sh
autcross --list-shorthands autcross --list-shorthands
#+END_SRC #+END_SRC
#+RESULTS: #+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. the following words, then the string on the right is appended.
autfilt %H>%O autfilt %H>%O
seminator %H>%O dstar2tgba %H>%O
ltl2dstar -B %H %O ltl2dstar -B %H %O
nba2dpa <%H>%O
nba2ldpa <%H>%O nba2ldpa <%H>%O
seminator %H>%O
Any {name} and directory component is skipped for the purpose of Any {name} and directory component is skipped for the purpose of
matching those prefixes. So for instance 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: 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 | randaut -B -n 3 a b |
autcross 'autfilt --complement' 'ltl2dstar --complement-input=yes' autcross 'autfilt --complement' 'ltl2dstar --complement-input=yes'
#+END_SRC #+END_SRC
@ -146,31 +144,26 @@ Second, we pass a =--csv= option to =autcross= to save statistics in a
file. file.
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh :prologue "exec 2>&1"
randaut -B -n 3 a b --name="automaton %L" | randaut -B -n 3 a b --name="automaton %L" |
autcross 'autfilt --complement' 'ltl2dstar --complement-input=yes' --csv=autcross.csv autcross 'autfilt --complement' 'ltl2dstar --complement-input=yes' --csv=autcross.csv
#+END_SRC #+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: #+RESULTS:
#+begin_example #+begin_example
-:1.1-46.7 automaton 0 -:1.1-46.7 automaton 0
Running [A0]: autfilt --complement 'lcr-i0-QHReWu'>'lcr-o0-0eTOmZ' Running [A0]: autfilt --complement 'lcr-i0-YPfmR5'>'lcr-o0-Z1bT0A'
Running [A1]: ltl2dstar --complement-input=yes -B 'lcr-i0-jsoPPt' 'lcr-o1-66bQiY' Running [A1]: ltl2dstar --complement-input=yes -B 'lcr-i0-DpL2i6' 'lcr-o1-gpYcBB'
Performing sanity checks and gathering statistics... Performing sanity checks and gathering statistics...
-:47.1-94.7 automaton 1 -:47.1-94.7 automaton 1
Running [A0]: autfilt --complement 'lcr-i1-IubpMs'>'lcr-o0-dfmYfX' Running [A0]: autfilt --complement 'lcr-i1-mxsGU6'>'lcr-o0-fPCaeC'
Running [A1]: ltl2dstar --complement-input=yes -B 'lcr-i1-13NXLr' 'lcr-o1-zSwXhW' Running [A1]: ltl2dstar --complement-input=yes -B 'lcr-i1-2hgYD7' 'lcr-o1-S4xM3C'
Performing sanity checks and gathering statistics... Performing sanity checks and gathering statistics...
-:95.1-140.7 automaton 2 -:95.1-140.7 automaton 2
Running [A0]: autfilt --complement 'lcr-i2-g5bDOq'>'lcr-o0-X71ilV' Running [A0]: autfilt --complement 'lcr-i2-YU1Qu8'>'lcr-o0-hwVVVD'
Running [A1]: ltl2dstar --complement-input=yes -B 'lcr-i2-og1mUp' 'lcr-o1-QVurtU' Running [A1]: ltl2dstar --complement-input=yes -B 'lcr-i2-MLmVq9' 'lcr-o1-edfVVE'
Performing sanity checks and gathering statistics... Performing sanity checks and gathering statistics...
No problem detected. No problem detected.
@ -178,17 +171,27 @@ No problem detected.
After this execution, the file =autcross.csv= contains the following: After this execution, the file =autcross.csv= contains the following:
#+BEGIN_SRC sh :results verbatim :exports results #+BEGIN_SRC sh :results output raw :exports results
cat autcross.csv sed 's/"//g
1a\
|-|
s/--/@@html:--@@/g
s/^/| /
s/$/ |/
s/,/|/g
' autcross.csv
#+END_SRC #+END_SRC
#+ATTR_HTML: :class csv-table
#+RESULTS: #+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" | 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 | -: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 |
: "-: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 | -: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,0,0,"ltl2dstar --complement-input=yes","ok",0,0.0026184,2,74,268,296,6,2,0,8,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 |
: "-: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 | -: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,0,0,"ltl2dstar --complement-input=yes","ok",0,0.00180888,2,24,74,96,2,4,0,35,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. 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 =ltlcross=, this can be adjusted by using a command specification of
the form ={short name}actual command=. the form ={short name}actual command=.
For instance For instance:
#+NAME: autcross2
#+BEGIN_SRC sh :results verbatim :exports both #+BEGIN_SRC sh :exports code
randaut -B -n 3 a b --name="automaton %L" | randaut -B -n 3 a b --name="automaton %L" |
autcross '{AF}autfilt --complement' '{L2D}ltl2dstar --complement-input=yes' --csv autcross '{AF}autfilt --complement' '{L2D}ltl2dstar --complement-input=yes' --csv
#+END_SRC #+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: #+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" | 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 | -: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 |
: "-: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 | -: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,0,0,"L2D","ok",0,0.00489558,2,74,268,296,6,2,0,20,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 |
: "-: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 | -: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,0,0,"L2D","ok",0,0.00329786,2,24,74,96,2,4,0,23,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 * 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 =autfilt --complement= preserves the input language (clearly it does
not, since it actually complement the language of the automaton). 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" | randaut -B -n 3 a b --name="automaton %L" |
autcross --language-preserved 'autfilt --complement' autcross --language-preserved 'autfilt --complement'
#+END_SRC #+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: #+RESULTS:
#+begin_example #+begin_example
-:1.1-46.7 automaton 0 -: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... Performing sanity checks and gathering statistics...
error: A0*Comp(input) is nonempty; both automata accept the infinite word: 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: error: input*Comp(A0) is nonempty; both automata accept the infinite word:
!a & !b; !a & !b; cycle{!a & !b; !a & b; a & b} !a & !b; !a & !b; cycle{!a & !b; !a & b; a & b}
-:47.1-94.7 automaton 1 -: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... Performing sanity checks and gathering statistics...
error: A0*Comp(input) is nonempty; both automata accept the infinite word: error: A0*Comp(input) is nonempty; both automata accept the infinite word:
!a & b; cycle{a & !b} !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} !a & b; a & !b; cycle{!a & b; a & b}
-:95.1-140.7 automaton 2 -: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... Performing sanity checks and gathering statistics...
error: A0*Comp(input) is nonempty; both automata accept the infinite word: 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: 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} 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 The verbose option can be useful to troubleshoot problems or simply
follow the list of transformations and tests performed by =autcross=. 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" | randaut -B -n 1 a b --name="automaton %L" |
autcross 'autfilt --complement' 'ltl2dstar --complement-input=yes' --verbose autcross 'autfilt --complement' 'ltl2dstar --complement-input=yes' --verbose
#+END_SRC #+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: #+RESULTS:
#+begin_example #+begin_example
-:1.1-46.7 automaton 0 -:1.1-46.7 automaton 0
info: input (10 st.,26 ed.,1 sets) info: input (10 st.,26 ed.,1 sets)
Running [A0]: autfilt --complement 'lcr-i0-oZm5P2'>'lcr-o0-O4P0IB' Running [A0]: autfilt --complement 'lcr-i0-KHA9NI'>'lcr-o0-BSYDwC'
Running [A1]: ltl2dstar --complement-input=yes -B 'lcr-i0-gEwlJa' 'lcr-o1-wSaHJJ' Running [A1]: ltl2dstar --complement-input=yes -B 'lcr-i0-DjL8hw' 'lcr-o1-PASD3p'
info: collected automata: 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 info: A1 (34 st.,121 ed.,6 sets) deterministic complete
Performing sanity checks and gathering statistics... Performing sanity checks and gathering statistics...
info: getting rid of any Fin acceptance... info: getting rid of any Fin acceptance...
info: A0 (27 st.,95 ed.,3 sets) -> (58 st.,203 ed.,2 sets) info: A0 (26 st.,91 ed.,5 sets) -> (83 st.,287 ed.,2 sets)
info: Comp(A0) (27 st.,95 ed.,3 sets) -> (51 st.,188 ed.,1 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: 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: Comp(A1) (34 st.,121 ed.,6 sets) -> (34 st.,121 ed.,1 sets)
info: check_empty A0*Comp(A1) info: check_empty A0*Comp(A1)
@ -380,14 +389,6 @@ info: check_empty A1*Comp(A0)
No problem detected. No problem detected.
#+end_example #+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= * Use-cases for =%M=
If the input automata are named, it is possible to use =%M= in some 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= is not in a syntax supported by =ltl2dstar=, so we call =ltl2dstar=
via [[file:ltldo.org][=ltldo=]] to arrange that. 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 | genltl --eh-patterns=1..3 | ltl2tgba |
autcross 'autfilt -P -D' 'ltldo ltl2dstar -f %M >%O' autcross 'autfilt -P -D' 'ltldo ltl2dstar -f %M >%O'
#+END_SRC #+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: #+RESULTS:
#+begin_example #+begin_example
-:1.1-16.7 p0 U (p1 & Gp2) -:1.1-16.7 p0 U (p1 & Gp2)
Running [A0]: autfilt -P -D 'lcr-i0-rBSCo9'>'lcr-o0-xyRJhy' Running [A0]: autfilt -P -D 'lcr-i0-VyvQVJ'>'lcr-o0-fVtUyh'
Running [A1]: ltldo ltl2dstar -f 'p0 U (p1 & Gp2)' >'lcr-o1-9uDUjX' Running [A1]: ltldo ltl2dstar -f 'p0 U (p1 & Gp2)' >'lcr-o1-4e57fP'
Performing sanity checks and gathering statistics... Performing sanity checks and gathering statistics...
-:17.1-34.7 p0 U (p1 & X(p2 U p3)) -:17.1-34.7 p0 U (p1 & X(p2 U p3))
Running [A0]: autfilt -P -D 'lcr-i1-LFDrvm'>'lcr-o0-6fBZGL' 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-AUXx0a' Running [A1]: ltldo ltl2dstar -f 'p0 U (p1 & X(p2 U p3))' >'lcr-o1-2oVyBs'
Performing sanity checks and gathering statistics... Performing sanity checks and gathering statistics...
-:35.1-64.7 p0 U (p1 & X(p2 & F(p3 & XF(p4 & XF(p5 & XFp6))))) -: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 [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-xhS4Ap' 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... Performing sanity checks and gathering statistics...
No problem detected. No problem detected.
#+end_example #+end_example
This example is a bit contrived, and in this case, an alternative would The previous example was a bit contrived, and in this case, a saner
be to use [[file:ltlcross.org][=ltlcross=]], as in: 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 | genltl --eh-patterns=1..3 |
ltlcross 'ltl2tgba %f | autfilt -P -D > %O' 'ltl2dstar' ltlcross 'ltl2tgba %f | autfilt -P -D > %O' 'ltl2dstar'
#+END_SRC #+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: #+RESULTS:
#+begin_example #+begin_example
-:1: (p0) U ((p1) & (G(p2))) -:1: (p0) U ((p1) & (G(p2)))
Running [P0]: ltl2tgba '(p0) U ((p1) & (G(p2)))' | autfilt -P -D > 'lcr-o0-DnV1rm' Running [P0]: ltl2tgba '(p0) U ((p1) & (G(p2)))' | autfilt -P -D > 'lcr-o0-6iPt1N'
Running [P1]: ltl2dstar --output-format=hoa 'lcr-i0-jBLulv' 'lcr-o1-epwYeE' 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-8bVQ9M' Running [N0]: ltl2tgba '!((p0) U ((p1) & (G(p2))))' | autfilt -P -D > 'lcr-o0-UL2Ju8'
Running [N1]: ltl2dstar --output-format=hoa 'lcr-i0-5oAAdW' 'lcr-o1-W7elh5' Running [N1]: ltl2dstar --output-format=hoa 'lcr-i0-FyS5HU' 'lcr-o1-Xy3rVG'
Performing sanity checks and gathering statistics... Performing sanity checks and gathering statistics...
-:2: (p0) U ((p1) & (X((p2) U (p3)))) -: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 [P0]: ltl2tgba '(p0) U ((p1) & (X((p2) U (p3))))' | autfilt -P -D > 'lcr-o0-3veUbt'
Running [P1]: ltl2dstar --output-format=hoa 'lcr-i1-OJU1Sn' 'lcr-o1-wOCsgx' 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-SzgmFG' Running [N0]: ltl2tgba '!((p0) U ((p1) & (X((p2) U (p3)))))' | autfilt -P -D > 'lcr-o0-imCn9N'
Running [N1]: ltl2dstar --output-format=hoa 'lcr-i1-8iIddQ' 'lcr-o1-zBV5KZ' Running [N1]: ltl2dstar --output-format=hoa 'lcr-i1-Q49LwA' 'lcr-o1-xF2aUm'
Performing sanity checks and gathering statistics... Performing sanity checks and gathering statistics...
-:3: (p0) U ((p1) & (X((p2) & (F((p3) & (X(F((p4) & (X(F((p5) & (X(F(p6)))))))))))))) -: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 [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-E0Ikpj' 'lcr-o1-ppDzlt' 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-jqlelD' 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-IwU1uN' 'lcr-o1-6YdQEX' Running [N1]: ltl2dstar --output-format=hoa 'lcr-i2-1IDzrh' 'lcr-o1-Ck5y13'
Performing sanity checks and gathering statistics... Performing sanity checks and gathering statistics...
No problem detected. No problem detected.
@ -476,3 +467,16 @@ No problem detected.
However in practice you could also use the =name:= field of the input However in practice you could also use the =name:= field of the input
automaton, combined with =%M= in the tool specification, to designate automaton, combined with =%M= in the tool specification, to designate
an alternate filename to load, or some key to look up somewhere. 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. #+DESCRIPTION: Spot command-line tool for filtering, tranforming, and converting ω-automata.
#+INCLUDE: setup.org #+INCLUDE: setup.org
#+HTML_LINK_UP: tools.html #+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. 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=, [[file:oaut.org][the common output options]] like =--spin=, =--lbtt=, =--dot=,
=--stats=... =--stats=...
#+BEGIN_SRC sh :results silent :exports both #+BEGIN_SRC sh :results silent
cat >example.hoa <<EOF cat >example.hoa <<EOF
HOA: v1 HOA: v1
States: 1 States: 1
@ -48,7 +49,7 @@ EOF
autfilt example.hoa --dot autfilt example.hoa --dot
#+END_SRC #+END_SRC
#+BEGIN_SRC sh :results verbatim :exports results #+BEGIN_SRC sh :exports results
SPOT_DOTEXTRA= autfilt example.hoa --dot SPOT_DOTEXTRA= autfilt example.hoa --dot
#+END_SRC #+END_SRC
@ -65,7 +66,7 @@ SPOT_DOTEXTRA= autfilt example.hoa --dot
The =--spin= option implicitly requires a degeneralization: The =--spin= option implicitly requires a degeneralization:
#+BEGIN_SRC sh :results verbatim :exports both #+BEGIN_SRC sh
autfilt example.hoa --spin autfilt example.hoa --spin
#+END_SRC #+END_SRC
@ -87,7 +88,7 @@ T0_S2:
Option =--lbtt= only works for Büchi or generalized Büchi acceptance. 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 autfilt example.hoa --lbtt
#+END_SRC #+END_SRC
@ -106,7 +107,7 @@ automata, and pipe the result into =autfilt= to display various
statistics. statistics.
#+BEGIN_SRC sh :results verbatim :exports both #+BEGIN_SRC sh
randaut -n 10 -A0..2 -Q10..20 -e0.05 2 | randaut -n 10 -A0..2 -Q10..20 -e0.05 2 |
autfilt --stats='%s states, %e edges, %a acc-sets, %c SCCs, det=%d' autfilt --stats='%s states, %e edges, %a acc-sets, %c SCCs, det=%d'
#+END_SRC #+END_SRC
@ -126,7 +127,7 @@ autfilt --stats='%s states, %e edges, %a acc-sets, %c SCCs, det=%d'
#+end_example #+end_example
The following =%= sequences are available: 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' ltl2tgba --help | sed -n '/ sequences:/,/^$/p' | sed '1d;$d'
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
@ -171,6 +172,11 @@ ltl2tgba --help | sed -n '/ sequences:/,/^$/p' | sed '1d;$d'
processes. processes.
%s number of reachable states %s number of reachable states
%t number of reachable transitions %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 %w one word accepted by the output automaton
%x, %[LETTERS]x number of atomic propositions declared in the %x, %[LETTERS]x number of atomic propositions declared in the
automaton; add LETTERS to list atomic automaton; add LETTERS to list atomic
@ -193,7 +199,7 @@ automaton.
=autfilt= offers multiple options to filter automata based on =autfilt= offers multiple options to filter automata based on
different characteristics of the automaton. 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' autfilt --help | sed -n '/Filtering options.*:/,/^$/p' | sed '1d;$d'
#+END_SRC #+END_SRC
#+RESULTS: #+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 --acc-sets=RANGE keep automata whose number of acceptance sets is
in RANGE in RANGE
--accept-word=WORD keep automata that accept WORD --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 --ap=RANGE match automata with a number of (declared) atomic
propositions in RANGE propositions in RANGE
--are-isomorphic=FILENAME keep automata that are isomorphic to the --are-isomorphic=FILENAME keep automata that are isomorphic to the
automaton in FILENAME automaton in FILENAME
--edges=RANGE keep automata whose number of edges is in RANGE --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 (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 --included-in=FILENAME keep automata whose languages are included in that
of the automaton from FILENAME of the automaton from FILENAME
--inherently-weak-sccs=RANGE --inherently-weak-sccs=RANGE
@ -220,14 +232,19 @@ autfilt --help | sed -n '/Filtering options.*:/,/^$/p' | sed '1d;$d'
rejecting cycle. rejecting cycle.
--intersect=FILENAME keep automata whose languages have an non-empty --intersect=FILENAME keep automata whose languages have an non-empty
intersection with the automaton from FILENAME 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-complete keep complete automata
--is-deterministic keep deterministic automata --is-deterministic keep deterministic automata
--is-empty keep automata with an empty language --is-empty keep automata with an empty language
--is-inherently-weak keep only inherently weak automata --is-inherently-weak keep only inherently weak automata
--is-semi-deterministic keep semi-deterministic automata
--is-stutter-invariant keep automata representing stutter-invariant --is-stutter-invariant keep automata representing stutter-invariant
properties properties
--is-terminal keep only terminal automata --is-terminal keep only terminal automata
--is-unambiguous keep only unambiguous automata --is-unambiguous keep only unambiguous automata
--is-very-weak keep only very-weak automata
--is-weak keep only weak automata --is-weak keep only weak automata
--nondet-states=RANGE keep automata whose number of nondeterministic --nondet-states=RANGE keep automata whose number of nondeterministic
states is in RANGE 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. keep the others.
* Simplifying automata * Simplifying automata
:PROPERTIES:
:header-args:sh: :results verbatim :exports results
:END:
The standard set of automata simplification routines (these are often The standard set of automata simplification routines (these are often
referred to as the "post-processing" routines, because these are the 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: 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' autfilt --help | sed -n '/Output automaton type:/,/^$/p' | sed '1d;$d'
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
#+begin_example #+begin_example
-B, --ba Büchi Automaton (with state-based acceptance) -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 -C, --complete output a complete automaton
-G, --generic any acceptance is allowed (default) -G, --generic any acceptance is allowed (default)
-M, --monitor Monitor (accepts all finite prefixes of the given -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: 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' autfilt --help | sed -n '/Simplification goal:/,/^$/p' | sed '1d;$d'
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
: -a, --any no preference, do not bother making it small or : -a, --any no preference, do not bother making it small or
: deterministic : 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 : --small prefer small automata
Finally, the following switches control the amount of effort applied Finally, the following switches control the amount of effort applied
toward the desired goal: toward the desired goal:
#+BEGIN_SRC sh :results verbatim :exports results #+BEGIN_SRC sh
autfilt --help | sed -n '/Simplification level:/,/^$/p' | sed '1d;$d' autfilt --help | sed -n '/Simplification level:/,/^$/p' | sed '1d;$d'
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
@ -374,7 +399,7 @@ set.
The following transformations are available: 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' autfilt --help | sed -n '/Transformations:/,/^$/p' | sed '1d;$d'
#+END_SRC #+END_SRC
@ -383,16 +408,20 @@ autfilt --help | sed -n '/Transformations:/,/^$/p' | sed '1d;$d'
--cleanup-acceptance remove unused acceptance sets from the automaton --cleanup-acceptance remove unused acceptance sets from the automaton
--cnf-acceptance put the acceptance condition in Conjunctive Normal --cnf-acceptance put the acceptance condition in Conjunctive Normal
Form Form
--complement complement each automaton (currently support only --complement complement each automaton (different strategies
deterministic automata) are used)
--complement-acceptance complement the acceptance condition (without --complement-acceptance complement the acceptance condition (without
touching the automaton) touching the automaton)
--decompose-strength=t|w|s extract the (t) terminal, (w) weak, or (s) --decompose-scc=t|w|s|N|aN, --decompose-strength=t|w|s|N|aN
strong part of an automaton (letters may be extract the (t) terminal, (w) weak, or (s) strong
combined to combine more strengths in the output) 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 --destut allow less stuttering
--dnf-acceptance put the acceptance condition in Disjunctive Normal --dnf-acceptance put the acceptance condition in Disjunctive Normal
Form Form
--dualize dualize each automaton
--exclusive-ap=AP,AP,... if any of those APs occur in the automaton, --exclusive-ap=AP,AP,... if any of those APs occur in the automaton,
restrict all edges to ensure two of them may not restrict all edges to ensure two of them may not
be true at the same time. Use this option 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 quantification, or by assigning them 0 or 1
--remove-dead-states remove states that are unreachable, or that cannot --remove-dead-states remove states that are unreachable, or that cannot
belong to an infinite path belong to an infinite path
--remove-fin rewrite the automaton without using Fin --remove-fin rewrite the automaton without using Fin acceptance
acceptance
--remove-unreachable-states --remove-unreachable-states
remove states that are unreachable from the remove states that are unreachable from the
initial state initial state
--remove-unused-ap remove declared atomic propositions that are not --remove-unused-ap remove declared atomic propositions that are not
used used
--sat-minimize[=options] minimize the automaton using a SAT solver --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 --separate-sets if both Inf(x) and Fin(x) appear in the acceptance
condition, replace Fin(x) by a new Fin(y) and condition, replace Fin(x) by a new Fin(y) and
adjust the automaton 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 --simplify-exclusive-ap if --exclusive-ap is used, assume those AP
groups are actually exclusive in the system to groups are actually exclusive in the system to
simplify the expression of transition labels simplify the expression of transition labels
(implies --merge-transitions) (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 --strip-acceptance remove the acceptance condition and all acceptance
sets 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 #+end_example
* Decorations * 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 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=). =--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' autfilt --help | sed -n '/^ *Decorations.*:/,/^$/p' | sed '1d;$d'
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
: --highlight-nondet[=NUM] highlight nondeterministic states and edges #+begin_example
: with color NUM --highlight-accepting-run[=NUM]
: --highlight-nondet-edges[=NUM] highlight one accepting run using color NUM
: highlight nondeterministic edges with color NUM --highlight-languages highlight states that recognize identical
: --highlight-nondet-states[=NUM] languages
: highlight nondeterministic states with color NUM --highlight-nondet[=NUM] highlight nondeterministic states and edges
: --highlight-word=[NUM,]WORD with color NUM
: highlight one run matching WORD using 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 Color numbers are indices in some hard-coded color palette. It is the
same palette that is currently used to display colored acceptance same palette that is currently used to display colored acceptance
@ -476,10 +531,13 @@ sets, but this might change in the future.
* Examples * Examples
** Acceptance transformations ** Acceptance transformations
:PROPERTIES:
:header-args:sh: :results verbatim :exports code
:END:
Here is an automaton with transition-based acceptance: 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 cat >aut-ex1.hoa<<EOF
HOA: v1 HOA: v1
States: 3 States: 3
@ -507,99 +565,24 @@ EOF
discussed [[file:oaut.org::#default-dot][on another page]].) discussed [[file:oaut.org::#default-dot][on another page]].)
#+NAME: autfilt-ex1 #+NAME: autfilt-ex1
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh
autfilt aut-ex1.hoa --dot autfilt aut-ex1.hoa --dot
#+END_SRC #+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 #+BEGIN_SRC dot :file autfilt-ex1.svg :var txt=autfilt-ex1 :exports results
$txt $txt
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
[[file:autfilt-ex1.svgz]] [[file:autfilt-ex1.svg]]
Using =-S= will "push" the acceptance membership of the transitions to the states: Using =-S= will "push" the acceptance membership of the transitions to the states:
#+NAME: autfilt-ex2 #+NAME: autfilt-ex2
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh
autfilt -S aut-ex1.hoa --dot= autfilt -S aut-ex1.hoa --dot
#+END_SRC #+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 #+BEGIN_SRC dot :file autfilt-ex2.svg :var txt=autfilt-ex2 :exports results
$txt $txt
#+END_SRC #+END_SRC
@ -610,37 +593,10 @@ $txt
Using =--cnf-acceptance= simply rewrites the acceptance condition in Conjunctive Normal Form: Using =--cnf-acceptance= simply rewrites the acceptance condition in Conjunctive Normal Form:
#+NAME: autfilt-ex3 #+NAME: autfilt-ex3
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh
autfilt --cnf-acceptance aut-ex1.hoa --dot autfilt --cnf-acceptance aut-ex1.hoa --dot
#+END_SRC #+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 #+BEGIN_SRC dot :file autfilt-ex3.svg :var txt=autfilt-ex3 :exports results
$txt $txt
#+END_SRC #+END_SRC
@ -654,40 +610,10 @@ of Fin-acceptance: this usually requires adding non-deterministic jumps to
altered copies of strongly-connected components. altered copies of strongly-connected components.
#+NAME: autfilt-ex4 #+NAME: autfilt-ex4
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh
autfilt --remove-fin aut-ex1.hoa --dot autfilt --remove-fin aut-ex1.hoa --dot
#+END_SRC #+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 #+BEGIN_SRC dot :file autfilt-ex4.svg :var txt=autfilt-ex4 :exports results
$txt $txt
#+END_SRC #+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. reflect the fact that these sets can never be visited.
#+NAME: autfilt-ex5 #+NAME: autfilt-ex5
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh
autfilt --mask-acc=1,2 aut-ex1.hoa --dot autfilt --mask-acc=1,2 aut-ex1.hoa --dot
#+END_SRC #+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 #+BEGIN_SRC dot :file autfilt-ex5.svg :var txt=autfilt-ex5 :exports results
$txt $txt
#+END_SRC #+END_SRC
@ -737,6 +638,9 @@ $txt
[[file:autfilt-ex5.svg]] [[file:autfilt-ex5.svg]]
** Atomic proposition removal ** Atomic proposition removal
:PROPERTIES:
:header-args:sh: :results verbatim :exports code
:END:
Atomic propositions can be removed from an automaton in three ways: 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. - 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: Here are the results of these three options on our example:
#+NAME: autfilt-ex6a #+NAME: autfilt-ex6a
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh
autfilt --remove-ap=a aut-ex1.hoa --dot autfilt --remove-ap=a aut-ex1.hoa --dot
#+END_SRC #+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 #+BEGIN_SRC dot :file autfilt-ex6a.svg :var txt=autfilt-ex6a :exports results
$txt $txt
#+END_SRC #+END_SRC
@ -786,31 +663,10 @@ $txt
[[file:autfilt-ex6a.svg]] [[file:autfilt-ex6a.svg]]
#+NAME: autfilt-ex6b #+NAME: autfilt-ex6b
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh
autfilt --remove-ap=a=0 aut-ex1.hoa --dot autfilt --remove-ap=a=0 aut-ex1.hoa --dot
#+END_SRC #+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 #+BEGIN_SRC dot :file autfilt-ex6b.svg :var txt=autfilt-ex6b :exports results
$txt $txt
#+END_SRC #+END_SRC
@ -819,12 +675,10 @@ $txt
[[file:autfilt-ex6b.svg]] [[file:autfilt-ex6b.svg]]
#+NAME: autfilt-ex6c #+NAME: autfilt-ex6c
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh
autfilt --remove-ap=a=1 aut-ex1.hoa --dot autfilt --remove-ap=a=1 aut-ex1.hoa --dot
#+END_SRC #+END_SRC
#+RESULTS: autfilt-ex6c
#+BEGIN_SRC dot :file autfilt-ex6c.svg :var txt=autfilt-ex6c :exports results #+BEGIN_SRC dot :file autfilt-ex6c.svg :var txt=autfilt-ex6c :exports results
$txt $txt
#+END_SRC #+END_SRC
@ -833,11 +687,15 @@ $txt
[[file:autfilt-ex6c.svg]] [[file:autfilt-ex6c.svg]]
** Testing word acceptance ** 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 following example checks whether the formula ~a U b U c~ accepts
the word ~a&!b&!c; cycle{!a&!b&c}~. 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' | ltl2tgba 'a U b U c' |
autfilt --accept-word 'a&!b&!c; cycle{!a&!b&c}' -q && echo "word accepted" autfilt --accept-word 'a&!b&!c; cycle{!a&!b&c}' -q && echo "word accepted"
#+END_SRC #+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 of the form =cycle{b}=, and display the associated formula (which was
stored as the name of the automaton by =ltl2tgba=). 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 | randltl -n -1 a b | ltlfilt --simplify --uniq | ltl2tgba |
autfilt --accept-word='a&!b;cycle{!a&!b}' --accept-word='!a&!b;cycle{a&b}' \ autfilt --accept-word='a&!b;cycle{!a&!b}' --accept-word='!a&!b;cycle{a&b}' \
--reject-word='cycle{b}' --stats=%M -n 10 --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 example Here is a list of 5 LTL formulas that =ltl2dstar= converts to
Rabin automata that have exactly 4 states: 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 | randltl -n -1 a b | ltlfilt --simplify --remove-wm |
ltldo ltl2dstar --name=%f | autfilt --states=4 --stats=%M -n 5 ltldo ltl2dstar --name=%f | autfilt --states=4 --stats=%M -n 5
#+END_SRC #+END_SRC
@ -895,7 +753,7 @@ randltl -n -1 a b | ltlfilt --simplify --remove-wm |
** Decorations ** Decorations
:PROPERTIES: :PROPERTIES:
:CUSTOM_ID: decorations :header-args:sh: :results verbatim :exports code
:END: :END:
We know from a previous exemple that formula =a U b U c= accepts the 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: run in the automaton:
#+NAME: highlight-word #+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 ltl2tgba 'a U b U c' | autfilt --highlight-word='a&!b&!c; cycle{!a&!b&c}' -d
#+END_SRC #+END_SRC
@ -945,7 +803,7 @@ transition may only have one color so late highlights will overwrite
previous ones. previous ones.
#+NAME: highlight-word2 #+NAME: highlight-word2
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh
ltl2tgba 'a U b U c' | ltl2tgba 'a U b U c' |
autfilt --highlight-word=5,'a&!b&!c; cycle{!a&!b&c}' \ autfilt --highlight-word=5,'a&!b&!c; cycle{!a&!b&c}' \
--highlight-word=4,'!a&b&!c; cycle{!a&!b&c}' -d --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. made.
#+NAME: highlight-nondet #+NAME: highlight-nondet
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh
ltl2tgba 'F((b R a) W Gb)' | ltl2tgba 'F((b R a) W Gb)' |
autfilt --highlight-nondet-states=5 --highlight-nondet-edges=1 -d autfilt --highlight-nondet-states=5 --highlight-nondet-edges=1 -d
#+END_SRC #+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 #+BEGIN_SRC dot :file autfilt-hlnondet.svg :var txt=highlight-nondet :exports results
$txt $txt
#+END_SRC #+END_SRC

View file

@ -3,6 +3,7 @@
#+DESCRIPTION: How to compile C++14 programs using Spot #+DESCRIPTION: How to compile C++14 programs using Spot
#+INCLUDE: setup.org #+INCLUDE: setup.org
#+HTML_LINK_UP: tut.html #+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 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 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=: file called =hello.cc=:
#+NAME: hello-word #+NAME: hello-word
#+BEGIN_SRC C++ :results verbatim :exports both #+BEGIN_SRC C++
#include <iostream> #include <iostream>
#include <spot/misc/version.hh> #include <spot/misc/version.hh>
@ -30,7 +31,7 @@ greetings and the Spot version:
#+RESULTS: hello-word #+RESULTS: hello-word
: Hello world! : 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, 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. #+DESCRIPTION: Informal explanation of various concepts used in Spot.
#+INCLUDE: setup.org #+INCLUDE: setup.org
#+HTML_LINK_UP: index.html #+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 This page documents some of the concepts used in Spot, and whose
knowledge is usually assumed throughout the documentation. The 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. which $a$ is always true, and $b$ is true infinitely often.
#+NAME: buchi-example1 #+NAME: buchi-example1
#+BEGIN_SRC sh :results verbatim :exports none #+BEGIN_SRC sh
ltl2tgba 'G(a) & GF(b)' -B -d ltl2tgba 'G(a) & GF(b)' -B -d
#+END_SRC #+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. =light_on= should be true whenever =door_open= is true.
#+NAME: buchi-example2 #+NAME: buchi-example2
#+BEGIN_SRC sh :results verbatim :exports none #+BEGIN_SRC sh
ltl2tgba 'G(door_open -> light_on)' -d -C ltl2tgba 'G(door_open -> light_on)' -d -C
#+END_SRC #+END_SRC
@ -183,7 +184,7 @@ all runs in which at all point $a$ is true iff $b$ is true at the next
instant. instant.
#+NAME: buchi-example3 #+NAME: buchi-example3
#+BEGIN_SRC sh :results verbatim :exports none #+BEGIN_SRC sh
ltl2tgba 'G(a <-> Xb)' -B -d ltl2tgba 'G(a <-> Xb)' -B -d
#+END_SRC #+END_SRC
#+BEGIN_SRC dot :file concept-buchi3.svg :var txt=buchi-example3 :exports results #+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: Here is a simple example:
#+NAME: te1 #+NAME: te1
#+BEGIN_SRC sh :results verbatim :exports none #+BEGIN_SRC sh
cat >concept-te.hoa <<EOF cat >concept-te.hoa <<EOF
HOA: v1 HOA: v1
Acceptance: 0 t Acceptance: 0 t
@ -232,7 +233,7 @@ $txt
[[file:concept-te1.svg]] [[file:concept-te1.svg]]
#+NAME: size #+NAME: size
#+BEGIN_SRC sh :exports none #+BEGIN_SRC sh
autfilt --merge --stats=$arg concept-te.hoa autfilt --merge --stats=$arg concept-te.hoa
#+END_SRC #+END_SRC
@ -243,7 +244,7 @@ This is because those formula-labeled edges actually simplify the
following transition structure: following transition structure:
#+NAME: te2 #+NAME: te2
#+BEGIN_SRC sh :results verbatim :exports none #+BEGIN_SRC sh
autfilt concept-te.hoa -d.A autfilt concept-te.hoa -d.A
#+END_SRC #+END_SRC
#+BEGIN_SRC dot :file concept-te2.svg :var txt=te2 :exports results #+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. contains a single state.
#+NAME: gen-buchi-example1 #+NAME: gen-buchi-example1
#+BEGIN_SRC sh :results verbatim :exports none #+BEGIN_SRC sh
ltl2tgba 'GFa & GFb' | autfilt -S --sat-minimize -d ltl2tgba 'GFa & GFb' | autfilt -S --sat-minimize -d
#+END_SRC #+END_SRC
@ -317,7 +318,7 @@ following automaton has the same language as the previous one (despite
its more complex look). its more complex look).
#+NAME: gen-buchi-example2 #+NAME: gen-buchi-example2
#+BEGIN_SRC sh :results verbatim :exports none #+BEGIN_SRC sh
ltl2tgba 'GFa & GFb' -S -d ltl2tgba 'GFa & GFb' -S -d
#+END_SRC #+END_SRC
@ -337,7 +338,7 @@ with a 2-state generalized-Büchi automaton, but the smallest
equivalent Büchi automaton has three state: equivalent Büchi automaton has three state:
#+NAME: gen-buchi-example-ba #+NAME: gen-buchi-example-ba
#+BEGIN_SRC sh :results verbatim :exports none #+BEGIN_SRC sh
ltl2tgba 'GFa & GFb' -B -d ltl2tgba 'GFa & GFb' -B -d
#+END_SRC #+END_SRC
@ -356,7 +357,7 @@ acceptance sets (as below). Spot's output routines have options for
both. both.
#+NAME: gen-buchi-example-ba2 #+NAME: gen-buchi-example-ba2
#+BEGIN_SRC sh :results verbatim :exports none #+BEGIN_SRC sh
ltl2tgba 'GFa & GFb' -B -d.b ltl2tgba 'GFa & GFb' -B -d.b
#+END_SRC #+END_SRC
@ -384,7 +385,7 @@ Here is an example of Transition-based Generalized Büchi Automaton
(TGBA). (TGBA).
#+NAME: tgba-example1 #+NAME: tgba-example1
#+BEGIN_SRC sh :results verbatim :exports none #+BEGIN_SRC sh
ltl2tgba 'GF(a & X(a U b))' -d ltl2tgba 'GF(a & X(a U b))' -d
#+END_SRC #+END_SRC
#+BEGIN_SRC dot :file concept-tgba1.svg :var txt=tgba-example1 :exports results #+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 that can be represented using a one-state transition-based Büchi
automaton: automaton:
#+NAME: tgba-example2 #+NAME: tgba-example2
#+BEGIN_SRC sh :results verbatim :exports none #+BEGIN_SRC sh
ltl2tgba 'GFa' -d ltl2tgba 'GFa' -d
#+END_SRC #+END_SRC
#+BEGIN_SRC dot :file concept-tgba2.svg :var txt=tgba-example2 :exports results #+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: state-based acceptance:
#+NAME: tgba-example3 #+NAME: tgba-example3
#+BEGIN_SRC sh :results verbatim :exports none #+BEGIN_SRC sh
ltl2tgba 'GFa' -B -d ltl2tgba 'GFa' -B -d
#+END_SRC #+END_SRC
#+BEGIN_SRC dot :file concept-tba-vs-ba.svg :var txt=tgba-example3 :exports results #+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: by Spot:
#+NAME: twa-example1 #+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 ltlfilt -l -f 'GFa | FGb' | ltl2dstar --output-format=hoa - - | autfilt --merge -d
#+END_SRC #+END_SRC
#+BEGIN_SRC dot :file concept-twa1.svg :var txt=twa-example1 :exports results #+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)=. generated by [[https://sourceforge.net/projects/ltl3ba/][=ltl3ba 1.1.3=]] for the LTL formula =GF(a <-> Xb)=.
#+NAME: concepts-alt #+NAME: concepts-alt
#+BEGIN_SRC sh :results verbatim :exports none #+BEGIN_SRC sh
autfilt -d.ba <<EOF autfilt -d.ba <<EOF
HOA: v1 HOA: v1
States: 5 States: 5
@ -635,7 +636,7 @@ alternating automata is the [[#hoa][HOA format, introduced below]].
infinitely often $p_1$). The graphical representation of that infinitely often $p_1$). The graphical representation of that
automaton follows. automaton follows.
#+BEGIN_SRC sh :results verbatim :exports results #+BEGIN_SRC sh :exports results
ltl2tgba -s 'p0 | GFp1' > tmp.$$ ltl2tgba -s 'p0 | GFp1' > tmp.$$
ltl2tgba -s6 'p0 | GFp1' | pr -w80 -m -t tmp.$$ - ltl2tgba -s6 'p0 | GFp1' | pr -w80 -m -t tmp.$$ -
rm tmp.$$ rm tmp.$$
@ -665,7 +666,7 @@ accept_all: accept_all:
#+end_example #+end_example
#+NAME: never-ex1 #+NAME: never-ex1
#+BEGIN_SRC sh :results verbatim :exports none #+BEGIN_SRC sh
ltl2tgba -Bd 'p0 | GFp1' ltl2tgba -Bd 'p0 | GFp1'
#+END_SRC #+END_SRC
#+BEGIN_SRC dot :file concept-never1.svg :var txt=never-ex1 :exports results #+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 For instance the Büchi automaton we used as an example for never
claims can be encoded as follows: claims can be encoded as follows:
#+BEGIN_SRC sh :results verbatim :exports results #+BEGIN_SRC sh :exports results
ltl2tgba --ba --lbtt 'p0 | GFp1' ltl2tgba --ba --lbtt 'p0 | GFp1'
#+END_SRC #+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 support transition-based acceptance. This is indicated by a =t= on
the first line: the first line:
#+BEGIN_SRC sh :results verbatim :exports results #+BEGIN_SRC sh :exports results
ltl2tgba --lbtt 'p0 | GFp1' ltl2tgba --lbtt 'p0 | GFp1'
#+END_SRC #+END_SRC
@ -748,7 +749,7 @@ ltl2tgba --lbtt 'p0 | GFp1'
#+end_example #+end_example
#+NAME: lbtt-ex2 #+NAME: lbtt-ex2
#+BEGIN_SRC sh :results verbatim :exports none #+BEGIN_SRC sh
ltl2tgba -d 'p0 | GFp1' ltl2tgba -d 'p0 | GFp1'
#+END_SRC #+END_SRC
#+BEGIN_SRC dot :file concept-lbtt2.svg :var txt=lbtt-ex2 :exports results #+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: 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 - - echo '| F G p0 G F p1' | ltl2dstar --output-format=native - -
#+END_SRC #+END_SRC
@ -821,7 +822,7 @@ Acc-Sig: +0 +1
#+end_example #+end_example
#+NAME: dstar-example1 #+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 echo '| F G p0 G F p1' | ltl2dstar --output-format=native - - | autfilt -d
#+END_SRC #+END_SRC
#+BEGIN_SRC dot :file concept-dstar.svg :var txt=dstar-example1 :exports results #+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 extends it in many ways, including support for non-deterministic
automata, alternating automata, and for arbitrary acceptance conditions. 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 ltldo ltl2dstar -f 'FGp0 | GFp1' --name=%f
#+END_SRC #+END_SRC
@ -880,7 +881,7 @@ State: 3 {1 3}
#+end_example #+end_example
#+NAME: hoa1 #+NAME: hoa1
#+BEGIN_SRC sh :results verbatim :exports none #+BEGIN_SRC sh
ltldo ltl2dstar -f 'FGp0 | GFp1' -d ltldo ltl2dstar -f 'FGp0 | GFp1' -d
#+END_SRC #+END_SRC
#+BEGIN_SRC dot :file concept-hoa.svg :var txt=hoa1 :exports results #+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]]. Here is for instance a translation of ={(1;1)[*]}[]->a= discussed [[#psl][above]].
#+NAME: ltl2tgba1 #+NAME: ltl2tgba1
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh :exports code
ltl2tgba '{(1;1)[*]}[]->a' -d ltl2tgba '{(1;1)[*]}[]->a' -d
#+END_SRC #+END_SRC
#+BEGIN_SRC dot :file concept-ltl2tgba.svg :var txt=ltl2tgba1 :exports results #+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. #+DESCRIPTION: Examples showing how to read and write CSV files using Spot's command-line tools.
#+INCLUDE: setup.org #+INCLUDE: setup.org
#+HTML_LINK_UP: tools.html #+HTML_LINK_UP: tools.html
#+PROPERTY: header-args:sh :results verbatim :exports both
This page discusses features available in Spot's command-line This page discusses features available in Spot's command-line
tools to produce an consume CSV files. 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 with three columns: the family name of the formula, its parameter, and
the formula itself. 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 genltl --and-gf=1..5 --u-left=1..5 --format='%F,%L,%f' > gen.csv
cat gen.csv cat gen.csv
#+END_SRC #+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 formulas, and show the resulting number of states (=%s=) and edges
(=%e=) of the automaton constructed for each formula. (=%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' genltl --and-gf=1..5 --u-left=1..5 | ltl2tgba --stats '%f,%s,%e'
#+END_SRC #+END_SRC
#+RESULTS: #+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 simple output may prove difficult to process by other tools. For
instance consider the translation of the following two formulas: 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' ltl2tgba -f Xa -f 'G("switch == on" -> F"tab[3,5] < 12")' --stats '%f,%s,%e'
#+END_SRC #+END_SRC
#+RESULTS: #+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. 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=: 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' ltl2tgba -f Xa -f 'G("switch == on" -> F"tab[3,5] < 12")' --stats '"%f",%s,%e'
#+END_SRC #+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 For instance let's consider the file =gen.csv= built with the first command of
this page. It contains: this page. It contains:
#+BEGIN_SRC sh :results verbatim :exports results #+BEGIN_SRC sh :exports results
cat gen.csv cat gen.csv
#+END_SRC #+END_SRC
#+RESULTS: #+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 We can run =ltl2tgba= on the third column to produce
the same output as in a previous example: 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' ltl2tgba -F gen.csv/3 --stats '%f,%s,%e'
#+END_SRC #+END_SRC
#+RESULTS: #+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. text before and after the matched formula in the CSV file.
For instance: For instance:
#+BEGIN_SRC sh :results verbatim :exports both #+BEGIN_SRC sh
ltlfilt -F gen.csv/3 --size-min=8 --relabel=abc ltlfilt -F gen.csv/3 --size-min=8 --relabel=abc
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
@ -162,7 +163,7 @@ string.
For instance this moves the first two columns after the formulas. 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",%<' ltlfilt -F gen.csv/3 --size-min=8 --format='"%f",%<'
#+END_SRC #+END_SRC
#+RESULTS: #+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. Some CSV files contain a header lines that should not be processed.
For instance the CSV files produced by =ltlcross= have such a line: 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 | randltl -n 2 a b | ltlfilt --remove-wm |
ltlcross --csv=results.csv 'ltl2tgba -s %f >%N' 'ltl3ba -f %s >%N' ltlcross --csv=results.csv 'ltl2tgba -s %f >%N' 'ltl3ba -f %s >%N'
cat results.csv cat results.csv
@ -209,7 +210,7 @@ cat results.csv
If we run =ltlfilt= on the first column, it will process the =formula= If we run =ltlfilt= on the first column, it will process the =formula=
header as if it was an LTL 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 ltlfilt -F results.csv/1 --format='%f' --unique
#+END_SRC #+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 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. 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 ltlfilt -F results.csv/-1 --format='%f' --unique
#+END_SRC #+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 The =--stats= option of tools that generate automata can be used to
generate CSV files that embed automata. For instance 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 genltl --dac=1..3 | ltl2tgba --stats='"%f","%e edges","%h"' > csv-aut.csv
cat csv-aut.csv cat csv-aut.csv
#+END_SRC #+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 automata. If you want to preserve the entire line, you should use
=%<= and =%>= in the =--stats= format. =%<= 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"' autfilt csv-aut.csv/3 --states=2..3 --stats='%<,"%h"'
#+END_SRC #+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 =--automata= it will record the automata produced by each tool into
the CSV file: the CSV file:
#+BEGIN_SRC sh :results verbatim :exports both #+BEGIN_SRC sh
genltl --dac=1..3 | ltlcross --csv=result.csv --automata ltl2tgba genltl --dac=1..3 | ltlcross --csv=result.csv --automata ltl2tgba
cat result.csv cat result.csv
#+END_SRC #+END_SRC

View file

@ -3,6 +3,7 @@
#+DESCRIPTION: Spot command-line tool for converting automata into Transition-based Generalized Büchi Automata. #+DESCRIPTION: Spot command-line tool for converting automata into Transition-based Generalized Büchi Automata.
#+INCLUDE: setup.org #+INCLUDE: setup.org
#+HTML_LINK_UP: tools.html #+HTML_LINK_UP: tools.html
#+PROPERTY: header-args:sh :results verbatim :exports both
This tool converts automata into transition-based generalized Büchi This tool converts automata into transition-based generalized Büchi
automata, a.k.a., TGBA. It can also produce Büchi automata on request 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 Additionally we use =ltlfilt= to convert our formula to the
prefix format used by =ltl2dstar=. 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 ltlfilt -f '(a U b) & GFb' -l | ltl2dstar --ltl2nba=spin:ltl2tgba@-Ds - fagfb
#+END_SRC #+END_SRC
By looking at the file =fagfb= you can see the =ltl2dsar= actually By looking at the file =fagfb= you can see the =ltl2dsar= actually
produced a 4-state DRA: produced a 4-state DRA:
#+BEGIN_SRC sh :results verbatim :exports both #+BEGIN_SRC sh
cat fagfb cat fagfb
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
#+begin_example #+begin_example
DRA v2 explicit DRA v2 explicit
Comment: "Safra[NBA=3]" Comment: "DBA2DRA[NBA=3]"
States: 4 States: 4
Acceptance-Pairs: 1 Acceptance-Pairs: 1
Start: 2 Start: 1
AP: 2 "a" "b" AP: 2 "a" "b"
--- ---
State: 0 State: 0
Acc-Sig: +0 Acc-Sig:
3 0
3 0
0 0
0 0
State: 1 State: 1
Acc-Sig: -0 Acc-Sig:
1 0
1
1
1 1
3
3
State: 2 State: 2
Acc-Sig: Acc-Sig:
1
2 2
0 2
0 3
3
State: 3 State: 3
Acc-Sig: Acc-Sig: +0
2
2
3 3
3 3
0
0
#+end_example #+end_example
Let's display this automaton with =autfilt=: Let's display this automaton with =autfilt=:
#+NAME: fagfb #+NAME: fagfb
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh :exports code
autfilt fagfb --dot autfilt fagfb --dot
#+END_SRC #+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 #+BEGIN_SRC dot :file fagfb.svg :var txt=fagfb :exports results
$txt $txt
#+END_SRC #+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=): For instance here is the conversion to a Büchi automaton (=-B=):
#+NAME: fagfb2ba #+NAME: fagfb2ba
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh :exports code
dstar2tgba -B fagfb -d dstar2tgba -B fagfb -d
#+END_SRC #+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 #+BEGIN_SRC dot :file fagfb2ba.svg :var txt=fagfb2ba :exports results
$txt $txt
@ -165,7 +116,7 @@ a complete automaton.
But we could as well require the output as a never claim for Spin (option =-s=): 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 dstar2tgba -s fagfb
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
@ -173,18 +124,18 @@ dstar2tgba -s fagfb
never { never {
T0_init: T0_init:
if if
:: (b) -> goto accept_S0
:: ((a) && (!(b))) -> goto T0_init :: ((a) && (!(b))) -> goto T0_init
:: (b) -> goto accept_S2
fi; fi;
accept_S0: T0_S1:
if if
:: (b) -> goto accept_S0 :: (!(b)) -> goto T0_S1
:: (!(b)) -> goto T0_S2 :: (b) -> goto accept_S2
fi; fi;
T0_S2: accept_S2:
if if
:: (b) -> goto accept_S0 :: (!(b)) -> goto T0_S1
:: (!(b)) -> goto T0_S2 :: (b) -> goto accept_S2
fi; fi;
} }
#+end_example #+end_example
@ -197,7 +148,7 @@ T0_S2:
Here is the translation of =GFa | GFb= to a 4-state Streett automaton: Here is the translation of =GFa | GFb= to a 4-state Streett automaton:
#+NAME: gfafgb #+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 ltlfilt -f 'GFa & GFb' -l | ltl2dstar --automata=streett --ltl2nba=spin:ltl2tgba@-Ds - gfagfb
autfilt --dot gfagfb autfilt --dot gfagfb
#+END_SRC #+END_SRC
@ -214,30 +165,9 @@ $txt
And now its conversion by =dstar2tgba= to a 1-state TGBA. And now its conversion by =dstar2tgba= to a 1-state TGBA.
#+NAME: gfagfb2ba #+NAME: gfagfb2ba
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh :exports code
dstar2tgba gfagfb -d dstar2tgba gfagfb -d
#+END_SRC #+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 #+BEGIN_SRC dot :file gfagfb2ba.svg :var txt=gfagfb2ba :exports results
$txt $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= The type of automaton to produce can be selected using the =-B= or =-M=
switches: switches:
#+BEGIN_SRC sh :results verbatim :exports results #+BEGIN_SRC sh :exports results
dstar2tgba --help | sed -n '/Output automaton type:/,/^$/p' | sed '1d;$d' dstar2tgba --help | sed -n '/Output automaton type:/,/^$/p' | sed '1d;$d'
#+END_SRC #+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 And these may be refined by a simplification goal, should the
post-processor routine had a choice to make: 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' dstar2tgba --help | sed -n '/Simplification goal:/,/^$/p' | sed '1d;$d'
#+END_SRC #+END_SRC
#+RESULTS: #+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 The effort put into post-processing can be limited with the =--low= or
=--medium= options: =--medium= options:
#+BEGIN_SRC sh :results verbatim :exports results #+BEGIN_SRC sh :exports results
dstar2tgba --help | sed -n '/Simplification level:/,/^$/p' | sed '1d;$d' dstar2tgba --help | sed -n '/Simplification level:/,/^$/p' | sed '1d;$d'
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
@ -308,7 +238,7 @@ should you find =dstar2tgba= too slow.
Finally, the output format can be changed with the following Finally, the output format can be changed with the following
[[file:oaut.org][common ouput options]]: [[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' dstar2tgba --help | sed -n '/Output format:/,/^$/p' | sed '1d;$d'
#+END_SRC #+END_SRC
#+RESULTS: #+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 output (Büchi) automaton, =%d=, whether the output automaton is
deterministic, and =%p= whether the automaton is complete. 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 | randltl -n -1 --tree-size=10..14 a b c |
ltlfilt --remove-wm -r -u --size-min=3 -n 10 | ltlfilt --remove-wm -r -u --size-min=3 -n 10 |
while read f; do while read f; do
@ -392,20 +322,20 @@ done
#+begin_example #+begin_example
(b | Fa) R Fc (b | Fa) R Fc
DRA: 9st.; BA: 9st.; det.? 1; complete? 1 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 DRA: 7st.; BA: 7st.; det.? 0; complete? 0
GFc GFc
DRA: 3st.; BA: 3st.; det.? 1; complete? 1 DRA: 2st.; BA: 2st.; det.? 1; complete? 1
!a | (a R b) !a | (a R b)
DRA: 3st.; BA: 2st.; det.? 1; complete? 0 DRA: 3st.; BA: 2st.; det.? 1; complete? 0
Xc R (G!c R (b | G!c)) Xc R G(b | G!c)
DRA: 4st.; BA: 2st.; det.? 1; complete? 0 DRA: 3st.; BA: 2st.; det.? 1; complete? 0
c & G(b | F(a & c)) c & G(b | F(a & c))
DRA: 4st.; BA: 3st.; det.? 1; complete? 0 DRA: 4st.; BA: 3st.; det.? 1; complete? 0
XXFc XXFc
DRA: 4st.; BA: 4st.; det.? 1; complete? 1 DRA: 4st.; BA: 4st.; det.? 1; complete? 1
XFc | Gb 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)) G(((!a & Gc) | (a & F!c)) U (!a | Ga))
DRA: 6st.; BA: 5st.; det.? 1; complete? 1 DRA: 6st.; BA: 5st.; det.? 1; complete? 1
a & !b a & !b

View file

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

View file

@ -3,6 +3,7 @@
#+DESCRIPTION: Spot command-line tool that generates LTL formulas from known patterns #+DESCRIPTION: Spot command-line tool that generates LTL formulas from known patterns
#+INCLUDE: setup.org #+INCLUDE: setup.org
#+HTML_LINK_UP: tools.html #+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 This tool outputs LTL formulas that either comes from named lists of
formulas, or from scalable patterns. 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 given different names in different papers, so we alias different
option names to the same pattern. 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' genltl --help | sed -n '/Pattern selection:/,/^$/p' | sed '1d;$d'
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
@ -32,10 +33,16 @@ genltl --help | sed -n '/Pattern selection:/,/^$/p' | sed '1d;$d'
(range should be included in 1..55) (range should be included in 1..55)
--eh-patterns[=RANGE] Etessami and Holzmann [Concur'00] patterns (range --eh-patterns[=RANGE] Etessami and Holzmann [Concur'00] patterns (range
should be included in 1..12) 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-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))&... --gh-r=RANGE (GF(p1)|FG(p2))&(GF(p2)|FG(p3))&...
&(GF(pn)|FG(p{n+1})) &(GF(pn)|FG(p{n+1}))
--go-theta=RANGE !((GF(p1)&GF(p2)&...&GF(pn)) -> G(q->F(r))) --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] --hkrss-patterns[=RANGE], --liberouter-patterns[=RANGE]
Holeček et al. patterns from the Liberouter Holeček et al. patterns from the Liberouter
project (range should be included in 1..55) 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 --kr-nlogn=RANGE quasilinear formula with doubly exponential DBA
--kv-psi=RANGE, --kr-n2=RANGE --kv-psi=RANGE, --kr-n2=RANGE
quadratic formula with doubly exponential DBA 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 --or-fg=RANGE, --ccj-xi=RANGE
FG(p1)|FG(p2)|...|FG(pn) FG(p1)|FG(p2)|...|FG(pn)
--or-g=RANGE, --gh-s=RANGE G(p1)|G(p2)|...|G(pn) --or-g=RANGE, --gh-s=RANGE G(p1)|G(p2)|...|G(pn)
--or-gf=RANGE, --gh-c1=RANGE --or-gf=RANGE, --gh-c1=RANGE
GF(p1)|GF(p2)|...|GF(pn) 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-left=RANGE (((p1 R p2) R p3) ... R pn)
--r-right=RANGE (p1 R (p2 R (... R pn))) --r-right=RANGE (p1 R (p2 R (... R pn)))
--rv-counter=RANGE n-bit counter --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) --rv-counter-linear=RANGE n-bit counter (linear size)
--sb-patterns[=RANGE] Somenzi and Bloem [CAV'00] patterns (range should --sb-patterns[=RANGE] Somenzi and Bloem [CAV'00] patterns (range should
be included in 1..27) 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-f1=RANGE G(p -> (q | Xq | ... | XX...Xq)
--tv-f2=RANGE G(p -> (q | X(q | X(... | Xq))) --tv-f2=RANGE G(p -> (q | X(q | X(... | Xq)))
--tv-g1=RANGE G(p -> (q & Xq & ... & XX...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: 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 genltl --and-gf=1..5 --u-left=1..5
#+END_SRC #+END_SRC
#+RESULTS: #+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. 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$ \\' genltl --and-gf=1..5 --u-left=1..5 --latex --format='%F & %L & $%f$ \\'
#+END_SRC #+END_SRC
#+RESULTS: #+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 =p0=, =p1=, ... before it is output, when the pattern (like
=--ccj-alpha=) use different names. Compare: =--ccj-alpha=) use different names. Compare:
#+BEGIN_SRC sh :results verbatim :exports both #+BEGIN_SRC sh
genltl --ccj-alpha=3 genltl --ccj-alpha=3
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
: F(F(Fq3 & q2) & q1) & F(F(Fp3 & p2) & p1) : F(p1 & F(p2 & Fp3)) & F(q1 & F(q2 & Fq3))
with with
#+BEGIN_SRC sh :results verbatim :exports both #+BEGIN_SRC sh
genltl --ccj-alpha=3 --lbt genltl --ccj-alpha=3 --lbt
#+END_SRC #+END_SRC
#+RESULTS: #+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 This is because most tools using =lbt='s syntax require atomic
propositions to have the form =pNN=. 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 a subset of the list of formulas. Without range, all formulas are
used. Here is the complete list: used. Here is the complete list:
#+BEGIN_SRC sh :results verbatim :exports both #+BEGIN_SRC sh
genltl --dac --eh --hkrss --p --sb --format=%F:%L,%f genltl --dac --eh --hkrss --p --sb --format='%F=%L,%f'
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
#+begin_example #+begin_example
dac-patterns:1,G!p0 dac-patterns=1,G!p0
dac-patterns:2,Fp0 -> (!p1 U p0) dac-patterns=2,Fp0 -> (!p1 U p0)
dac-patterns:3,G(p0 -> G!p1) dac-patterns=3,G(p0 -> G!p1)
dac-patterns:4,G((p0 & !p1 & Fp1) -> (!p2 U p1)) dac-patterns=4,G((p0 & !p1 & Fp1) -> (!p2 U p1))
dac-patterns:5,G((p0 & !p1) -> (!p2 W p1)) dac-patterns=5,G((p0 & !p1) -> (!p2 W p1))
dac-patterns:6,Fp0 dac-patterns=6,Fp0
dac-patterns:7,!p0 W (!p0 & p1) dac-patterns=7,!p0 W (!p0 & p1)
dac-patterns:8,G!p0 | F(p0 & Fp1) dac-patterns=8,G!p0 | F(p0 & Fp1)
dac-patterns:9,G((p0 & !p1) -> (!p1 W (!p1 & p2))) dac-patterns=9,G((p0 & !p1) -> (!p1 W (!p1 & p2)))
dac-patterns:10,G((p0 & !p1) -> (!p1 U (!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=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=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=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=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=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=16,Gp0
dac-patterns:17,Fp0 -> (p1 U p0) dac-patterns=17,Fp0 -> (p1 U p0)
dac-patterns:18,G(p0 -> Gp1) dac-patterns=18,G(p0 -> Gp1)
dac-patterns:19,G((p0 & !p1 & Fp1) -> (p2 U p1)) dac-patterns=19,G((p0 & !p1 & Fp1) -> (p2 U p1))
dac-patterns:20,G((p0 & !p1) -> (p2 W p1)) dac-patterns=20,G((p0 & !p1) -> (p2 W p1))
dac-patterns:21,!p0 W p1 dac-patterns=21,!p0 W p1
dac-patterns:22,Fp0 -> (!p1 U (p0 | p2)) dac-patterns=22,Fp0 -> (!p1 U (p0 | p2))
dac-patterns:23,G!p0 | F(p0 & (!p1 W p2)) dac-patterns=23,G!p0 | F(p0 & (!p1 W p2))
dac-patterns:24,G((p0 & !p1 & Fp1) -> (!p2 U (p1 | p3))) dac-patterns=24,G((p0 & !p1 & Fp1) -> (!p2 U (p1 | p3)))
dac-patterns:25,G((p0 & !p1) -> (!p2 W (p1 | p3))) dac-patterns=25,G((p0 & !p1) -> (!p2 W (p1 | p3)))
dac-patterns:26,G(p0 -> Fp1) dac-patterns=26,G(p0 -> Fp1)
dac-patterns:27,Fp0 -> ((p1 -> (!p0 U (!p0 & p2))) U p0) dac-patterns=27,Fp0 -> ((p1 -> (!p0 U (!p0 & p2))) U p0)
dac-patterns:28,G(p0 -> G(p1 -> Fp2)) dac-patterns=28,G(p0 -> G(p1 -> Fp2))
dac-patterns:29,G((p0 & !p1 & Fp1) -> ((p2 -> (!p1 U (!p1 & p3))) U p1)) 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=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=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=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=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=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=35,G(p0 -> (Fp1 -> (!p1 U (p2 | (!p1 & p3 & X(!p1 U p4))))))
dac-patterns:36,F(p0 & XFp1) -> (!p0 U p2) 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=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=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=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=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=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=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=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=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=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=46,G(p0 -> F(p1 & XFp2))
dac-patterns:47,Fp0 -> ((p1 -> (!p0 U (!p0 & p2 & X(!p0 U p3)))) U p0) 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=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=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=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=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=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=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=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)))))) 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=1,p0 U (p1 & Gp2)
eh-patterns:2,p0 U (p1 & X(p2 U p3)) 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=3,p0 U (p1 & X(p2 & F(p3 & XF(p4 & XF(p5 & XFp6)))))
eh-patterns:4,F(p0 & XGp1) eh-patterns=4,F(p0 & XGp1)
eh-patterns:5,F(p0 & X(p1 & XFp2)) eh-patterns=5,F(p0 & X(p1 & XFp2))
eh-patterns:6,F(p0 & X(p1 U p2)) eh-patterns=6,F(p0 & X(p1 U p2))
eh-patterns:7,FGp0 | GFp1 eh-patterns=7,FGp0 | GFp1
eh-patterns:8,G(p0 -> (p1 U p2)) eh-patterns=8,G(p0 -> (p1 U p2))
eh-patterns:9,G(p0 & XF(p1 & XF(p2 & XFp3))) eh-patterns=9,G(p0 & XF(p1 & XF(p2 & XFp3)))
eh-patterns:10,GFp0 & GFp1 & GFp2 & GFp3 & GFp4 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=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))) eh-patterns=12,G(p0 -> (p1 U (Gp2 | Gp3)))
hkrss-patterns:1,G(Fp0 & F!p0) hkrss-patterns=1,G(Fp0 & F!p0)
hkrss-patterns:2,GFp0 & GF!p0 hkrss-patterns=2,GFp0 & GF!p0
hkrss-patterns:3,GF(!(p1 <-> Xp1) | !(p0 <-> Xp0)) hkrss-patterns=3,GF(!(p1 <-> Xp1) | !(p0 <-> Xp0))
hkrss-patterns:4,GF(!(p1 <-> Xp1) | !(p0 <-> Xp0) | !(p2 <-> Xp2) | !(p3 <-> Xp3)) hkrss-patterns=4,GF(!(p1 <-> Xp1) | !(p0 <-> Xp0) | !(p2 <-> Xp2) | !(p3 <-> Xp3))
hkrss-patterns:5,G!p0 hkrss-patterns=5,G!p0
hkrss-patterns:6,G((p0 -> F!p0) & (!p0 -> Fp0)) hkrss-patterns=6,G((p0 -> F!p0) & (!p0 -> Fp0))
hkrss-patterns:7,G(p0 -> F(p0 & p1)) hkrss-patterns=7,G(p0 -> F(p0 & p1))
hkrss-patterns:8,G(p0 -> F((!p0 & p1 & p2 & p3) -> Fp4)) hkrss-patterns=8,G(p0 -> F((!p0 & p1 & p2 & p3) -> Fp4))
hkrss-patterns:9,G(p0 -> F!p1) hkrss-patterns=9,G(p0 -> F!p1)
hkrss-patterns:10,G(p0 -> Fp1) hkrss-patterns=10,G(p0 -> Fp1)
hkrss-patterns:11,G(p0 -> F(p1 -> Fp2)) hkrss-patterns=11,G(p0 -> F(p1 -> Fp2))
hkrss-patterns:12,G(p0 -> F((p1 & p2) -> Fp3)) hkrss-patterns=12,G(p0 -> F((p1 & p2) -> Fp3))
hkrss-patterns:13,G((p0 -> Fp1) & (p2 -> Fp3) & (p4 -> Fp5) & (p6 -> Fp7)) hkrss-patterns=13,G((p0 -> Fp1) & (p2 -> Fp3) & (p4 -> Fp5) & (p6 -> Fp7))
hkrss-patterns:14,G(!p0 & !p1) hkrss-patterns=14,G(!p0 & !p1)
hkrss-patterns:15,G!(p0 & p1) hkrss-patterns=15,G!(p0 & p1)
hkrss-patterns:16,G(p0 -> p1) hkrss-patterns=16,G(p0 -> p1)
hkrss-patterns:17,G((p0 -> !p1) & (p1 -> !p0)) hkrss-patterns=17,G((p0 -> !p1) & (p1 -> !p0))
hkrss-patterns:18,G(!p0 -> (p1 <-> !p2)) hkrss-patterns=18,G(!p0 -> (p1 <-> !p2))
hkrss-patterns:19,G((!p0 & (p1 | p2 | p3)) -> p4) hkrss-patterns=19,G((!p0 & (p1 | p2 | p3)) -> p4)
hkrss-patterns:20,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=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=22,G((p0 & p1 & !p2 & !p3 & !p4) -> F(p5 & !p6 & !p7 & !p8))
hkrss-patterns:23,G(!p0 -> !(p1 & p2 & p3 & p4 & p5)) hkrss-patterns=23,G(!p0 -> !(p1 & p2 & p3 & p4 & p5))
hkrss-patterns:24,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=25,G((p0 & p1) -> (p2 | p3 | !(p4 & p5)))
hkrss-patterns:26,G((!p0 & (p1 | p2 | p3 | p4)) -> (!p5 <-> p6)) hkrss-patterns=26,G((!p0 & (p1 | p2 | p3 | p4)) -> (!p5 <-> p6))
hkrss-patterns:27,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=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=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=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=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=32,G(p0 -> (p1 U (!p1 U (!p2 | p3))))
hkrss-patterns:33,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=34,G((!p0 & p1) -> Xp2)
hkrss-patterns:35,G(p0 -> X(p0 | p1)) 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=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=37,G((p0 & !p1 & Xp1 & Xp0) -> (p2 -> Xp3))
hkrss-patterns:38,G(p0 -> X(!p0 U p1)) hkrss-patterns=38,G(p0 -> X(!p0 U p1))
hkrss-patterns:39,G((!p0 & Xp0) -> X((p0 U p1) | Gp0)) 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=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=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=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=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=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=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=46,G((Xp0 -> p0) -> (p1 <-> Xp1))
hkrss-patterns:47,G((Xp0 -> p0) -> ((p1 -> Xp1) & (!p1 -> X!p1))) 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=48,!p0 U G!((p1 & p2) | (p3 & p4) | (p2 & p3) | (p2 & p4) | (p1 & p4) | (p1 & p3))
hkrss-patterns:49,!p0 U p1 hkrss-patterns=49,!p0 U p1
hkrss-patterns:50,(p0 U p1) | Gp0 hkrss-patterns=50,(p0 U p1) | Gp0
hkrss-patterns:51,p0 & XG!p0 hkrss-patterns=51,p0 & XG!p0
hkrss-patterns:52,XG(p0 -> (G!p1 | (!Xp1 U p2))) hkrss-patterns=52,XG(p0 -> (G!p1 | (!Xp1 U p2)))
hkrss-patterns:53,XG((p0 & !p1) -> (G!p1 | (!p1 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=54,XG((p0 & p1) -> ((p1 U p2) | Gp1))
hkrss-patterns:55,Xp0 & G((!p0 & Xp0) -> XXp0) hkrss-patterns=55,Xp0 & G((!p0 & Xp0) -> XXp0)
p-patterns:1,G(p0 -> Fp1) p-patterns=1,G(p0 -> Fp1)
p-patterns:2,(GFp1 & GFp0) -> GFp2 p-patterns=2,(GFp1 & GFp0) -> GFp2
p-patterns:3,G(p0 -> (p1 & (p2 U p3))) p-patterns=3,G(p0 -> (p1 & (p2 U p3)))
p-patterns:4,F(p0 | p1) p-patterns=4,F(p0 | p1)
p-patterns:5,GF(p0 | p1) p-patterns=5,GF(p0 | p1)
p-patterns:6,(p0 U p1) -> ((p2 U p3) | Gp2) 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=7,G(p0 -> (!p1 U (p1 U (!p1 & (p2 R !p1)))))
p-patterns:8,G(p0 -> (p1 R !p2)) p-patterns=8,G(p0 -> (p1 R !p2))
p-patterns:9,G(!p0 -> Fp0) p-patterns=9,G(!p0 -> Fp0)
p-patterns:10,G(p0 -> F(p1 | p2)) p-patterns=10,G(p0 -> F(p1 | p2))
p-patterns:11,!(!(p0 | p1) U p2) & G(p3 -> !(!(p0 | p1) U p2)) p-patterns=11,!(!(p0 | p1) U p2) & G(p3 -> !(!(p0 | p1) U p2))
p-patterns:12,G!p0 -> G!p1 p-patterns=12,G!p0 -> G!p1
p-patterns:13,G(p0 -> (G!p1 | (!p2 U p1))) p-patterns=13,G(p0 -> (G!p1 | (!p2 U p1)))
p-patterns:14,G(p0 -> (p1 R (p1 | !p2))) p-patterns=14,G(p0 -> (p1 R (p1 | !p2)))
p-patterns:15,G((p0 & p1) -> (!p1 R (p0 | !p1))) p-patterns=15,G((p0 & p1) -> (!p1 R (p0 | !p1)))
p-patterns:16,G(p0 -> F(p1 & p2)) p-patterns=16,G(p0 -> F(p1 & p2))
p-patterns:17,G(p0 -> (!p1 U (p1 U (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=18,G(p0 -> (!p1 U (p1 U (!p1 U (p1 U (p1 & p2))))))
p-patterns:19,GFp0 -> GFp1 p-patterns=19,GFp0 -> GFp1
p-patterns:20,GF(p0 | p1) & GF(p1 | p2) p-patterns=20,GF(p0 | p1) & GF(p1 | p2)
sb-patterns:1,p0 U p1 sb-patterns=1,p0 U p1
sb-patterns:2,p0 U (p1 U p2) sb-patterns=2,p0 U (p1 U p2)
sb-patterns:3,!(p0 U (p1 U p2)) sb-patterns=3,!(p0 U (p1 U p2))
sb-patterns:4,GFp0 -> GFp1 sb-patterns=4,GFp0 -> GFp1
sb-patterns:5,Fp0 U Gp1 sb-patterns=5,Fp0 U Gp1
sb-patterns:6,Gp0 U p1 sb-patterns=6,Gp0 U p1
sb-patterns:7,!(Fp0 <-> Fp1) sb-patterns=7,!(Fp0 <-> Fp1)
sb-patterns:8,!(GFp0 -> GFp1) sb-patterns=8,!(GFp0 -> GFp1)
sb-patterns:9,!(GFp0 <-> GFp1) sb-patterns=9,!(GFp0 <-> GFp1)
sb-patterns:10,p0 R (p0 | p1) sb-patterns=10,p0 R (p0 | p1)
sb-patterns:11,(Xp0 U Xp1) | !X(p0 U p1) sb-patterns=11,(Xp0 U Xp1) | !X(p0 U p1)
sb-patterns:12,(Xp0 U p1) | !X(p0 U (p0 & 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=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=14,G(p0 -> Fp1) & ((Xp0 U Xp1) | !X(p0 U p1))
sb-patterns:15,G(p0 -> Fp1) sb-patterns=15,G(p0 -> Fp1)
sb-patterns:16,!G(p0 -> X(p1 R p2)) sb-patterns=16,!G(p0 -> X(p1 R p2))
sb-patterns:17,!(FGp0 | FGp1) sb-patterns=17,!(FGp0 | FGp1)
sb-patterns:18,G(Fp0 & Fp1) sb-patterns=18,G(Fp0 & Fp1)
sb-patterns:19,Fp0 & F!p0 sb-patterns=19,Fp0 & F!p0
sb-patterns:20,(p0 & Xp1) R X(((p2 U p3) R p0) U (p2 R 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=21,Gp2 | (G(p0 | GFp1) & G(p2 | GF!p1)) | Gp0
sb-patterns:22,Gp0 | Gp2 | (G(p0 | FGp1) & G(p2 | FG!p1)) 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=23,!(Gp2 | (G(p0 | GFp1) & G(p2 | GF!p1)) | Gp0)
sb-patterns:24,!(Gp0 | Gp2 | (G(p0 | FGp1) & G(p2 | FG!p1))) sb-patterns=24,!(Gp0 | Gp2 | (G(p0 | FGp1) & G(p2 | FG!p1)))
sb-patterns:25,G(p0 | XGp1) & G(p2 | XG!p1) sb-patterns=25,G(p0 | XGp1) & G(p2 | XG!p1)
sb-patterns:26,G(p0 | (Xp1 & X!p1)) sb-patterns=26,G(p0 | (Xp1 & X!p1))
sb-patterns:27,p0 | (p1 U p0) sb-patterns=27,p0 | (p1 U p0)
#+end_example #+end_example
Note that ~--sb-patterns=2 --sb-patterns=4 --sb-patterns=21..22~ also 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 formula output by =genltl --sb-patterns= plus its negation, it will
contain only 46 formulas, not 54. contain only 46 formulas, not 54.
#+BEGIN_SRC sh :results verbatim :exports both #+BEGIN_SRC sh
genltl --sb | ltlfilt --uniq --count genltl --sb | ltlfilt --uniq --count
genltl --sb --pos --neg | ltlfilt --uniq --count genltl --sb --pos --neg | ltlfilt --uniq --count
#+END_SRC #+END_SRC

View file

@ -3,6 +3,7 @@
#+DESCRIPTION: Spot command-line tools for exploring the temporal hierarchy of Manna & Pnueli #+DESCRIPTION: Spot command-line tools for exploring the temporal hierarchy of Manna & Pnueli
#+INCLUDE: setup.org #+INCLUDE: setup.org
#+HTML_LINK_UP: tools.html #+HTML_LINK_UP: tools.html
#+PROPERTY: header-args:sh :results verbatim :exports both
/A hierarchy of temporal properties/ was defined by Manna & Pnueli in /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]]. 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 The =--format=%h= option can be used to display the "class key" of the
most precise class to which a formula belongs. 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 ltlfilt -f 'a U b' --format=%h
#+END_SRC #+END_SRC
#+RESULTS: #+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 If you find hard to remember the class name corresponding to the class
keys, you can request verbose output with =%[v]h=: 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' ltlfilt -f 'a U b' --format='%[v]h'
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
@ -102,7 +103,7 @@ But actually any /guarantee/ property is also an /obligation/, a
/recurrence/, a /persistence/, and a /reactivity/ property. You can /recurrence/, a /persistence/, and a /reactivity/ property. You can
get the complete list of classes using =%[w]h= or =%[vw]h=: 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' ltlfilt -f 'a U b' --format='%[w]h = %[vw]h'
#+END_SRC #+END_SRC
#+RESULTS: #+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 =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: 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 genltl --dac-patterns --format='%[v]h' | sort | uniq -c
#+END_SRC #+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= remove all recurrence properties from the =genltl --dac-pattern=
output: output:
#+BEGIN_SRC sh :results verbatim :exports both #+BEGIN_SRC sh
genltl --dac-patterns | genltl --dac-patterns |
ltlfilt -v --recurrence --format='%[v]h, %f' ltlfilt -v --recurrence --format='%[v]h, %f'
#+END_SRC #+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 here is how to generate 10 random recurrence PSL formulas that are
not LTL formulas, and that are not obligations: not LTL formulas, and that are not obligations:
#+BEGIN_SRC sh :results verbatim :exports both #+BEGIN_SRC sh
randltl --psl -n -1 a b | randltl --psl -n -1 a b |
ltlfilt -v --ltl | ltlfilt -v --ltl |
ltlfilt -v --obligation | 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 possible files. Here is a generation of 200 random LTL formulas
binned into aptly named files: binned into aptly named files:
#+BEGIN_SRC sh :results verbatim :exports both #+BEGIN_SRC sh
randltl -n 200 a b -o random-%h.ltl randltl -n 200 a b -o random-%h.ltl
wc -l random-?.ltl wc -l random-?.ltl
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
: 40 random-B.ltl : 45 random-B.ltl
: 49 random-G.ltl : 49 random-G.ltl
: 12 random-O.ltl : 12 random-O.ltl
: 21 random-P.ltl : 21 random-P.ltl
: 18 random-R.ltl : 18 random-R.ltl
: 51 random-S.ltl : 46 random-S.ltl
: 9 random-T.ltl : 9 random-T.ltl
: 200 total : 200 total
@ -229,7 +230,7 @@ is in class syntactic-C).
Here is how to generate 10 random LTL formulas that describe safety Here is how to generate 10 random LTL formulas that describe safety
properties but that are not in the syntactic-safety class: 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 | randltl -n-1 a b |
ltlfilt -v --syntactic-safety | ltlfilt -v --syntactic-safety |
ltlfilt --safety -n10 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 belongs to this fragment. In this particular case, =ltlfilt
--simplify= recognizes this: --simplify= recognizes this:
#+BEGIN_SRC sh :results verbatim :exports both #+BEGIN_SRC sh
ltlfilt --simplify -f 'b M Gb' ltlfilt --simplify -f 'b M Gb'
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
@ -291,7 +292,7 @@ the translator could produce before determinization and minimization.
For instance =Fa R b= is an obligation: 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' ltlfilt -f 'Fa R b' --format='%[v]h'
#+END_SRC #+END_SRC
@ -303,7 +304,7 @@ automaton (here we use =autfilt --highlight-nondet= to show where the
non-determinism occurs): non-determinism occurs):
#+NAME: hier-oblig-1 #+NAME: hier-oblig-1
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh :exports code
ltl2tgba 'Fa R b' | autfilt --highlight-nondet -d ltl2tgba 'Fa R b' | autfilt --highlight-nondet -d
#+END_SRC #+END_SRC
@ -351,7 +352,7 @@ For instance, let us use =ltl2dstar= to construct a Streett automaton
for the obligation property =Ga | XFb=. for the obligation property =Ga | XFb=.
#+NAME: hier-oblig-3 #+NAME: hier-oblig-3
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh :exports code
ltldo 'ltl2dstar --automata=streett' -f 'Ga | XFb' -d ltldo 'ltl2dstar --automata=streett' -f 'Ga | XFb' -d
#+END_SRC #+END_SRC
@ -365,7 +366,7 @@ $txt
We can now minimize this automaton with: We can now minimize this automaton with:
#+NAME: hier-oblig-4 #+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 ltldo 'ltl2dstar --automata=streett' -f 'Ga | XFb' | autfilt -D -C -d
#+END_SRC #+END_SRC
#+BEGIN_SRC dot :file hier-oblig-4.svg :var txt=hier-oblig-4 :exports results #+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=: An example is =a U Xb=:
#+BEGIN_SRC sh :results verbatim :exports both #+BEGIN_SRC sh
ltlfilt -f 'a U Xb' --format='%[v]h' ltlfilt -f 'a U Xb' --format='%[v]h'
#+END_SRC #+END_SRC
@ -399,7 +400,7 @@ ltlfilt -f 'a U Xb' --format='%[v]h'
#+NAME: hier-guarantee-1 #+NAME: hier-guarantee-1
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh :exports code
ltl2tgba 'a U Xb' | autfilt --highlight-nondet -d ltl2tgba 'a U Xb' | autfilt --highlight-nondet -d
#+END_SRC #+END_SRC
#+BEGIN_SRC dot :file hier-guarantee-1.svg :var txt=hier-guarantee-1 :exports results #+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]] [[file:hier-guarantee-1.svg]]
#+NAME: hier-guarantee-2 #+NAME: hier-guarantee-2
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh :exports code
ltl2tgba -D 'a U Xb' -d ltl2tgba -D 'a U Xb' -d
#+END_SRC #+END_SRC
#+BEGIN_SRC dot :file hier-guarantee-2.svg :var txt=hier-guarantee-2 :exports results #+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: Here is an example:
#+BEGIN_SRC sh :results verbatim :exports both #+BEGIN_SRC sh
ltlfilt -f '(a W Gb) M b' --format='%[v]h' ltlfilt -f '(a W Gb) M b' --format='%[v]h'
#+END_SRC #+END_SRC
@ -449,7 +450,7 @@ ltlfilt -f '(a W Gb) M b' --format='%[v]h'
#+NAME: hier-safety-1 #+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 ltl2tgba '(a W Gb) M b' | autfilt --highlight-nondet -d
#+END_SRC #+END_SRC
#+BEGIN_SRC dot :file hier-safety-1.svg :var txt=hier-safety-1 :exports results #+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. that is guaranteed to be minimal, and where all runs are accepting.
#+NAME: hier-safety-2 #+NAME: hier-safety-2
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh :exports code
ltl2tgba -D '(a W Gb) M b' -d ltl2tgba -D '(a W Gb) M b' -d
#+END_SRC #+END_SRC
#+BEGIN_SRC dot :file hier-safety-2.svg :var txt=hier-safety-2 :exports results #+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). extended into valid ω-words).
#+NAME: hier-safety-1m #+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 ltl2tgba -M '(a W Gb) M b' | autfilt --highlight-nondet -d
#+END_SRC #+END_SRC
#+BEGIN_SRC dot :file hier-safety-1m.svg :var txt=hier-safety-1m :exports results #+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]] [[file:hier-safety-1m.svg]]
#+NAME: hier-safety-2m #+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 ltl2tgba -M -D '(a W Gb) M b' -d
#+END_SRC #+END_SRC
#+BEGIN_SRC dot :file hier-safety-2m.svg :var txt=hier-safety-2m :exports results #+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 The typical example is =GFa=, which can be translated into a 1-state
transition-based Büchi automaton: transition-based Büchi automaton:
#+BEGIN_SRC sh :results verbatim :exports both #+BEGIN_SRC sh
ltlfilt -f 'GFa' --format='%[v]h' ltlfilt -f 'GFa' --format='%[v]h'
#+END_SRC #+END_SRC
@ -538,7 +539,7 @@ ltlfilt -f 'GFa' --format='%[v]h'
: recurrence : recurrence
#+NAME: hier-recurrence-1 #+NAME: hier-recurrence-1
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh :exports code
ltl2tgba 'GFa' -d ltl2tgba 'GFa' -d
#+END_SRC #+END_SRC
#+BEGIN_SRC dot :file hier-recurrence-1.svg :var txt=hier-recurrence-1 :exports results #+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: Using state-based acceptance, at least two states are required. For instance:
#+NAME: hier-recurrence-2 #+NAME: hier-recurrence-2
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh :exports code
ltl2tgba -S 'GFa' -d ltl2tgba -S 'GFa' -d
#+END_SRC #+END_SRC
#+BEGIN_SRC dot :file hier-recurrence-2.svg :var txt=hier-recurrence-2 :exports results #+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 Here is an example of a formula for which =ltl2tgba= does not produce a
deterministic automaton, even with =-D=. deterministic automaton, even with =-D=.
#+BEGIN_SRC sh :results verbatim :exports both #+BEGIN_SRC sh
ltlfilt -f 'G(Gb | Fa)' --format='%[v]h' ltlfilt -f 'G(Gb | Fa)' --format='%[v]h'
#+END_SRC #+END_SRC
@ -573,7 +574,7 @@ ltlfilt -f 'G(Gb | Fa)' --format='%[v]h'
: recurrence : recurrence
#+NAME: hier-recurrence-3 #+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 ltl2tgba -D 'G(Gb | Fa)' | autfilt --highlight-nondet -d
#+END_SRC #+END_SRC
#+BEGIN_SRC dot :file hier-recurrence-3.svg :var txt=hier-recurrence-3 :exports results #+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. acceptance is desired.
#+NAME: hier-recurrence-4 #+NAME: hier-recurrence-4
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh :exports code
ltl2tgba -P -D 'G(Gb | Fa)' -d ltl2tgba -P -D 'G(Gb | Fa)' -d
#+END_SRC #+END_SRC
#+BEGIN_SRC dot :file hier-recurrence-4.svg :var txt=hier-recurrence-4 :exports results #+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. generalized Rabin.
#+NAME: hier-recurrence-5 #+NAME: hier-recurrence-5
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh :exports code
ltl2tgba -P -D 'G(Gb | Fa)' | ltl2tgba -P -D 'G(Gb | Fa)' |
autfilt --generalized-rabin -d autfilt --generalized-rabin -d
#+END_SRC #+END_SRC
@ -649,7 +650,7 @@ a /recurrence/ property), is to chain a few algorithms implemented in Spot:
simply get a larger deterministic automaton). simply get a larger deterministic automaton).
#+NAME: hier-recurrence-7 #+NAME: hier-recurrence-7
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh :exports code
ltl2tgba -P -D 'G(Gb | Fa)' | ltl2tgba -P -D 'G(Gb | Fa)' |
autfilt -S --generalized-rabin | autfilt -S --generalized-rabin |
autfilt -B -D -d 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: helps producing a smaller automaton. Here is what we get without it:
#+NAME: hier-recurrence-8 #+NAME: hier-recurrence-8
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh :exports code
ltl2tgba -P -D 'G(Gb | Fa)' | ltl2tgba -P -D 'G(Gb | Fa)' |
autfilt --generalized-rabin | autfilt --generalized-rabin |
autfilt -B -D -d 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. persistence formula is =FGa=, and using =-D= on this is hopeless.
#+NAME: hier-persistence-1 #+NAME: hier-persistence-1
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh :exports code
ltl2tgba -D FGa -d ltl2tgba -D FGa -d
#+END_SRC #+END_SRC
#+BEGIN_SRC dot :file hier-persistence-1.svg :var txt=hier-persistence-1 :exports results #+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: complementation ourselves:
#+NAME: hier-persistence-2 #+NAME: hier-persistence-2
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh :exports code
ltlfilt --negate -f FGa | ltlfilt --negate -f FGa |
ltl2tgba -D | ltl2tgba -D |
autfilt --complement -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 Let's do that on the persistence formula =F(G!a | G(b U a))=, just for
the fun of it. 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' ltlfilt -f 'F(G!a | G(b U a))' --format='%[v]h'
#+END_SRC #+END_SRC
#+RESULTS: #+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: Unfortunately the default output of the translation is not weak:
#+NAME: hier-persistence-3 #+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 ltl2tgba 'F(G!a | G(b U a))' -d
#+END_SRC #+END_SRC
#+BEGIN_SRC dot :file hier-persistence-3.svg :var txt=hier-persistence-3 :exports results #+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: generalized Büchi automaton:
#+NAME: hier-persistence-4 #+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))' | ltlfilt --negate -f 'F(G!a | G(b U a))' |
ltl2tgba -D | ltl2tgba -D |
autfilt --highlight-nondet=5 -d autfilt --highlight-nondet=5 -d
@ -787,7 +788,7 @@ determinizing this automaton into a Rabin automaton, and then back to
deterministic Büchi: deterministic Büchi:
#+NAME: hier-persistence-5 #+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))' | ltlfilt --negate -f 'F(G!a | G(b U a))' |
ltl2tgba -P -D | ltl2tgba -P -D |
autfilt --generalized-rabin | 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))=: 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 #+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))' | ltlfilt --negate -f 'F(G!a | G(b U a))' |
ltl2tgba -P -D | ltl2tgba -P -D |
autfilt --generalized-rabin | autfilt --generalized-rabin |
@ -822,7 +823,7 @@ $txt
And finally we convert the result back to Büchi: And finally we convert the result back to Büchi:
#+NAME: hier-persistence-7 #+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))' | ltlfilt --negate -f 'F(G!a | G(b U a))' |
ltl2tgba -P -D | ltl2tgba -P -D |
autfilt --generalized-rabin | autfilt --generalized-rabin |

View file

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

View file

@ -3,6 +3,7 @@
#+DESCRIPTION: Options for input and output of temporal logic formulas in Spot's command-line tools #+DESCRIPTION: Options for input and output of temporal logic formulas in Spot's command-line tools
#+INCLUDE: setup.org #+INCLUDE: setup.org
#+HTML_LINK_UP: tools.html #+HTML_LINK_UP: tools.html
#+PROPERTY: header-args:sh :results verbatim :exports both
Spot supports different syntaxes for LTL/PSL formulas. This page Spot supports different syntaxes for LTL/PSL formulas. This page
documents the options, common to all tools where it makes sense, that 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: 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' ltl2tgba --help | sed -n '/Input options:/,/^$/p' | sed '1d;$d'
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
: -f, --formula=STRING process the formula STRING : -f, --formula=STRING process the formula STRING
: -F, --file=FILENAME[/COL] process each line of FILENAME as a formula; if COL : -F, --file=FILENAME[/COL] process each line of FILENAME as a formula; if COL
: is a positive integer, assume a CSV file and read : 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 : line of the CSV file
: --lbt-input read all formulas using LBT's prefix syntax : --lbt-input read all formulas using LBT's prefix syntax
: --lenient parenthesized blocks that cannot be parsed as : --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 An unfortunate side-effect of =--lenient= parsing is that many syntax
errors will not be caught. Compare the following syntax error: 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' ltlfilt -f '(a U b U) U c'
#+END_SRC #+END_SRC
#+RESULTS: #+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 : >>> (a U b U) U c
: ^ : ^
: syntax error, unexpected closing parenthesis : syntax error, unexpected closing parenthesis
:
: >>> (a U b U) U c : >>> (a U b U) U c
: ^ : ^
: missing right operand for "until operator" : missing right operand for "until operator"
:
With the same command in =--lenient= mode: 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: 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' genltl --help | sed -n '/Output options:/,/^$/p' | sed '1d;$d'
#+END_SRC #+END_SRC
#+RESULTS: #+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 -0, --zero-terminated-output separate output formulas with \0 instead of \n
(for use with xargs -0) (for use with xargs -0)
-8, --utf8 output using UTF-8 characters -8, --utf8 output using UTF-8 characters
--csv-escape quote the formula for use in a CSV file --format=FORMAT, --stats=FORMAT
--format=FORMAT specify how each line should be output (default: specify how each line should be output (default:
"%f") "%f")
-l, --lbt output in LBT's syntax -l, --lbt output in LBT's syntax
--latex output using LaTeX macros --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 -o, --output=FORMAT send output to a file named FORMAT instead of
standard output. The first formula sent to a file standard output. The first formula sent to a file
truncates it unless FORMAT starts with '>>'. 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 -p, --full-parentheses output fully-parenthesized formulas
-s, --spin output in Spin's syntax -s, --spin output in Spin's syntax
--spot output in Spot's syntax (default) --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 For instance the following invocation of [[file:randltl.org][=randltl=]] will create 5
random formulas, but in 5 different files: 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 randltl -n5 a b -o example-%L.ltl
wc -l example-*.ltl wc -l example-*.ltl
#+END_SRC #+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 null characters. So for instance the following two invocations have
nearly the same output: 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 -0 --gh-q=1..4 | xargs -0 ltl2tgba --stats='%F,%f,%s'
genltl --gh-q=1..4 | ltl2tgba -F- --stats='%F,%f,%s' genltl --gh-q=1..4 | ltl2tgba -F- --stats='%F,%f,%s'
#+END_SRC #+END_SRC

View file

@ -3,6 +3,7 @@
#+DESCRIPTION: Spot command-line tool for translating LTL into Transition-based Generalized Büchi Automata. #+DESCRIPTION: Spot command-line tool for translating LTL into Transition-based Generalized Büchi Automata.
#+INCLUDE: setup.org #+INCLUDE: setup.org
#+HTML_LINK_UP: tools.html #+HTML_LINK_UP: tools.html
#+PROPERTY: header-args:sh :results verbatim :exports both
This tool translates LTL or PSL formulas into different types of This tool translates LTL or PSL formulas into different types of
automata. automata.
@ -31,7 +32,7 @@ less frequent.)
Formulas to translate may be specified using [[file:ioltl.org][common input options for Formulas to translate may be specified using [[file:ioltl.org][common input options for
LTL/PSL formulas]]. LTL/PSL formulas]].
#+BEGIN_SRC sh :results verbatim :exports both #+BEGIN_SRC sh
ltl2tgba -f 'Fa & GFb' ltl2tgba -f 'Fa & GFb'
#+END_SRC #+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 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 =-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 =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 ltl2tgba "Fa & GFb" -d | dot -Tpdf > tgba.pdf
#+END_SRC #+END_SRC
#+RESULTS: #+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 we use some [[file:oaut.org::#default-dot][environment variables]] to produce a more colorful
output by default) output by default)
#+NAME: dotex #+NAME: dotex
#+BEGIN_SRC sh :results verbatim :exports none #+BEGIN_SRC sh :exports none
ltl2tgba "Fa & GFb" -d ltl2tgba "Fa & GFb" -d
#+END_SRC #+END_SRC
#+RESULTS: dotex #+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): =dot= to render the output of =ltl2tgba= from now on):
#+NAME: dotex2 #+NAME: dotex2
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh :exports code
ltl2tgba "GFa & GFb" -d ltl2tgba "GFa & GFb" -d
#+END_SRC #+END_SRC
#+RESULTS: dotex2 #+RESULTS: dotex2
@ -158,7 +159,7 @@ A Büchi automaton for the previous formula can be obtained with the
=-B= option: =-B= option:
#+NAME: dotex2ba #+NAME: dotex2ba
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh :exports code
ltl2tgba -B 'GFa & GFb' -d ltl2tgba -B 'GFa & GFb' -d
#+END_SRC #+END_SRC
#+RESULTS: dotex2ba #+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 requests the use of transition-based acceptance as it is done
internally): internally):
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh :exports code
ltl2tgba --dot=t -B 'GFa & GFb' ltl2tgba --dot=t -B 'GFa & GFb'
#+END_SRC #+END_SRC
#+NAME: dotex2ba-t #+NAME: dotex2ba-t
#+BEGIN_SRC sh :results verbatim :exports none #+BEGIN_SRC sh :exports none
ltl2tgba --dot=.t -B 'GFa & GFb' ltl2tgba --dot=.t -B 'GFa & GFb'
#+END_SRC #+END_SRC
@ -244,7 +245,7 @@ Büchi automata with state-based acceptance. Here is the same formula
as above, for comparison. as above, for comparison.
#+NAME: dotex2gba #+NAME: dotex2gba
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh :exports code
ltl2tgba -S 'GFa & GFb' -d ltl2tgba -S 'GFa & GFb' -d
#+END_SRC #+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 As already discussed on the page about [[file:oaut.org][common output options]], various
options controls the output format of =ltl2tgba=: 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' ltl2tgba --help | sed -n '/Output format:/,/^$/p' | sed '1d;$d'
#+END_SRC #+END_SRC
#+RESULTS: #+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. if your system can display UTF-8 correctly.
#+NAME: dotex2ba8 #+NAME: dotex2ba8
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh :exports code
ltl2tgba -B8 "GFa & GFb" -d ltl2tgba -B8 "GFa & GFb" -d
#+END_SRC #+END_SRC
#+RESULTS: dotex2ba8 #+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=. =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' ltl2tgba -s 'GFa & GFb'
#+END_SRC #+END_SRC
#+RESULTS: #+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 propositions, you may also need put the parser in =--lenient= mode to
support these: support these:
#+BEGIN_SRC sh :results verbatim :exports both #+BEGIN_SRC sh
ltl2tgba -s --lenient '(a < b) U (process[2]@ok)' ltl2tgba -s --lenient '(a < b) U (process[2]@ok)'
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
: never { /* "a < b" U "process[2]@ok" */ : never { /* "a < b" U "process[2]@ok" */
: T0_init: : T0_init:
: if : if
: :: ((process[2]@ok)) -> goto accept_all : :: (process[2]@ok) -> goto accept_all
: :: ((a < b) && (!(process[2]@ok))) -> goto T0_init : :: ((a < b) && (!(process[2]@ok))) -> goto T0_init
: fi; : fi;
: accept_all: : 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 whenever possible, would you prefer a small automaton (=--small=) or a
deterministic (=--deterministic=) automaton? 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' ltl2tgba --help | sed -n '/Simplification goal:/,/^$/p' | sed '1d;$d'
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
: -a, --any no preference, do not bother making it small or : -a, --any no preference, do not bother making it small or
: deterministic : 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) : --small prefer small automata (default)
The =--any= option tells the translator that it should attempt to 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=: flagrant is =Ga|Gb|Gc=:
#+NAME: gagbgc1 #+NAME: gagbgc1
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh :exports code
ltl2tgba 'Ga|Gb|Gc' -d ltl2tgba 'Ga|Gb|Gc' -d
#+END_SRC #+END_SRC
#+RESULTS: gagbgc1 #+RESULTS: gagbgc1
@ -509,7 +512,7 @@ $txt
[[file:gagbgc1.svg]] [[file:gagbgc1.svg]]
#+NAME: gagbgc2 #+NAME: gagbgc2
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh :exports code
ltl2tgba -D 'Ga|Gb|Gc' -d ltl2tgba -D 'Ga|Gb|Gc' -d
#+END_SRC #+END_SRC
#+RESULTS: gagbgc2 #+RESULTS: gagbgc2
@ -577,7 +580,7 @@ two ways to accept a run that repeats continuously the configuration
$\bar ab$. $\bar ab$.
#+NAME: ambig1 #+NAME: ambig1
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh :exports code
ltl2tgba -B 'GFa -> GFb' -d ltl2tgba -B 'GFa -> GFb' -d
#+END_SRC #+END_SRC
#+RESULTS: ambig1 #+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: is only one run that recognizes this example word:
#+NAME: ambig2 #+NAME: ambig2
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh :exports code
ltl2tgba -B -U 'GFa -> GFb' -d ltl2tgba -B -U 'GFa -> GFb' -d
#+END_SRC #+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 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 of pre- and post-processing performed. These two steps can be adjusted
via a common set of switches: 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' ltl2tgba --help | sed -n '/Simplification level:/,/^$/p' | sed '1d;$d'
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
@ -740,7 +743,7 @@ expectations.
deterministic TGBA exists. deterministic TGBA exists.
#+NAME: ltl2tgba-fga #+NAME: ltl2tgba-fga
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh :exports code
ltl2tgba "FGa" -D -d ltl2tgba "FGa" -D -d
#+END_SRC #+END_SRC
@ -754,7 +757,7 @@ ltl2tgba "FGa" -D -d
But with =--generic=, =ltl2tgba= will output the following co-Büchi automaton: But with =--generic=, =ltl2tgba= will output the following co-Büchi automaton:
#+NAME: ltl2tgba-fga-D #+NAME: ltl2tgba-fga-D
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh :exports code
ltl2tgba "FGa" -G -D -d ltl2tgba "FGa" -G -D -d
#+END_SRC #+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: acceptance condition, we get a weak and deterministic Büchi automaton:
#+NAME: ltl2tgba-fbgc-D #+NAME: ltl2tgba-fbgc-D
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh :exports code
ltl2tgba "Fb|Gc" -G -D -d ltl2tgba "Fb|Gc" -G -D -d
#+END_SRC #+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: product of these two automata will be made, producing:
#+NAME: ltl2tgba-fbgcfga-D #+NAME: ltl2tgba-fbgcfga-D
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh :exports code
ltl2tgba "(Fb|Gc)&FGa" -G -D -d ltl2tgba "(Fb|Gc)&FGa" -G -D -d
#+END_SRC #+END_SRC
@ -804,7 +807,7 @@ TGBA is non-deterministic, it will then be determinized into an
automaton with parity acceptance: automaton with parity acceptance:
#+NAME: ltl2tgba-fbgcfga-nosplit-D #+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 ltl2tgba "(Fb|Gc)&FGa" -G -D -xltl-split=0 -d
#+END_SRC #+END_SRC
#+BEGIN_SRC dot :file ltl2tgba-fbgcfga-nosplit-D.svg :var txt=ltl2tgba-fbgcfga-nosplit-D :exports results #+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 For instance the following deterministic automaton
#+NAME: ltl2tgba-det1 #+NAME: ltl2tgba-det1
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh :exports code
ltl2tgba "F(a W FGb)" -G -D -d ltl2tgba "F(a W FGb)" -G -D -d
#+END_SRC #+END_SRC
@ -837,7 +840,7 @@ ltl2tgba "F(a W FGb)" -G -D -d
would be larger if SCC-based optimizations were disabled: would be larger if SCC-based optimizations were disabled:
#+NAME: ltl2tgba-det2 #+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 ltl2tgba "F(a W FGb)" -xdet-scc=0 -G -D -d
#+END_SRC #+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=): acceptance (another name for =parity min odd 2=):
#+NAME: ltl2tgba-dp1 #+NAME: ltl2tgba-dp1
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh :exports code
ltl2tgba "FGa" -D -P -d ltl2tgba "FGa" -D -P -d
#+END_SRC #+END_SRC
@ -897,7 +900,7 @@ And =GFa & GFb= gets translated into a =Büchi= automaton (another name
for =parity min even 1=): for =parity min even 1=):
#+NAME: ltl2tgba-dp2 #+NAME: ltl2tgba-dp2
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh :exports code
ltl2tgba "GFa & GFb" -D -P -d ltl2tgba "GFa & GFb" -D -P -d
#+END_SRC #+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 we can specify it as an argument to the =--parity= option. For instance
#+NAME: ltl2tgba-dp3 #+NAME: ltl2tgba-dp3
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh :exports code
ltl2tgba "GFa & GFb" -D -P'min odd' -d ltl2tgba "GFa & GFb" -D -P'min odd' -d
#+END_SRC #+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. requested) should belong to exactly one acceptance set.
#+NAME: ltl2tgba-dp4 #+NAME: ltl2tgba-dp4
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh :exports code
ltl2tgba "GFa & GFb" -D -p -d ltl2tgba "GFa & GFb" -D -p -d
#+END_SRC #+END_SRC
@ -942,7 +945,7 @@ ltl2tgba "GFa & GFb" -D -p -d
[[file:ltl2tgba-dp4.svg]] [[file:ltl2tgba-dp4.svg]]
#+NAME: ltl2tgba-dp5 #+NAME: ltl2tgba-dp5
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh :exports code
ltl2tgba "GFa & GFb" -D -p'min odd' -d ltl2tgba "GFa & GFb" -D -p'min odd' -d
#+END_SRC #+END_SRC
@ -957,7 +960,7 @@ Note that all these options can be combined with state-based
acceptance if needed: acceptance if needed:
#+NAME: ltl2tgba-dp6 #+NAME: ltl2tgba-dp6
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh :exports code
ltl2tgba "GFa & GFb" -D -S -p'max even' -d ltl2tgba "GFa & GFb" -D -S -p'max even' -d
#+END_SRC #+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 statistics should be output, and how they should be output using the
following sequence of characters (other characters are output as-is): 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' ltl2tgba --help | sed -n '/ sequences:/,/^$/p' | sed '1d;$d'
#+END_SRC #+END_SRC
#+RESULTS: #+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 For instance we can study the size of the automata generated for the
right-nested =U= formulas as follows: 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"' genltl --u-right=1..8 | ltl2tgba --stats '%s states and %e edges for "%f"'
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
@ -1093,7 +1096,7 @@ compatible outgoing transition exist.
deterministic monitor for the given formula. deterministic monitor for the given formula.
#+NAME: monitor1 #+NAME: monitor1
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh :exports code
ltl2tgba -M '(Xa & Fb) | Gc' -d ltl2tgba -M '(Xa & Fb) | Gc' -d
#+END_SRC #+END_SRC
@ -1128,7 +1131,7 @@ $txt
[[file:monitor1.svg]] [[file:monitor1.svg]]
#+NAME: monitor2 #+NAME: monitor2
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh :exports code
ltl2tgba -MD '(Xa & Fb) | Gc' -d ltl2tgba -MD '(Xa & Fb) | Gc' -d
#+END_SRC #+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. "complete" version of the previous monitor.
#+NAME: monitor3 #+NAME: monitor3
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh :exports code
ltl2tgba -C -M -D '(Xa & Fb) | Gc' -d ltl2tgba -C -M -D '(Xa & Fb) | Gc' -d
#+END_SRC #+END_SRC

View file

@ -3,6 +3,7 @@
#+DESCRIPTION: Spot command-line tool for translating LTL into Transition-based Generalized Testing Automata. #+DESCRIPTION: Spot command-line tool for translating LTL into Transition-based Generalized Testing Automata.
#+INCLUDE: setup.org #+INCLUDE: setup.org
#+HTML_LINK_UP: tools.html #+HTML_LINK_UP: tools.html
#+PROPERTY: header-args:sh :results verbatim :exports code
This tool generates various form of Testing Automata, i.e., automata This tool generates various form of Testing Automata, i.e., automata
that observe the /changes/ of atomic propositions, not their values. 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=]]). discussing [[file:ltl2tgba.org][=ltl2tgba=]]).
#+NAME: augb-ta #+NAME: augb-ta
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh
ltl2tgta --ta --multiple-init 'a U Gb' ltl2tgta --ta --multiple-init 'a U Gb'
#+END_SRC #+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 #+BEGIN_SRC dot :file augb-ta.svg :var txt=augb-ta :exports results
$txt $txt
#+END_SRC #+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. This is the default since it often makes the result more readable.
#+NAME: augb-ta2 #+NAME: augb-ta2
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh
ltl2tgta --ta 'a U Gb' ltl2tgta --ta 'a U Gb'
#+END_SRC #+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 #+BEGIN_SRC dot :file augb-ta2.svg :var txt=augb-ta2 :exports results
$txt $txt
@ -117,37 +67,9 @@ Büchi accepting transitions are marked with the same ={0,1}=
notation used in TGBA. notation used in TGBA.
#+NAME: gfagfb-gta #+NAME: gfagfb-gta
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh
ltl2tgta --gta 'GFa & GFb' ltl2tgta --gta 'GFa & GFb'
#+END_SRC #+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 #+BEGIN_SRC dot :file gfagfb-gta.svg :var txt=gfagfb-gta :exports results
$txt $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. acceptance sets, livelock acceptance states are no longer needed.
#+NAME: gfagfb-tgta #+NAME: gfagfb-tgta
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh
ltl2tgta 'GFa & GFb' ltl2tgta 'GFa & GFb'
#+END_SRC #+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 #+BEGIN_SRC dot :file gfagfb-tgta.svg :var txt=gfagfb-tgta :exports results
$txt $txt
@ -210,10 +100,12 @@ $txt
[[file:gfagfb-tgta.svg]] [[file:gfagfb-tgta.svg]]
[fn:topnoc]: This new class of automaton, as well as the [fn:topnoc]: This new class of automata, as well as the implementation
implementation of the previous testing automata classes, is part of of the previous testing automata classes, is part of Ala Eddine BEN
Ala Eddine BEN SALEM's PhD work, and should appear in a future edition SALEM's PhD work, and is discussed in [[https://www.lrde.epita.fr/~adl/dl/adl/bensalem.12.topnoc.pdf][*Model checking using
of ToPNoC (LNCS 7400). 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 # 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. #+DESCRIPTION: Spot command-line tool for cross-comparing the output of LTL translators.
#+INCLUDE: setup.org #+INCLUDE: setup.org
#+HTML_LINK_UP: tools.html #+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 =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 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 Each translator should be specified as a string that use some of the
following character sequences: 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' ltlcross --help | sed -n '/character sequences:/,/^$/p' | sed '1d;$d'
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
@ -73,7 +75,7 @@ following character sequences:
For instance here is how we could cross-compare the never claims 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)=. 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' ltlcross -f 'GFa' -f 'X(a U b)' 'ltl2tgba -s %s >%O' 'spin -f %s >%O'
#+END_SRC #+END_SRC
#+RESULTS: #+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 temporary file into which the output of the translator is redirected
before it is read back by =ltlcross=. 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 ltlcross -f 'GFa' -f 'X(a U b)' 'ltl2tgba -s %s >%O' 'spin -f %s >%O' 2>&1
#+END_SRC #+END_SRC
#+RESULTS: #+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 shorthands are available. Those can be listed with the
=--list-shorthands= option. =--list-shorthands= option.
#+BEGIN_SRC sh :results verbatim :exports both #+BEGIN_SRC sh
ltlcross --list-shorthands ltlcross --list-shorthands
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
@ -182,24 +184,28 @@ ltlcross --list-shorthands
If a COMMANDFMT does not use any %-sequence, and starts with one of If a COMMANDFMT does not use any %-sequence, and starts with one of
the following words, then the string on the right is appended. the following words, then the string on the right is appended.
delag %f>%O
lbt <%L>%O lbt <%L>%O
ltl2ba -f %s>%O ltl2ba -f %s>%O
ltl2da %f>%O ltl2da %f>%O
ltl2dgra %f>%O
ltl2dpa %f>%O ltl2dpa %f>%O
ltl2dra %f>%O
ltl2ldba %f>%O ltl2ldba %f>%O
ltl2dstar --output-format=hoa %[MW]L %O ltl2dstar --output-format=hoa %[MW]L %O
ltl2tgba -H %f>%O ltl2tgba -H %f>%O
ltl3ba -f %s>%O ltl3ba -f %s>%O
ltl3dra -f %s>%O ltl3dra -f %s>%O
ltl3hoa -f %f>%O ltl3hoa -f %f>%O
ltl3tela -f %f>%O
modella %[MWei^]L %O modella %[MWei^]L %O
spin -f %s>%O spin -f %s>%O
Any {name} and directory component is skipped for the purpose of Any {name} and directory component is skipped for the purpose of
matching those prefixes. So for instance matching those prefixes. So for instance
'{DRA} ~/mytools/ltl2dstar-0.5.2' '{DRA} ~/mytools/ltl2dstar-0.5.2'
will changed into will be changed into
'{DRA} ~/mytools/ltl2dstar-0.5.2 --output-format=hoa %[MR]L %O' '{DRA} ~/mytools/ltl2dstar-0.5.2 --output-format=hoa %[MW]L %O'
#+end_example #+end_example
What this implies is that running =ltlcross ltl2ba ltl3ba ...= is 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 \ ltlcross --csv=results.csv --json=results.json \
'ltl2tgba -s %f >%O' \ 'ltl2tgba -s %f >%O' \
'spin -f %s >%O' \ 'spin -f %s >%O' \
'lbt < %L >%O' --csv=results.csv 2>&1 'lbt < %L >%O' 2>&1
#+END_SRC #+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: After this execution, the file =results.csv= contains the following:
#+BEGIN_SRC sh :results verbatim :exports results #+BEGIN_SRC sh :results output raw :exports results
cat results.csv sed 's/"//g
s/|/\\vert{}/g
s/--/@@html:--@@/g
1a\
|-|
s/^/| /
s/$/ |/
s/,/|/g
' results.csv
#+END_SRC #+END_SRC
#+ATTR_HTML: :class csv-table
#+RESULTS: #+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 |
"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 | 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.00396246,2,2,1,1,2,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.00262385,1,0,0,0,1,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.0261614,1,1,1,1,1,0,0,1,200,4199,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.0137128,2,2,2,1,2,0,0,1,201,4220,2 | 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.00792516,3,3,3,0,3,0,0,1,222,4653,23 | 1 | lbt < %L >%O | ok | 0 | 0.00206923 | 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 | !(F(!(p0))) | ltl2tgba -s %f >%O | ok | 0 | 0.0293213 | 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 | !(F(!(p0))) | spin -f %s >%O | ok | 0 | 0.00114213 | 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 | !(F(!(p0))) | lbt < %L >%O | ok | 0 | 0.00281165 | 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 | F(!(p0)) | ltl2tgba -s %f >%O | ok | 0 | 0.0273697 | 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 | F(!(p0)) | spin -f %s >%O | ok | 0 | 0.00110435 | 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 | F(!(p0)) | lbt < %L >%O | ok | 0 | 0.00205025 | 4 | 6 | 10 | 1 | 4 | 2 | 1 | 1 | 601 | 14497 | 203 |
"(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 | 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 |
"(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 | 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 |
"(1) U ((G(p0)) | (F(p1)))","lbt < %L >%O","ok",0,0.0016987,9,17,52,2,9,4,1,0,1601,41559,805 | F((G(p0)) \vert{} (F(p1))) | lbt < %L >%O | ok | 0 | 0.00218541 | 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 | !(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 |
"!((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 | !(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 |
"!((1) U ((G(p0)) | (F(p1))))","lbt < %L >%O","ok",0,0.00280787,3,6,9,1,2,3,1,0,397,5957,2 | !(F((G(p0)) \vert{} (F(p1)))) | lbt < %L >%O | ok | 0 | 0.00184477 | 3 | 6 | 9 | 1 | 2 | 3 | 1 | 0 | 397 | 5957 | 2 |
#+end_example
This file can be loaded in any spreadsheet or statistical application. 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 addition to) =--cvs=results.csv=, the file =results.json= would have
contained the following [[http://www.json.org/][JSON]] output. 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 cat results.json
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
#+begin_example #+begin_SRC json
{ {
"tool": [ "tool": [
"ltl2tgba -s %f >%O", "ltl2tgba -s %f >%O",
@ -467,37 +451,37 @@ cat results.json
"formula": [ "formula": [
"0", "0",
"1", "1",
"!((1) U (F(!(p0))))", "!(F(!(p0)))",
"(1) U (F(!(p0)))", "F(!(p0))",
"(1) U ((G(p0)) | (F(p1)))", "F((G(p0)) | (F(p1)))",
"!((1) U ((G(p0)) | (F(p1))))" "!(F((G(p0)) | (F(p1))))"
], ],
"fields": [ "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" "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 ], "inputs": [ 0, 1 ],
"results": [ "results": [
[ 0,0,"ok",0,0.0299298,1,1,0,1,1,0,0,0,1,0,1 ], [ 0,0,"ok",0,0.0137672,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,1,"ok",0,0.000908285,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 ], [ 0,2,"ok",0,0.00133153,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,0,"ok",0,0.0135283,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,1,"ok",0,0.000828822,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 ], [ 1,2,"ok",0,0.00134064,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,0,"ok",0,0.0140072,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,1,"ok",0,0.00081293,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 ], [ 2,2,"ok",0,0.00134737,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,0,"ok",0,0.0137064,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,1,"ok",0,0.000911401,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 ], [ 3,2,"ok",0,0.00130378,4,6,10,1,4,2,1,1,601,14497,203 ],
[ 4,0,"ok",0,0.0287222,3,5,11,1,3,1,1,0,600,11358,3 ], [ 4,0,"ok",0,0.0144879,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,1,"ok",0,0.00103421,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 ], [ 4,2,"ok",0,0.0013883,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,0,"ok",0,0.0142669,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,1,"ok",0,0.00240013,2,3,5,1,1,1,1,0,396,4964,1 ],
[ 5,2,"ok",0,0.00280787,3,6,9,1,2,3,1,0,397,5957,2 ] [ 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. Here the =fields= table describes the columns of the =results= table.
The =inputs= tables lists the columns that are considered as inputs The =inputs= tables lists the columns that are considered as inputs
@ -535,8 +519,8 @@ for i in range(0, len(data["tool"])):
#+RESULTS: #+RESULTS:
: tool & count & time & states & edges & transitions & acc & scc & nondet_states & nondet_aut & complete_aut & product_states & product_transitions & product_scc \\ : 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 \\ : 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 \\ : 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 & 4.2 & 6.8 & 14.7 & 0.8 & 4.0 & 1.8 & 0.5 & 0.3 & 603.8 & 14905.2 & 239.5 \\ : 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 The script =bench/ltl2tgba/sum.py= is a more evolved version of the
above script that generates two kinds of LaTeX tables. 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 =1=, so its value is meaningful only when evaluating translations to
generalized Büchi automata. =edges= counts the actual number of edges generalized Büchi automata. =edges= counts the actual number of edges
in the graph supporting the automaton; an edge (labeled by a Boolean 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 assignment of all atomic propositions). For instance in an automaton
where the atomic proposition are $a$ and $b$, one edge labeled by 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 $a\lor b$ actually represents three transitions $a b$, $a\bar b$, and
$\bar a b$. $\bar a b$.
The following picture displays two automata for the LTL formula =a U =scc= counts the number of strongly-connected components in the
b=. They both have 2 states and 3 edges, however they differ in the automaton.
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.
If option =--strength= is passed to =ltlcross=, these SCCs are If option =--strength= is passed to =ltlcross=, these SCCs are
also partitioned on four sets based on their strengths: 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 configurations, and the strings =ltl2tgba -s --small %f >%O= and
=ltl2tgba -s --deter %f >%O= appear verbatim in the output: =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 ltlcross -f a -f Ga 'ltl2tgba -s --small %f >%O' 'ltl2tgba -s --deter %f >%O' --csv
#+END_SRC #+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: #+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" | 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 @@html:--@@small %f >%O | ok | 0 | 0.045425 | 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 @@html:--@@deter %f >%O | ok | 0 | 0.0452103 | 2 | 2 | 3 | 1 | 2 | 0 | 0 | 0 | 201 | 4144 | 2 |
: "!(a)","ltl2tgba -s --deter %f >%O","ok",0,0.0117374,2,2,3,1,2,0,0,0,201,4149,2 | !(a) | ltl2tgba -s @@html:--@@small %f >%O | ok | 0 | 0.0475807 | 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 | !(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 --deter %f >%O","ok",0,0.011645,1,1,1,1,1,0,0,0,200,2059,1 | 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 --small %f >%O","ok",0,0.0129519,2,3,4,1,2,0,0,1,400,8264,2 | 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 --deter %f >%O","ok",0,0.0129941,2,3,4,1,2,0,0,1,400,8264,2 | !(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 To present these results graphically, or even when analyzing these
data, it might be convenient to give each configured tool a shorter 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 looking whether the command specification for a translator has the
form "={short name}actual command=". form "={short name}actual command=".
For instance: For instance, after
#+BEGIN_SRC sh :results verbatim :exports both #+BEGIN_SRC sh :exports code
genltl --and-f=1..5 | genltl --and-f=1..5 |
ltlcross '{small} ltl2tgba -s --small %f >%O' \ ltlcross '{small} ltl2tgba -s --small %f >%O' \
'{deter} ltl2tgba -s --deter %f >%O' --csv=ltlcross.csv '{deter} ltl2tgba -s --deter %f >%O' --csv=ltlcross.csv
cat ltlcross.csv
#+END_SRC #+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: #+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 |
"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) | small | ok | 0 | 0.0143077 | 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) | deter | ok | 0 | 0.0143547 | 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)) | small | ok | 0 | 0.0146721 | 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)) | deter | ok | 0 | 0.0145825 | 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)) | small | ok | 0 | 0.0147275 | 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)) | deter | ok | 0 | 0.0144936 | 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))) | small | ok | 0 | 0.0147704 | 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))) | 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.0142109,8,27,64,1,8,0,0,1,1587,33068,34 | (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.0149064,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.0159551,4,6,24,1,4,1,1,0,601,6171,4 | !((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.0143288,7,19,37,1,7,0,0,0,1387,18792,33 | !((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.0152539,16,81,256,1,16,0,0,1,2727,57786,74 | (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.0155381,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.015231,5,8,64,1,5,1,1,0,801,8468,5 | !((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.0157937,15,65,175,1,15,0,0,0,2527,37226,73 | !((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.017919,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.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.0167644,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.0187427,6,10,160,1,6,1,1,0,1000,10707,6 | !((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 |
"!((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
In this last example, we saved the CSV output to =ltlcross.csv= so we In this last example, we saved the CSV output to =ltlcross.csv= so we
can play with it in the next section. 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 The produced CSV should be directly readable by R's CSV input functions like
=read.csv()=, =readr::read_csv()=, or =data.table::fread()=. =read.csv()=, =readr::read_csv()=, or =data.table::fread()=.
#+BEGIN_SRC R :session :results output :exports both #+BEGIN_SRC R
library(data.table) library(data.table)
dt <- fread('ltlcross.csv') dt <- fread('ltlcross.csv')
str(dt) str(dt)
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
#+begin_example #+begin_example
data.table 1.12.0 Latest news: r-datatable.com
Classes data.table and 'data.frame': 20 obs. of 16 variables: Classes data.table and 'data.frame': 20 obs. of 16 variables:
$ formula : chr "F(p1)" "F(p1)" "!(F(p1))" "!(F(p1))" ... $ formula : chr "F(p1)" "F(p1)" "!(F(p1))" "!(F(p1))" ...
$ tool : chr "small" "deter" "small" "deter" ... $ tool : chr "small" "deter" "small" "deter" ...
$ exit_status : chr "ok" "ok" "ok" "ok" ... $ exit_status : chr "ok" "ok" "ok" "ok" ...
$ exit_code : int 0 0 0 0 0 0 0 0 0 0 ... $ 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 ... $ states : int 2 2 1 1 4 4 3 3 8 8 ...
$ edges : int 3 3 1 1 9 9 5 5 27 27 ... $ edges : int 3 3 1 1 9 9 5 5 27 27 ...
$ transitions : int 4 4 1 1 16 16 7 7 64 64 ... $ 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 same line: using exactly one line per formula. This is easily
achieved using =dcast()= from the =data.table= library. 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=".") dt2 <- dcast(dt, formula ~ tool, value.var=names(dt)[-(1:2)], sep=".")
str(dt2) str(dt2)
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
#+begin_example #+begin_example
Classes data.table and 'data.frame': 10 obs. of 29 variables: 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)))" ... $ 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.deter : chr "ok" "ok" "ok" "ok" ...
$ exit_status.small : 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.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 $ 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.deter : num 0.0172 0.0212 0.02 0.0191 0.0282 ...
$ time.small : num 0.0171 0.0155 0.0152 0.0146 0.0139 ... $ 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.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 $ 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 $ 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 =ltl2tgba= for each formula, we just need to plot column
=dt2$state.small= against =dt2$state.deter=. =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) library(ggplot2)
ggplot(dt2, aes(x=states.small, y=states.deter)) + ggplot(dt2, aes(x=states.small, y=states.deter)) +
geom_abline(colour='white') + geom_point() 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 We should probably print the formulas for the cases where the two
sizes differ. 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)) + ggplot(dt2, aes(x=states.small, y=states.deter)) +
geom_abline(colour='white') + geom_point() + 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) aes(label=formula), hjust=0, nudge_x=.5)
#+END_SRC #+END_SRC
@ -942,52 +932,47 @@ If =--save-bogus=OTHERFILENAME= is provided, every bogus formula found
during the process will be saved in =OTHERFILENAME=. during the process will be saved in =OTHERFILENAME=.
Example: 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" \ ltlcross -f '(G!b & (!c | F!a)) | (c & Ga & Fb)' "modella %L %O" \
--save-bogus=bogus \ --save-bogus=bogus \
--grind=bogus-grind --grind=bogus-grind
#+END_SRC #+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: #+RESULTS:
#+begin_example #+begin_example
| & G ! p0 | ! p1 F ! p2 & & p1 G p2 F p0 | & G ! p0 | ! p1 F ! p2 & & p1 G p2 F p0
Running [P0]: modella 'lcr-i0-FUPmeY' 'lcr-o0-F3bZRp' Running [P0]: modella 'lcr-i0-Nc8B1P' 'lcr-o0-CDjvYF'
Running [N0]: modella 'lcr-i0-ebjQwR' 'lcr-o0-20eIbj' Running [N0]: modella 'lcr-i0-Io4LVv' 'lcr-o0-C482Sl'
Performing sanity checks and gathering statistics... Performing sanity checks and gathering statistics...
error: P0*N0 is nonempty; both automata accept the infinite word: error: P0*N0 is nonempty; both automata accept the infinite word:
cycle{!p0 & !p1} cycle{!p0 & !p1}
Trying to find a bogus mutation of (G!b & (!c | F!a)) | (c & Ga & Fb)... Trying to find a bogus mutation of (G!b & (!c | F!a)) | (c & Ga & Fb)...
Mutation 1/22: & & p0 G p1 F p2 Mutation 1/22: & & p0 G p1 F p2
Running [P0]: modella 'lcr-i1-zXEyXK' 'lcr-o0-RsypJc' Running [P0]: modella 'lcr-i1-EmhjSb' 'lcr-o0-q1GzR1'
Running [N0]: modella 'lcr-i1-Ux7xvE' 'lcr-o0-x19Gh6' Running [N0]: modella 'lcr-i1-mwR1QR' 'lcr-o0-gEcuQH'
Performing sanity checks and gathering statistics... Performing sanity checks and gathering statistics...
Mutation 2/22: & G ! p0 | ! p1 F ! p2 Mutation 2/22: & G ! p0 | ! p1 F ! p2
Running [P0]: modella 'lcr-i2-syS74x' 'lcr-o0-wPRySZ' Running [P0]: modella 'lcr-i2-4UoNQx' 'lcr-o0-W9W6Qn'
Running [N0]: modella 'lcr-i2-x9DdGr' 'lcr-o0-fgHStT' Running [N0]: modella 'lcr-i2-h5IDRd' 'lcr-o0-VDFaS3'
Performing sanity checks and gathering statistics... Performing sanity checks and gathering statistics...
Mutation 3/22: | G ! p0 & & p1 G p2 F p0 Mutation 3/22: | G ! p0 & & p1 G p2 F p0
Running [P0]: modella 'lcr-i3-rVOAil' 'lcr-o0-jU2i7M' Running [P0]: modella 'lcr-i3-bkvvTT' 'lcr-o0-wMAQUJ'
Running [N0]: modella 'lcr-i3-KATfWe' 'lcr-o0-2UOcLG' Running [N0]: modella 'lcr-i3-qoYoWz' 'lcr-o0-ILwXXp'
Performing sanity checks and gathering statistics... Performing sanity checks and gathering statistics...
error: P0*N0 is nonempty; both automata accept the infinite word: error: P0*N0 is nonempty; both automata accept the infinite word:
cycle{!p0 & !p1} cycle{!p0 & !p1}
Trying to find a bogus mutation of G!b | (c & Ga & Fb)... Trying to find a bogus mutation of G!b | (c & Ga & Fb)...
Mutation 1/16: t Mutation 1/16: t
Running [P0]: modella 'lcr-i4-OJk2B8' 'lcr-o0-VVCSsA' Running [P0]: modella 'lcr-i4-avS30f' 'lcr-o0-MYCa45'
Running [N0]: modella 'lcr-i4-nKwTj2' 'lcr-o0-npMUau' Running [N0]: modella 'lcr-i4-vJss7V' 'lcr-o0-ItCKaM'
Performing sanity checks and gathering statistics... Performing sanity checks and gathering statistics...
Mutation 2/16: G ! p0 Mutation 2/16: G ! p0
Running [P0]: modella 'lcr-i5-Waoe2V' 'lcr-o0-9wsyTn' Running [P0]: modella 'lcr-i5-TG7leC' 'lcr-o0-N6UXhs'
Running [N0]: modella 'lcr-i5-M0R2KP' 'lcr-o0-uhmxCh' Running [N0]: modella 'lcr-i5-KwJJli' 'lcr-o0-kbRvp8'
Performing sanity checks and gathering statistics... Performing sanity checks and gathering statistics...
Mutation 3/16: & & p0 G p1 F p2 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. Use --allow-dups if it should not be ignored.
Mutation 4/16: | G ! p0 & p1 F p0 Mutation 4/16: | G ! p0 & p1 F p0
Running [P0]: modella 'lcr-i6-OtIGuJ' 'lcr-o0-qBEQmb' Running [P0]: modella 'lcr-i6-otaRtY' 'lcr-o0-bRLcyO'
Running [N0]: modella 'lcr-i6-MGbcfD' 'lcr-o0-t93x74' Running [N0]: modella 'lcr-i6-3DMJCE' 'lcr-o0-v04gHu'
Performing sanity checks and gathering statistics... Performing sanity checks and gathering statistics...
error: P0*N0 is nonempty; both automata accept the infinite word: error: P0*N0 is nonempty; both automata accept the infinite word:
cycle{!p0 & !p1} 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. Use --allow-dups if it should not be ignored.
Mutation 3/10: & p0 F p1 Mutation 3/10: & p0 F p1
Running [P0]: modella 'lcr-i7-4oa00w' 'lcr-o0-3IEsUY' Running [P0]: modella 'lcr-i7-gKcHMk' 'lcr-o0-UPD7Ra'
Running [N0]: modella 'lcr-i7-vyy5Nq' 'lcr-o0-nXOIHS' Running [N0]: modella 'lcr-i7-4HUKX0' 'lcr-o0-Dpno3Q'
Performing sanity checks and gathering statistics... Performing sanity checks and gathering statistics...
Mutation 4/10: | p0 G ! p1 Mutation 4/10: | p0 G ! p1
Running [P0]: modella 'lcr-i8-Kt48Bk' 'lcr-o0-xeIzwM' Running [P0]: modella 'lcr-i8-H6GH9G' 'lcr-o0-xyO1fx'
Running [N0]: modella 'lcr-i8-ye5are' 'lcr-o0-3QMMlG' Running [N0]: modella 'lcr-i8-w3vxmn' 'lcr-o0-wgw3sd'
Performing sanity checks and gathering statistics... Performing sanity checks and gathering statistics...
Mutation 5/10: | G ! p0 F p0 Mutation 5/10: | G ! p0 F p0
Running [P0]: modella 'lcr-i9-Bpmah8' 'lcr-o0-38lycA' Running [P0]: modella 'lcr-i9-vt8eA3' 'lcr-o0-982qHT'
Running [N0]: modella 'lcr-i9-cQJ771' 'lcr-o0-yUcH3t' Running [N0]: modella 'lcr-i9-qrbNOJ' 'lcr-o0-ceD9Vz'
Performing sanity checks and gathering statistics... Performing sanity checks and gathering statistics...
Mutation 6/10: | ! p0 & p1 F p0 Mutation 6/10: | ! p0 & p1 F p0
Running [P0]: modella 'lcr-i10-mYtDZV' 'lcr-o0-nCdAVn' Running [P0]: modella 'lcr-i10-6upQ3p' 'lcr-o0-EStxbg'
Running [N0]: modella 'lcr-i10-d1fIRP' 'lcr-o0-oAsQNh' Running [N0]: modella 'lcr-i10-7nUoj6' 'lcr-o0-e4DgrW'
Performing sanity checks and gathering statistics... Performing sanity checks and gathering statistics...
Mutation 7/10: | & p1 F p0 G p0 Mutation 7/10: | & p1 F p0 G p0
Running [P0]: modella 'lcr-i11-petsKJ' 'lcr-o0-Z3U4Gb' Running [P0]: modella 'lcr-i11-ohXyzM' 'lcr-o0-bozRHC'
Running [N0]: modella 'lcr-i11-bmFSDD' 'lcr-o0-P1DGA5' Running [N0]: modella 'lcr-i11-6wYkQs' 'lcr-o0-TCxOYi'
Performing sanity checks and gathering statistics... Performing sanity checks and gathering statistics...
Mutation 8/10: | & p0 p1 G ! p0 Mutation 8/10: | & p0 p1 G ! p0
Running [P0]: modella 'lcr-i12-eUjByx' 'lcr-o0-DZAwwZ' Running [P0]: modella 'lcr-i12-51Vd88' 'lcr-o0-uWKDhZ'
Running [N0]: modella 'lcr-i12-v3JCur' 'lcr-o0-IzWIsT' Running [N0]: modella 'lcr-i12-0OkfrP' 'lcr-o0-aEdRAF'
Performing sanity checks and gathering statistics... Performing sanity checks and gathering statistics...
Mutation 9/10: | G ! p0 & p0 F p0 Mutation 9/10: | G ! p0 & p0 F p0
Running [P0]: modella 'lcr-i13-Sb2Arl' 'lcr-o0-kBwtqN' Running [P0]: modella 'lcr-i13-vy57Kv' 'lcr-o0-lcfpVl'
Running [N0]: modella 'lcr-i13-Tctwpf' 'lcr-o0-hvIzoH' Running [N0]: modella 'lcr-i13-D7SQ5b' 'lcr-o0-k8Hig2'
Performing sanity checks and gathering statistics... Performing sanity checks and gathering statistics...
error: P0*N0 is nonempty; both automata accept the infinite word: error: P0*N0 is nonempty; both automata accept the infinite word:
cycle{!p0} 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. Use --allow-dups if it should not be ignored.
Mutation 3/7: & p0 F p0 Mutation 3/7: & p0 F p0
Running [P0]: modella 'lcr-i14-iDAoo9' 'lcr-o0-6vSdoB' Running [P0]: modella 'lcr-i14-AvSorS' 'lcr-o0-AZkvCI'
Running [N0]: modella 'lcr-i14-WMIdo3' 'lcr-o0-NxEdov' Running [N0]: modella 'lcr-i14-Hd7LNy' 'lcr-o0-pM82Yo'
Performing sanity checks and gathering statistics... Performing sanity checks and gathering statistics...
Mutation 4/7: | p0 G ! p0 Mutation 4/7: | p0 G ! p0
Running [P0]: modella 'lcr-i15-lS5FoX' 'lcr-o0-XFX8op' Running [P0]: modella 'lcr-i15-tygKaf' 'lcr-o0-YHFrm5'
Running [N0]: modella 'lcr-i15-8IdNpR' 'lcr-o0-0Bxrqj' Running [N0]: modella 'lcr-i15-GL9iyV' 'lcr-o0-riOaKL'
Performing sanity checks and gathering statistics... Performing sanity checks and gathering statistics...
Mutation 5/7: | G ! p0 F p0 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. Use --allow-dups if it should not be ignored.
Mutation 6/7: | ! p0 & p0 F p0 Mutation 6/7: | ! p0 & p0 F p0
Running [P0]: modella 'lcr-i16-7boQrL' 'lcr-o0-wsIftd' Running [P0]: modella 'lcr-i16-M0RHWB' 'lcr-o0-iVlf9r'
Running [N0]: modella 'lcr-i16-tk8OuF' 'lcr-o0-9wQow7' Running [N0]: modella 'lcr-i16-WD4Xli' 'lcr-o0-Ez6Gy8'
Performing sanity checks and gathering statistics... Performing sanity checks and gathering statistics...
Mutation 7/7: | G p0 & p0 F p0 Mutation 7/7: | G p0 & p0 F p0
Running [P0]: modella 'lcr-i17-wnlkyz' 'lcr-o0-MAjgA1' Running [P0]: modella 'lcr-i17-F1BLLY' 'lcr-o0-Z9nQYO'
Running [N0]: modella 'lcr-i17-qFLnCt' 'lcr-o0-45gvEV' Running [N0]: modella 'lcr-i17-efo5bF' 'lcr-o0-fFzkpv'
Performing sanity checks and gathering statistics... Performing sanity checks and gathering statistics...
Smallest bogus mutation found for (G!b & (!c | F!a)) | (c & Ga & Fb) is G!c | (c & Fc). 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. Check file bogus for problematic formulas.
#+end_example #+end_example
#+BEGIN_SRC sh :exports both :results verbatim #+BEGIN_SRC sh
cat bogus cat bogus
#+END_SRC #+END_SRC
@ -1096,7 +1081,7 @@ cat bogus
: G!b | (c & Fb) : G!b | (c & Fb)
: G!c | (c & Fc) : G!c | (c & Fc)
#+BEGIN_SRC sh :exports both :results verbatim #+BEGIN_SRC sh
cat bogus-grind cat bogus-grind
#+END_SRC #+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 positives ones in the results. Therefore the =--no-check= option can
be used to gather statistics about a specific set of formulas. 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= ** =--verbose=
:PROPERTIES: :PROPERTIES:
:CUSTOM_ID: verbose :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 produce transition-based generalized Büchi automata, while =ltl3ba
-H1= produces co-Büchi alternating automata. -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 ltlcross -f 'FGa' ltl2tgba 'ltl3ba -H1' --determinize --verbose
#+END_SRC #+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: #+RESULTS:
#+begin_example #+begin_example
F(G(a)) F(G(a))
Running [P0]: ltl2tgba -H 'F(G(a))'>'lcr-o0-opbyhq' Running [P0]: ltl2tgba -H 'F(G(a))'>'lcr-o0-cNwEjy'
Running [P1]: ltl3ba -H1 -f '<>([](a))'>'lcr-o1-aP47sS' Running [P1]: ltl3ba -H1 -f '<>([](a))'>'lcr-o1-WQo28q'
Running [N0]: ltl2tgba -H '!(F(G(a)))'>'lcr-o0-UV1eFk' Running [N0]: ltl2tgba -H '!(F(G(a)))'>'lcr-o0-KT96Zj'
Running [N1]: ltl3ba -H1 -f '!(<>([](a)))'>'lcr-o1-bFSrTM' Running [N1]: ltl3ba -H1 -f '!(<>([](a)))'>'lcr-o1-WE1RXc'
info: collected automata: info: collected automata:
info: P0 (2 st.,3 ed.,1 sets) info: P0 (2 st.,3 ed.,1 sets)
info: N0 (1 st.,2 ed.,1 sets) deterministic complete 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 Note that if we had not used the =--determinize= option, the procedure
would look slightly more complex: 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 ltlcross -f 'FGa' ltl2tgba 'ltl3ba -H1' --verbose
#+END_SRC #+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: #+RESULTS:
#+begin_example #+begin_example
F(G(a)) F(G(a))
Running [P0]: ltl2tgba -H 'F(G(a))'>'lcr-o0-cq9s5c' Running [P0]: ltl2tgba -H 'F(G(a))'>'lcr-o0-Ot1KDa'
Running [P1]: ltl3ba -H1 -f '<>([](a))'>'lcr-o1-Fb0iii' Running [P1]: ltl3ba -H1 -f '<>([](a))'>'lcr-o1-Kvzdfm'
Running [N0]: ltl2tgba -H '!(F(G(a)))'>'lcr-o0-X5dGvn' Running [N0]: ltl2tgba -H '!(F(G(a)))'>'lcr-o0-X2dURx'
Running [N1]: ltl3ba -H1 -f '!(<>([](a)))'>'lcr-o1-tLO5Ks' Running [N1]: ltl3ba -H1 -f '!(<>([](a)))'>'lcr-o1-wuLpzJ'
info: collected automata: info: collected automata:
info: P0 (2 st.,3 ed.,1 sets) info: P0 (2 st.,3 ed.,1 sets)
info: N0 (1 st.,2 ed.,1 sets) deterministic complete 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 the output of =ltl2tgba= against this reference. See how the number
of tests performed has been reduced. 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 ltlcross -f 'FGa' ltl2tgba --reference 'ltl3ba -H1' --verbose
#+END_SRC #+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: #+RESULTS:
#+begin_example #+begin_example
F(G(a)) F(G(a))
Running [P0]: ltl3ba -H1 -f '<>([](a))'>'lcr-o0-UanRv9' Running [P0]: ltl3ba -H1 -f '<>([](a))'>'lcr-o0-hsnlkV'
Running [P1]: ltl2tgba -H 'F(G(a))'>'lcr-o1-43jbVn' Running [P1]: ltl2tgba -H 'F(G(a))'>'lcr-o1-R0jOmP'
Running [N0]: ltl3ba -H1 -f '!(<>([](a)))'>'lcr-o0-TUeymC' Running [N0]: ltl3ba -H1 -f '!(<>([](a)))'>'lcr-o0-7GwxvJ'
Running [N1]: ltl2tgba -H '!(F(G(a)))'>'lcr-o1-5PYsOQ' Running [N1]: ltl2tgba -H '!(F(G(a)))'>'lcr-o1-5sgPFD'
info: collected automata: info: collected automata:
info: P0 (2 st.,3 ed.,1 sets) info: P0 (2 st.,3 ed.,1 sets)
info: N0 (3 st.,5 ed.,1 sets) univ-edges complete 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. No problem detected.
#+end_example #+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 #+DESCRIPTION: Spot's wrapper for third-party LTL translators
#+INCLUDE: setup.org #+INCLUDE: setup.org
#+HTML_LINK_UP: tools.html #+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 This tool is a wrapper for tools that read LTL/PSL formulas and
(optionally) output automata. (optionally) output automata.
@ -26,7 +27,7 @@ Büchi automaton produced by =ltl3ba=.
Here is the input file: Here is the input file:
#+BEGIN_SRC sh :results silent :exports both #+BEGIN_SRC sh :results silent
cat >sample.ltl <<EOF cat >sample.ltl <<EOF
1 1
1 U a 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: Here is how the shell command could look like:
#+BEGIN_SRC sh :results verbatim :exports both #+BEGIN_SRC sh
ltlfilt -F sample.ltl -s | ltlfilt -F sample.ltl -s |
while read f; do while read f; do
ltl3ba -f "$f" | autfilt --stats="$f,%s,%t" 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: 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' ltldo 'ltl3ba -f %s>%O' -F sample.ltl --stats='%f,%s,%t'
#+END_SRC #+END_SRC
#+RESULTS: #+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 already knows about, so there is a shorter way to run the above
command: command:
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh :exports code
ltldo ltl3ba -F sample.ltl --stats='%f,%s,%t' ltldo ltl3ba -F sample.ltl --stats='%f,%s,%t'
#+END_SRC #+END_SRC
#+RESULTS: #+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 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. converts the never claim produced by =spin= into this format.
#+BEGIN_SRC sh :results verbatim :exports both :wrap SRC hoa #+BEGIN_SRC sh :wrap SRC hoa
ltldo -f a -f GFa 'spin -f %s>%O' ltldo 'spin -f %s>%O' -f a -f GFa
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
@ -177,7 +178,7 @@ simplified to just this:
The syntax for specifying how a tool should be called is the same as 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. 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' ltldo --help | sed -n '/character sequences:/,/^$/p' | sed '1d;$d'
#+END_SRC #+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 we could simply run a formula though =echo= to compare different
output syntaxes: output syntaxes:
#+BEGIN_SRC sh :results verbatim :exports both #+BEGIN_SRC sh
ltldo -f 'p0 U p1' -f 'GFp0' 'echo %f, %s, %l, %w' ltldo -f 'p0 U p1' -f 'GFp0' 'echo %f, %s, %l, %w'
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
@ -211,7 +212,7 @@ executed on each formula in the same order.
A typical use-case is to compare statistics of different tools: 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 ltldo -F sample.ltl 'spin -f %s>%O' 'ltl3ba -f %s>%O' --stats=%T,%f,%s,%e
#+END_SRC #+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 using the trick that the command =echo %f= will not be subject to
=--stats= (since it does not declare any output automaton). =--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 \ ltldo -F sample.ltl --stats=%T,%s,%e \
'echo "#" %f' '{spin}spin -f %s>%O' '{ltl3ba}ltl3ba -f %s>%O' 'echo "#" %f' '{spin}spin -f %s>%O' '{ltl3ba}ltl3ba -f %s>%O'
#+END_SRC #+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 have built-in specifications. This list can be printed using the
=--list-shorthands= option: =--list-shorthands= option:
#+BEGIN_SRC sh :results verbatim :exports both #+BEGIN_SRC sh
ltldo --list-shorthands ltldo --list-shorthands
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
@ -327,22 +328,18 @@ will changed into
'{DRA} ~/mytools/ltl2dstar-0.5.2 --output-format=hoa %[MR]L %O' '{DRA} ~/mytools/ltl2dstar-0.5.2 --output-format=hoa %[MR]L %O'
#+end_example #+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 ltldo ltl2ba -f a -d
#+END_SRC #+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: #+RESULTS:
#+begin_example #+begin_example
digraph G { digraph "" {
rankdir=LR rankdir=LR
label="\n[Büchi]"
labelloc="t"
node [shape="circle"] node [shape="circle"]
I [label="", style=invis, width=0] I [label="", style=invis, width=0]
I -> 0 I -> 0
@ -356,14 +353,13 @@ digraph G {
The =ltl2ba= argument passed to =ltldo= was interpreted as if you had The =ltl2ba= argument passed to =ltldo= was interpreted as if you had
typed ={ltl2ba}ltl2ba -f %s>%O=. 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 string that does not use any =%= character. This makes it possible to
add options: add options:
#+BEGIN_SRC sh :results verbatim :exports both #+BEGIN_SRC sh
ltldo ltl3ba 'ltl3ba -H2' -f GFa --stats='%T, %s states, %e edges' ltldo ltl3ba 'ltl3ba -H2' -f GFa --stats='%T, %s states, %e edges'
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
: ltl3ba, 2 states, 4 edges : ltl3ba, 2 states, 4 edges
: ltl3ba -H2, 1 states, 2 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 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: 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' spin -f '[]!Error'
#+END_SRC #+END_SRC
#+RESULTS: #+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: expected predicate, saw 'E'
: tl_spin: []!Error : tl_spin: []!Error
: -------------^ : -------------^
@ -391,14 +382,14 @@ only atomic propositions starting with a lowercase letter.
Running the same command through =ltldo= will work: Running the same command through =ltldo= will work:
#+BEGIN_SRC sh :results verbatim :exports both #+BEGIN_SRC sh
ltldo spin -f '[]!Error' -s ltldo spin -f '[]!Error' -s
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
: never { : never {
: accept_init: : accept_init:
: if : if
: :: ((!(Error))) -> goto accept_init : :: (!(Error)) -> goto accept_init
: fi; : 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 automaton uses the atomic proposition =Error=, but its name contains a
reference to =p0=. reference to =p0=.
#+BEGIN_SRC sh :results verbatim :exports both :wrap SRC hoa #+BEGIN_SRC sh :wrap SRC hoa
ltldo 'ltl3ba -H' -f '[]!Error' ltldo 'ltl3ba -H' -f '[]!Error'
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
@ -451,7 +442,7 @@ State: 0 "accept_init" {0}
If this is a problem, you can always force a new name with the If this is a problem, you can always force a new name with the
=--name= option: =--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' ltldo 'ltl3ba -H' -f '[]!Error' --name='BA for %f'
#+END_SRC #+END_SRC
@ -480,7 +471,7 @@ State: 0 "accept_init" {0}
Here is a formula on which different translators produce Büchi automata of Here is a formula on which different translators produce Büchi automata of
different sizes (states and edges): 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)' \ ltldo ltl2ba ltl3ba 'ltl2tgba -s' -f 'F(a & Xa | FGa)' \
--stats='%T: %s st. (%n non-det.), %e ed.' --stats='%T: %s st. (%n non-det.), %e ed.'
#+END_SRC #+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 translator, =ltldo= can also be configured to output the smallest
automaton obtained for each formula: 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 ltldo ltl2ba ltl3ba 'ltl2tgba -s' -f 'F(a & Xa | FGa)' --smallest
#+END_SRC #+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 case of equality the smallest number of non-deterministic states, we
can use the following command instead. 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 ltldo ltl2ba ltl3ba 'ltl2tgba -s' -f 'F(a & Xa | FGa)' --smallest=%s,%n
#+END_SRC #+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 =ltl2ba=, =ltl3ba=, and =ltl2tgba -s= would produce the smallest
automaton. automaton.
#+BEGIN_SRC sh :results verbatim :exports both #+BEGIN_SRC sh
genltl --dac=10..20 --format=%F:%L,%f | genltl --dac=10..20 --format=%F:%L,%f |
ltldo -F-/2 ltl2ba ltl3ba 'ltl2tgba -s' --smallest --stats='%<,%T' ltldo -F-/2 ltl2ba ltl3ba 'ltl2tgba -s' --smallest --stats='%<,%T'
#+END_SRC #+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 To understand the above pipeline, remove the =ltldo= invocation. The
[[file:genltl.org][=genltl=]] command outputs this: [[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 genltl --dac=10..20 --format=%F:%L,%f
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:

View file

@ -3,6 +3,7 @@
#+DESCRIPTION: Spot command-line tool for filtering, tranforming, and converting LTL formulas. #+DESCRIPTION: Spot command-line tool for filtering, tranforming, and converting LTL formulas.
#+INCLUDE: setup.org #+INCLUDE: setup.org
#+HTML_LINK_UP: tools.html #+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 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: 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 using infix notation (with different names supported for the same
operators) and convert it into LBT's syntax. 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' ltlfilt -l -f 'p1 U (p2 & GFp3)' -f 'X<>[]p4'
#+END_SRC #+END_SRC
#+RESULTS: #+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 Conversely, here is how to rewrite formulas expressed using the
LBT's Polish notation. Let's take the following four formulas LBT's Polish notation. Let's take the following four formulas
taken from examples distributed with =scheck=: taken from examples distributed with =scheck=:
#+BEGIN_SRC sh :results verbatim :exports both #+BEGIN_SRC sh
cat >scheck.ltl<<EOF cat >scheck.ltl<<EOF
! | G p0 & G p1 F p3 ! | G p0 & G p1 F p3
| | X p7 F p6 & | | t p3 p7 U | f p3 p3 | | X p7 F p6 & | | t p3 p7 U | f p3 p3
@ -44,7 +45,7 @@ EOF
#+RESULTS: #+RESULTS:
These can be turned into something easier to read (to the human) with: 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 ltlfilt --lbt-input -F scheck.ltl
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
@ -58,7 +59,7 @@ ltlfilt --lbt-input -F scheck.ltl
The following options can be used to modify the formulas that have The following options can be used to modify the formulas that have
been read. been read.
#+BEGIN_SRC sh :results verbatim :exports results #+BEGIN_SRC sh :exports results
ltlfilt --help | sed -n '/Transformation options.*:/,/^$/p' | sed '1d;$d' ltlfilt --help | sed -n '/Transformation options.*:/,/^$/p' | sed '1d;$d'
#+END_SRC #+END_SRC
#+RESULTS: #+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. 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 ltlfilt --lbt-input -F scheck.ltl -r
#+END_SRC #+END_SRC
#+RESULTS: #+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=, letters of the alphabet, while =--relabel=pnn= will use =p0=, =p1=,
etc. as in LBT's syntax. 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 ltlfilt --lbt-input -F scheck.ltl -r --relabel=abc
#+END_SRC #+END_SRC
#+RESULTS: #+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 Another use of relabeling is to get rid of complex atomic propositions
such as the one shown when [[file:ioltl.org][presenting lenient mode]]: 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)' ltlfilt --lenient --relabel=pnn -f '(a < b) U (process[2]@ok)'
#+END_SRC #+END_SRC
#+RESULTS: #+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 option, Boolean subformulas that do not interfere with other
subformulas will be changed into atomic propositions. For instance: 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)' --relabel-bool=pnn
ltlfilt -f '(a & !b) & GF(a & !b) & FG(!c & a)' --relabel-bool=pnn ltlfilt -f '(a & !b) & GF(a & !b) & FG(!c & a)' --relabel-bool=pnn
#+END_SRC #+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 as well. For instance here are some LTL formulas extracted from an
[[http://www.fi.muni.cz/~xrehak/publications/verificationresults.ps.gz][industrial project]]: [[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 ltlfilt --nnf -u --relabel-bool <<EOF
G (hfe_rdy -> F !hfe_req) G (hfe_rdy -> F !hfe_req)
G (lup_sr_valid -> F lup_sr_clean ) 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= between old and new names to be printed as a set of =#define=
statements. 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 ltlfilt -f '(a & !b) & GF(a & !b) & FG(!c)' --relabel-bool=pnn --define --spin
#+END_SRC #+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 a neverclaim for an LTL formula containing atomic propositions that
=ltl3ba= cannot parse: =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 | ltlfilt -f '"proc@loc1" U "proc@loc2"' --relabel=pnn --define=ltlex.def --spin |
ltl3ba -F - >ltlex.never ltl3ba -F - >ltlex.never
cat ltlex.def 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: 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 ltldo ltl3ba -f '"proc@loc1" U "proc@loc2"' --spin
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
@ -292,7 +293,7 @@ separate page]].
=ltlfilt= supports many ways to filter formulas: =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' ltlfilt --help | sed -n '/Filtering options.*:/,/^$/p' | sed '1d;$d'
#+END_SRC #+END_SRC
#+RESULTS: #+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= the following command will extract all formulas from =scheck.ltl=
which do not represent guarantee properties. which do not represent guarantee properties.
#+BEGIN_SRC sh :results verbatim :exports both #+BEGIN_SRC sh
ltlfilt --lbt-input -F scheck.ltl -v --guarantee ltlfilt --lbt-input -F scheck.ltl -v --guarantee
#+END_SRC #+END_SRC
#+RESULTS: #+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 formulas that respect certain constraints. For instance let us
generate 10 formulas that are equivalent to =a U b=: 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 randltl -n -1 a b | ltlfilt --equivalent-to 'a U b' -n 10
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
@ -375,7 +376,7 @@ syntactically. We can generate some starting again with =randltl=,
then ignoring all syntactic safety formulas, and keeping only the then ignoring all syntactic safety formulas, and keeping only the
safety formulas in the remaining list. 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 randltl -r -n -1 a b | ltlfilt -v --syntactic-safety | ltlfilt --safety -n 10
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
@ -397,7 +398,7 @@ Ga | (!b U !a)
about a single formula. For instance is =a U (b U a)= equivalent to about a single formula. For instance is =a U (b U a)= equivalent to
=b U a=? =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' ltlfilt -f 'a U (b U a)' --equivalent-to 'b U a'
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
@ -410,7 +411,7 @@ status to 1, were the two formulas not equivalent.
Is the formula =F(a & X(!a & Gb))= stutter-invariant? 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 ltlfilt -f 'F(a & X(!a & Gb))' --stutter-invariant
#+END_SRC #+END_SRC
#+RESULTS: #+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= equivalent formulas that do not use =X= operator. The =--remove-x=
option gives one: option gives one:
#+BEGIN_SRC sh :results verbatim :exports both #+BEGIN_SRC sh
ltlfilt -f 'F(a & X(!a & Gb))' --remove-x ltlfilt -f 'F(a & X(!a & Gb))' --remove-x
#+END_SRC #+END_SRC
#+RESULTS: #+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 We could even verify that the resulting horrible formula is equivalent
to the original one: 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))' ltlfilt -f 'F(a & X(!a & Gb))' --remove-x | ltlfilt --equivalent-to 'F(a & X(!a & Gb))'
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
@ -447,7 +448,7 @@ the formula generated randomly can be reduced by trivial
simplifications such as =!!f= being rewritten to =f=, yielding simplifications such as =!!f= being rewritten to =f=, yielding
formulas of smaller sizes). 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 randltl -n -1 --tree-size=8 a b | ltlfilt --size=5 -n 10
#+END_SRC #+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 influence on the overall translation. Here are 10 random formula with
Boolean-size 5: 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 randltl -n -1 --tree-size=12 a b | ltlfilt --bsize=5 -n 10
#+END_SRC #+END_SRC
@ -495,7 +496,7 @@ GF(1 U b)
The =--format= option can be used the alter the way formulas are output. 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: 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' ltlfilt --help | sed -n '/ sequences:/,/^$/p' | sed '1d;$d'
#+END_SRC #+END_SRC
#+RESULTS: #+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 some criterion. In the following, we print only the numbers of the
lines of =scheck.ltl= that contain guarantee formulas: 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 ltlfilt --lbt-input -F scheck.ltl --guarantee --format=%L
#+END_SRC #+END_SRC
#+RESULTS: #+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 We could also prefix each formula by its size, in order to sort
the file by formula size: 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 ltlfilt --lbt-input scheck.ltl --format='%s,%f' | sort -n
#+END_SRC #+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 For instance here is how to split =scheck.ltl= according to formula
sizes. sizes.
#+BEGIN_SRC sh :results verbatim :exports both #+BEGIN_SRC sh
ltlfilt --lbt-input scheck.ltl --output='scheck-%s.ltl' ltlfilt --lbt-input scheck.ltl --output='scheck-%s.ltl'
wc -l scheck*.ltl wc -l scheck*.ltl
#+END_SRC #+END_SRC
@ -587,7 +588,7 @@ wc -l scheck*.ltl
: 4 scheck.ltl : 4 scheck.ltl
: 8 total : 8 total
#+BEGIN_SRC sh :results verbatim :exports both #+BEGIN_SRC sh
rm -f ltlex.def ltlex.never scheck.ltl rm -f ltlex.def ltlex.never scheck.ltl
#+END_SRC #+END_SRC

View file

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

View file

@ -3,6 +3,7 @@
#+DESCRIPTION: Spot command-line tool for synthesizing AIGER circuits from LTL/PSL formulas. #+DESCRIPTION: Spot command-line tool for synthesizing AIGER circuits from LTL/PSL formulas.
#+INCLUDE: setup.org #+INCLUDE: setup.org
#+HTML_LINK_UP: tools.html #+HTML_LINK_UP: tools.html
#+PROPERTY: header-args:sh :results verbatim :exports both
* Basic usage * Basic usage
@ -23,7 +24,7 @@ N}$ satisfies \phi.
The following example illustrates the synthesis of a controller acting as an 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= =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: 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)' ltlsynt --ins=a,b --outs=c -f 'G (a & b <=> c)'
#+END_SRC #+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 =a= is an input proposition, there is no way to guarantee that it will
eventually hold. eventually hold.
#+BEGIN_SRC sh :results verbatim :exports both #+BEGIN_SRC sh :epilogue true
ltlsynt --ins=a --outs=b -f 'F a' ltlsynt --ins=a --outs=b -f 'F a'
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
#+begin_example : UNREALIZABLE
UNREALIZABLE
#+end_example
By default, the controller is output in HOA format, but it can be output as an 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 The following four steps show you how a TLSF specification called spec.tlsf can
be synthesized using =syfco= and =ltlsynt=: be synthesized using =syfco= and =ltlsynt=:
#+BEGIN_SRC sh #+BEGIN_SRC sh :export code
LTL=$(syfco FILE -f ltlxba -m fully) LTL=$(syfco FILE -f ltlxba -m fully)
IN=$(syfco FILE -f ltlxba -m fully) IN=$(syfco FILE -f ltlxba -m fully)
OUT=$(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 [[https://github.com/tcsprojects/pgsolver][PGSolver]] format, with the flag
=--print-pg=. Note that this flag deactivates the resolution of the parity =--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. 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 #+DESCRIPTION: Options for input and output of ω-automata in Spot's command-line tools
#+INCLUDE: setup.org #+INCLUDE: setup.org
#+HTML_LINK_UP: tools.html #+HTML_LINK_UP: tools.html
#+PROPERTY: header-args:sh :results verbatim :exports both
Spot supports different output syntaxes for automata. This page Spot supports different output syntaxes for automata. This page
documents the options, common to all tools where it makes sense, that 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: 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' ltl2tgba --help | sed -n '/Output format:/,/^$/p' | sed '1d;$d'
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
@ -86,7 +87,7 @@ printer.
Here is an example where [[file:ltl2tgba.org][=ltl2tgba=]] is used to construct two automata: 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=. 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' ltl2tgba 'a U b' '(Ga -> Gb) W c'
#+END_SRC #+END_SRC
#+RESULTS: #+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: represent. Here is a picture of these two automata:
#+NAME: hoafex #+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 | 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' perl -pe 's/\\\n//g;s/\\/\\\\/g;s/graph G/graph cluster/g'
#+END_SRC #+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 transition-based acceptance. For instance compare this output to the
previous one: previous one:
#+BEGIN_SRC sh :results verbatim :exports both :wrap SRC hoa #+BEGIN_SRC sh :wrap SRC hoa
ltl2tgba -Ht 'a U b' ltl2tgba -Ht 'a U b'
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
@ -343,7 +344,7 @@ State: 1
Option =m= uses mixed acceptance, i.e, some states might use Option =m= uses mixed acceptance, i.e, some states might use
state-based acceptance while other will not: 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' ltl2tgba -Hm '(Ga -> Gb) W c'
#+END_SRC #+END_SRC
#+RESULTS: #+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, file... Here is an example using both transition-based acceptance,
and single-line output: 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' ltl2tgba -Htl 'a U b' '(Ga -> Gb) W c'
#+END_SRC #+END_SRC
#+RESULTS: #+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 1.1, as far as Spot is concerned, is that some of negated properties
can be transmitted. For instance, compare 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):' ltl2tgba -f GFa -f FGa -H1 --check | grep -E '^(HOA|properties|name):'
#+END_SRC #+END_SRC
@ -416,7 +417,7 @@ properties: weak
versus 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):' ltl2tgba -f GFa -f FGa -H1.1 --check | grep -E '^(HOA|properties|name):'
#+END_SRC #+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 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). 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' ltl2tgba --ba --lbtt 'p0 U p1'
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
@ -460,7 +461,7 @@ ltl2tgba --ba --lbtt 'p0 U p1'
If you want to request transition-based output even for Büchi automata, If you want to request transition-based output even for Büchi automata,
use =--lbtt=t=. use =--lbtt=t=.
#+BEGIN_SRC sh :results verbatim :exports both #+BEGIN_SRC sh
ltl2tgba --ba --lbtt=t 'p0 U p1' ltl2tgba --ba --lbtt=t 'p0 U p1'
#+END_SRC #+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 quotes. This other extension of the format is also supported by
[[http://www.ltl2dstar.de/][ltl2dstar]]. [[http://www.ltl2dstar.de/][ltl2dstar]].
#+BEGIN_SRC sh :results verbatim :exports both #+BEGIN_SRC sh
ltl2tgba --ba --lbtt 'a U b' ltl2tgba --ba --lbtt 'a U b'
#+END_SRC #+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 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=. represent Büchi automata, so these options imply =--ba=.
#+BEGIN_SRC sh :results verbatim :exports both #+BEGIN_SRC sh
ltl2tgba -s 'a U b' ltl2tgba -s 'a U b'
#+END_SRC #+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 in a slightly different style that can be requested using either
=-s6= or =--spin=6=: =-s6= or =--spin=6=:
#+BEGIN_SRC sh :results verbatim :exports both #+BEGIN_SRC sh
ltl2tgba -s6 'a U b' ltl2tgba -s6 'a U b'
#+END_SRC #+END_SRC
@ -543,38 +544,35 @@ of Promela syntax.)
The =-d= or =--dot= option causes automata to be output in GraphViz's The =-d= or =--dot= option causes automata to be output in GraphViz's
format. 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 ltl2tgba '(Ga -> Gb) W c' -d
#+END_SRC #+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 #+RESULTS: oaut-dot1
#+begin_example #+begin_example
digraph G { digraph "(Gb | F!a) W c" {
rankdir=LR rankdir=LR
label="Inf(0)\n[Büchi]"
labelloc="t"
node [shape="circle"] node [shape="circle"]
I [label="", style=invis, width=0] I [label="", style=invis, width=0]
I -> 1 I -> 0
0 [label="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 [label="1"]
1 -> 0 [label="a & b & !c"] 1 -> 1 [label="1\n{0}"]
1 -> 1 [label="!a & !c\n{0}"]
1 -> 2 [label="a & !c"]
1 -> 3 [label="c"]
2 [label="2"] 2 [label="2"]
2 -> 1 [label="!a & !c\n{0}"] 2 -> 2 [label="b\n{0}"]
2 -> 2 [label="a & !c"]
2 -> 3 [label="!a & c"]
2 -> 4 [label="a & c"]
3 [label="3"] 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 [label="4"]
4 -> 3 [label="!a"] 4 -> 1 [label="!a"]
4 -> 4 [label="a"] 4 -> 4 [label="a"]
} }
#+end_example #+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 when =b= is used to ensure the characters ⓿, ❶, etc. are all selected
from the same font. 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' ltl2tgba --dot=vcsna '(Ga -> Gb) W c'
#+END_SRC #+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 #+RESULTS: oaut-dot2
#+begin_example #+begin_example
digraph G { digraph "(Gb | F!a) W c" {
label="(Gb | F!a) W c\nInf(0)\n[Büchi]" label="(Gb | F!a) W c\nInf(0)\n[Büchi]"
labelloc="t" labelloc="t"
node [shape="circle"] node [shape="circle"]
@ -728,7 +677,7 @@ The strongly connected components are displayed using the following colors:
Here is an example involving all colors: Here is an example involving all colors:
#+NAME: oaut-dot3 #+NAME: oaut-dot3
#+BEGIN_SRC sh :results verbatim :exports none #+BEGIN_SRC sh :exports none
SPOT_DOTEXTRA= autfilt --dot=cas <<EOF SPOT_DOTEXTRA= autfilt --dot=cas <<EOF
HOA: v1 HOA: v1
States: 10 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 this documentation are generated with the following environment
variables set: variables set:
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh :exports code
export SPOT_DOTDEFAULT='Brf(Lato)C(#ffffa0)' export SPOT_DOTDEFAULT='Brf(Lato)C(#ffffa0)'
export SPOT_DOTEXTRA='edge[arrowhead=vee, arrowsize=.7]' export SPOT_DOTEXTRA='edge[arrowhead=vee, arrowsize=.7]'
#+END_SRC #+END_SRC
@ -936,7 +885,7 @@ Caveats:
of =dot2tex= was fixed in 2014, but at the time of writing 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, (summer 2017) no new release of =dot2tex= has been made. To work around this,
make sure you install =dot2tex= from its git repository: 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 git clone https://github.com/kjellmf/dot2tex.git
cd dot2tex cd dot2tex
sudo python setup.py install 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=]]: 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' randaut --help | sed -n '/ sequences:/,/^$/p' | sed '1d;$d'
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
@ -972,13 +921,22 @@ randaut --help | sed -n '/ sequences:/,/^$/p' | sed '1d;$d'
%a number of acceptance sets %a number of acceptance sets
%c, %[LETTERS]c number of SCCs; you may filter the SCCs to count %c, %[LETTERS]c number of SCCs; you may filter the SCCs to count
using the following LETTERS, possibly using the following LETTERS, possibly
concatenated: (a) accepting, (r) rejecting, (v) concatenated: (a) accepting, (r) rejecting, (c)
trivial, (t) terminal, (w) weak, (iw) inherently complete, (v) trivial, (t) terminal, (w) weak,
weak. Use uppercase letters to negate them. (iw) inherently weak. Use uppercase letters to
negate them.
%d 1 if the output is deterministic, 0 otherwise %d 1 if the output is deterministic, 0 otherwise
%e number of edges %e number of reachable edges
%F seed number %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 %h the automaton in HOA format on a single line (use
%[opt]h to specify additional options as in %[opt]h to specify additional options as in
--hoa=opt) --hoa=opt)
@ -992,9 +950,22 @@ randaut --help | sed -n '/ sequences:/,/^$/p' | sed '1d;$d'
LETTERS to restrict to(u) user time, (s) system LETTERS to restrict to(u) user time, (s) system
time, (p) parent process, or (c) children time, (p) parent process, or (c) children
processes. processes.
%s number of states %s number of reachable states
%t number of transitions %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 %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 #+end_example
In most tools =%F= and =%L= are the input filename and line number, 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 density 0.2, and just count the number of edges in each automaton. Then
use =R= to summarize the distribution of these values: 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 randaut -e0.2 -Q100 -n1000 a --stats %e > size.csv
Rscript -e "summary(read.csv('size.csv', header=FALSE, col.names='edges'))" Rscript -e "summary(read.csv('size.csv', header=FALSE, col.names='edges'))"
#+END_SRC #+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 Two of the statistics are related to time: =%r= displays wall-clock
time, while =%R= displays CPU-time. 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' genltl --or-gf=1..8 | ltl2tgba --high --stats='%f,%r,%R'
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
: GFp1,0.000502296,0 : GFp1,0.00100355,0
: GF(p1 | p2),0.000796475,0 : GF(p1 | p2),0.00137515,0
: GF(p1 | p2 | p3),0.00215579,0 : GF(p1 | p2 | p3),0.00331282,0.01
: GF(p1 | p2 | p3 | p4),0.00441474,0 : GF(p1 | p2 | p3 | p4),0.00526782,0
: GF(p1 | p2 | p3 | p4 | p5),0.00980961,0.01 : GF(p1 | p2 | p3 | p4 | p5),0.00895499,0.01
: GF(p1 | p2 | p3 | p4 | p5 | p6),0.0255462,0.03 : GF(p1 | p2 | p3 | p4 | p5 | p6),0.0223277,0.02
: GF(p1 | p2 | p3 | p4 | p5 | p6 | p7),0.121033,0.12 : GF(p1 | p2 | p3 | p4 | p5 | p6 | p7),0.0936452,0.09
: GF(p1 | p2 | p3 | p4 | p5 | p6 | p7 | p8),0.624101,0.62 : GF(p1 | p2 | p3 | p4 | p5 | p6 | p7 | p8),0.480063,0.48
Note that =%r= is implemented using the most precise clock available Note that =%r= is implemented using the most precise clock available
and usually has nano-second precision, while =%R= uses the =times()= 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=, each option the overall wall-clock time, CPU-time spent in =ltldo=,
and CPU-time spent in =ltl2tgba=: and CPU-time spent in =ltl2tgba=:
#+BEGIN_SRC sh :results verbatim :exports both #+BEGIN_SRC sh
genltl --or-gf=1..8 | genltl --or-gf=1..8 |
ltldo '{high}ltl2tgba' '{low}ltl2tgba --low' --stats='%T,%f,%r,%[p]R,%[c]R' ltldo '{high}ltl2tgba' '{low}ltl2tgba --low' --stats='%T,%f,%r,%[p]R,%[c]R'
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
#+begin_example #+begin_example
high,GFp1,0.0495443,0,0.02 high,GFp1,0.0409265,0,0.05
low,GFp1,0.0427718,0,0.03 low,GFp1,0.0199356,0,0.02
high,GFp1 | GFp2,0.0449237,0,0.03 high,GFp1 | GFp2,0.0145994,0,0.02
low,GFp1 | GFp2,0.0429886,0,0.03 low,GFp1 | GFp2,0.0143211,0,0.01
high,GFp1 | GFp2 | GFp3,0.0477704,0.01,0.03 high,GFp1 | GFp2 | GFp3,0.0155654,0,0.03
low,GFp1 | GFp2 | GFp3,0.0294271,0,0.01 low,GFp1 | GFp2 | GFp3,0.014428,0,0.01
high,GFp1 | GFp2 | GFp3 | GFp4,0.0250874,0,0.02 high,GFp1 | GFp2 | GFp3 | GFp4,0.0173471,0,0.02
low,GFp1 | GFp2 | GFp3 | GFp4,0.0203729,0,0.01 low,GFp1 | GFp2 | GFp3 | GFp4,0.0143645,0,0.02
high,GFp1 | GFp2 | GFp3 | GFp4 | GFp5,0.0318887,0,0.03 high,GFp1 | GFp2 | GFp3 | GFp4 | GFp5,0.0214066,0,0.03
low,GFp1 | GFp2 | GFp3 | GFp4 | GFp5,0.0207457,0,0.01 low,GFp1 | GFp2 | GFp3 | GFp4 | GFp5,0.0147305,0,0
high,GFp1 | GFp2 | GFp3 | GFp4 | GFp5 | GFp6,0.0612968,0,0.05 high,GFp1 | GFp2 | GFp3 | GFp4 | GFp5 | GFp6,0.0386194,0,0.05
low,GFp1 | GFp2 | GFp3 | GFp4 | GFp5 | GFp6,0.0145482,0,0.01 low,GFp1 | GFp2 | GFp3 | GFp4 | GFp5 | GFp6,0.0140456,0,0.02
high,GFp1 | GFp2 | GFp3 | GFp4 | GFp5 | GFp6 | GFp7,0.130631,0,0.12 high,GFp1 | GFp2 | GFp3 | GFp4 | GFp5 | GFp6 | GFp7,0.108726,0,0.1
low,GFp1 | GFp2 | GFp3 | GFp4 | GFp5 | GFp6 | GFp7,0.0151502,0,0.01 low,GFp1 | GFp2 | GFp3 | GFp4 | GFp5 | GFp6 | GFp7,0.0137925,0,0.02
high,GFp1 | GFp2 | GFp3 | GFp4 | GFp5 | GFp6 | GFp7 | GFp8,0.595865,0,0.59 high,GFp1 | GFp2 | GFp3 | GFp4 | GFp5 | GFp6 | GFp7 | GFp8,0.49704,0,0.5
low,GFp1 | GFp2 | GFp3 | GFp4 | GFp5 | GFp6 | GFp7 | GFp8,0.0160234,0,0.01 low,GFp1 | GFp2 | GFp3 | GFp4 | GFp5 | GFp6 | GFp7 | GFp8,0.0218286,0,0.03
#+end_example #+end_example
* Naming automata * Naming automata
@ -1106,17 +1076,18 @@ tools have no default name. This name can be changed using the
=--stats=. =--stats=.
#+NAME: oaut-name #+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' ltl2tgba --name='TGBA for %f' --dot=n 'a U b'
#+END_SRC #+END_SRC
#+RESULTS: oaut-name #+RESULTS: oaut-name
#+begin_example #+begin_example
digraph G { digraph "TGBA for a U b" {
rankdir=LR rankdir=LR
label="TGBA for a U b" label="TGBA for a U b\n[Büchi]"
labelloc="t" 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 [label="", style=invis, width=0]
I -> 1 I -> 1
0 [label="0", peripheries=2] 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 states, and finally restricting the output to the first 5 matches
using =autfilt -n5=. using =autfilt -n5=.
#+BEGIN_SRC sh :results verbatim :exports both #+BEGIN_SRC sh
randltl -n -1 a b | randltl -n -1 a b |
ltl2tgba | ltl2tgba |
autfilt --states=3 --stats='!(%M)' | autfilt --states=3 --stats='!(%M)' |
@ -1172,7 +1143,7 @@ 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 read the standard input as if it was a CSV file, and to process its
second column): second column):
#+BEGIN_SRC sh :results verbatim :exports both #+BEGIN_SRC sh
randltl -n -1 a b | # generate a stream of random LTL formulas randltl -n -1 a b | # generate a stream of random LTL formulas
ltl2tgba -F- --stats='%s,!(%f)' | # for each formula output "states,negated formula" ltl2tgba -F- --stats='%s,!(%f)' | # for each formula output "states,negated formula"
grep '^3,' | # keep only formulas with 3 states grep '^3,' | # keep only formulas with 3 states
@ -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. superfluous as the tool default to reading from its standard input.
But we put it there for symmetry with the second call. 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 * Naming output
By default, all output is sent to standard output, so you can either 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 automaton is deterministic. We can generate 20 random automata, and
output them in two files depending on their determinism: 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 randaut -n 20 -Q2 -e1 1 -o out-det%d.hoa
autfilt -c out-det0.hoa # Count of non-deterministic automata autfilt -c out-det0.hoa # Count of non-deterministic automata
autfilt -c out-det1.hoa # Count of 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 forcing [[file:randaut.org][=randaut=]] to output 20 *deterministic* automata, it may look
like we produced more than 20 automata: 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 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-det0.hoa # Count of non-deterministic automata
autfilt -c out-det1.hoa # Count of 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 In the case where you want to append to a file instead of overwriting
it, prefix the output filename with =>>= as in 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 =>>=.) (You need the quotes so that the shell does not interpret =>>=.)
#+BEGIN_SRC sh :results silent :exports results #+BEGIN_SRC sh :results silent :exports results
rm -f out-det0.hoa out-det1.hoa rm -f out-det0.hoa out-det1.hoa
#+END_SRC #+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. #+DESCRIPTION: Spot command-line tool for generating random ω-automata.
#+INCLUDE: setup.org #+INCLUDE: setup.org
#+HTML_LINK_UP: tools.html #+HTML_LINK_UP: tools.html
#+PROPERTY: header-args:sh :results verbatim :exports code
The =randaut= tool generates random (connected) automata. The =randaut= tool generates random (connected) automata.
@ -11,64 +12,9 @@ acceptance sets, and using a set of atomic propositions you have to
supply. supply.
#+NAME: randaut1 #+NAME: randaut1
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh
randaut a b --dot randaut a b --dot
#+END_SRC #+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 #+BEGIN_SRC dot :file randaut1.svg :var txt=randaut1 :exports results
$txt $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. =-e1= will cause all states to be interconnected.
#+NAME: randaut2 #+NAME: randaut2
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh
randaut -Q3 -e0 2 --dot randaut -Q3 -e0 2 --dot
#+END_SRC #+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 #+BEGIN_SRC dot :file randaut2.svg :var txt=randaut2 :exports results
$txt $txt
#+END_SRC #+END_SRC
@ -126,36 +52,10 @@ $txt
[[file:randaut2.svg]] [[file:randaut2.svg]]
#+NAME: randaut3 #+NAME: randaut3
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh
randaut -Q3 -e1 2 --dot randaut -Q3 -e1 2 --dot
#+END_SRC #+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 #+BEGIN_SRC dot :file randaut3.svg :var txt=randaut3 :exports results
$txt $txt
#+END_SRC #+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, - =-A ACCEPTANCE= (or =--acceptance=ACCEPTANCE=) controls both the acceptance condition,
and the number of associated acceptance sets. The =ACCEPTANCE= argument is documented and the number of associated acceptance sets. The =ACCEPTANCE= argument is documented
in =--help= as follows: in =--help= as follows:
#+BEGIN_SRC sh :results verbatim :exports results #+BEGIN_SRC sh :exports results
randaut --help | sed -n '/^ \(ACCEPTANCE\|RANGE\)/,/^$/p' randaut --help | sed -n '/^ \(ACCEPTANCE\|RANGE\)/,/^$/p'
#+END_SRC #+END_SRC
@ -221,34 +121,10 @@ ans =-s= (or =--spin=) implies =-B=.
#+NAME: randaut4 #+NAME: randaut4
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh
randaut -Q3 -e0.5 -A3 -a0.5 2 --dot randaut -Q3 -e0.5 -A3 -a0.5 2 --dot
#+END_SRC #+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 #+BEGIN_SRC dot :file randaut4.svg :var txt=randaut4 :exports results
$txt $txt
#+END_SRC #+END_SRC
@ -257,7 +133,7 @@ $txt
#+NAME: randaut5 #+NAME: randaut5
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh
randaut -Q3 -e0.4 -B -a0.7 2 --dot randaut -Q3 -e0.4 -B -a0.7 2 --dot
#+END_SRC #+END_SRC
@ -292,46 +168,10 @@ $txt
[[file:randaut5.svg]] [[file:randaut5.svg]]
#+NAME: randaut5b #+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 randaut -Q6 -e0.4 -S -a.2 -A 'Streett 1..3' 2 --dot
#+END_SRC #+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 #+BEGIN_SRC dot :file randaut5b.svg :var txt=randaut5b :exports results
$txt $txt
#+END_SRC #+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. give =randaut= some freedom, as in this example.
#+NAME: randaut5c #+NAME: randaut5c
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh
randaut -Q10 -S --colored -A 'parity rand rand 3..4' 2 --dot randaut -Q10 -S --colored -A 'parity rand rand 3..4' 2 --dot
#+END_SRC #+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 #+BEGIN_SRC dot :file randaut5c.svg :var txt=randaut5c :exports results
$txt $txt
#+END_SRC #+END_SRC
@ -421,34 +210,10 @@ sum of all these formulas is $\top$. The resulting automaton is
therefore deterministic and complete. therefore deterministic and complete.
#+NAME: randaut6 #+NAME: randaut6
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh
randaut -D -Q3 -e0.6 -A2 -a0.5 2 --dot randaut -D -Q3 -e0.6 -A2 -a0.5 2 --dot
#+END_SRC #+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 #+BEGIN_SRC dot :file randaut6.svg :var txt=randaut6 :exports results
$txt $txt
#+END_SRC #+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 according to the acceptance condition. The format =%g= represent the
formula for the acceptance condition and would not make a nice formula for the acceptance condition and would not make a nice
filename, but =%[s]g= is a short name for that acceptance condition 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 #+BEGIN_SRC sh :exports both
randaut -n20 -Q10 -A 'random 3' 2 -o 'randaut-%[s]g.hoa' randaut -n20 -Q10 -A 'random 3' 2 -Hl -o 'randaut-%[s]g.hoa'
wc -l randaut-*.hoa wc -l randaut-*.hoa
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
: 222 randaut-Rabin-like.hoa : 1 randaut-Fin-less.hoa
: 380 randaut-Streett-like.hoa : 4 randaut-Rabin-like.hoa
: 100 randaut-generalized-Buchi.hoa : 7 randaut-Streett-like.hoa
: 249 randaut-other.hoa : 2 randaut-generalized-Buchi.hoa
: 951 total : 1 randaut-generalized-Rabin.hoa
: 1 randaut-generalized-Streett.hoa
: 4 randaut-other.hoa
: 20 total
#+BEGIN_SRC sh :results silent :exports results #+BEGIN_SRC sh :results silent :exports results
rm -f rautaut-*.hoa rm -f rautaut-*.hoa
@ -515,7 +285,7 @@ options discussed [[file:oaut.org::#default-dot][on another page]], while '=s='
displayed.) displayed.)
#+NAME: randaut7 #+NAME: randaut7
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh
randaut -n -1 --colored -A'parity min odd 4' a b | randaut -n -1 --colored -A'parity min odd 4' a b |
autfilt --sccs=5 --trivial-sccs=1 --rejecting-sccs=1 \ autfilt --sccs=5 --trivial-sccs=1 --rejecting-sccs=1 \
--inherently-weak-sccs=2 --weak-sccs=1 -n 1 --dot=.s --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. #+DESCRIPTION: Spot command-line tool for generating random LTL formulas.
#+INCLUDE: setup.org #+INCLUDE: setup.org
#+HTML_LINK_UP: tools.html #+HTML_LINK_UP: tools.html
#+PROPERTY: header-args:sh :results verbatim :exports both
This tool generates random formulas. By default, it will generate one This tool generates random formulas. By default, it will generate one
random LTL formula using atomic propositions supplied on the 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 For instance to obtain fave random LTL formula over the propositions
=a=, =b=, or =c=, use: =a=, =b=, or =c=, use:
#+BEGIN_SRC sh :results verbatim :exports both #+BEGIN_SRC sh
randltl -n5 a b c randltl -n5 a b c
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
: 1 : 0
: !(!((a U Gb) U b) U GFa) : 0 R b
: GF((b R !a) U (Xc M 1)) : F(XG(F!b M Fb) W (b R a))
: (b <-> Xc) xor Fb : F(a R !c)
: FXb R (a R (1 U b)) : G(a | Fb) W (FGb R !b)
Note that the result does not always use all atomic propositions. Note that the result does not always use all atomic propositions.
If you do not care about how the atomic propositions are named, If you do not care about how the atomic propositions are named,
you can give a nonnegative number instead: you can give a nonnegative number instead:
#+BEGIN_SRC sh :results verbatim :exports both #+BEGIN_SRC sh
randltl -n5 3 randltl -n5 3
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
: 1 : 0
: !(!((p0 U Gp1) U p1) U GFp0) : 0 R p1
: GF((p1 R !p0) U (Xp2 M 1)) : F(XG(F!p1 M Fp1) W (p1 R p0))
: (p1 <-> Xp2) xor Fp1 : F(p0 R !p2)
: FXp1 R (p0 R (1 U p1)) : G(p0 | Fp1) W (FGp1 R !p1)
The syntax of the formula output can be changed using the The syntax of the formula output can be changed using the
[[file:ioltl.org][common output options]]: [[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' randltl --help | sed -n '/Output options:/,/^$/p' | sed '1d;$d'
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
: -8, --utf8 output using UTF-8 characters #+begin_example
: -l, --lbt output in LBT's syntax -0, --zero-terminated-output separate output formulas with \0 instead of \n
: -p, --full-parentheses output fully-parenthesized formulas (for use with xargs -0)
: -s, --spin output in Spin's syntax -8, --utf8 output using UTF-8 characters
: --spot output in Spot's syntax (default) --format=FORMAT, --stats=FORMAT
: --wring output in Wring's syntax 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 When you select Spin's or Wring's syntax, operators =W= and =M= are
automatically rewritten using =U= and =R= (written =V= for Spin). 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 like =p0=, =p1=, etc... (Atomic proposition named differently will be
output by Spot in double-quotes, but this is not supported by LBT.) 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 -l 12
randltl -8 12 randltl -8 12
randltl -s 12 randltl -s 12
@ -65,10 +77,10 @@ randltl --wring 12
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
: V ! X ^ G p4 M p10 F ! p11 V G p3 p5 : V f W V G p5 p7 p10
: ¬○(□p4⊕(p10 M ◇¬p11)) R (□p3 R p5) : 0 R ((□p5 R p7) W p10)
: !X(([]p4 && !(<>!p11 U (p10 && <>!p11))) || (![]p4 && (<>!p11 U (p10 && <>!p11)))) V ([]p3 V p5) : false V (p10 V (p10 || ([]p5 V p7)))
: (!(X((G(p4=1)) ^ ((F(p11=0)) U ((p10=1) * (F(p11=0))))))) R ((G(p3=1)) R (p5=1)) : (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 As you might guess from the above result, for a given set of atomic
propositions (and on the same computer) the generated formula will 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: three commands:
#+NAME: result-seed #+NAME: result-seed
#+BEGIN_SRC sh :results verbatim :exports both #+BEGIN_SRC sh
randltl a b c randltl a b c d
randltl --seed=123 a b c randltl --seed=4 a b c d
randltl --seed=0 a b c randltl --seed=0 a b c d
#+END_SRC #+END_SRC
Will give three formulas in which the first and last are identical: Will give three formulas in which the first and last are identical:
#+RESULTS: result-seed #+RESULTS: result-seed
: 1 : Xb R ((Gb R c) W d)
: b W 0 : Gd
: 1 : Xb R ((Gb R c) W d)
When generating random formulas, we usually want large quantity of When generating random formulas, we usually want large quantity of
them. Rather than running =randltl= several times with different 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= 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 option. For instance in the following, for each formula the tree size
will be chosen randomly in the range =22..30=. 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 randltl -n 5 a b c --tree-size=22..30
#+END_SRC #+END_SRC
#+RESULTS: #+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 : 0
: !((c xor Gb) -> !Fb) xor !(Gc M 1)
: 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 The tree size is just the number of nodes in the syntax tree of the
formula during its construction. However because Spot automatically 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 implements many rewritings that helps Spot translators algorithms (so
beware that using =-r= reduces the randomness of the output). 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 randltl -n 5 a b c --tree-size=22..30 -r
#+END_SRC #+END_SRC
#+RESULTS: #+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 : 0
: ((G!b | (!c & F!b) | (c & Gb)) & GF!c) | (Fb & ((!c & Gb) | (c & F!b)) & FGc) : 1
: (b R c) | (!a & ((!c & F(a & !b)) M (!c W !b)))
: XGa
The generator build the syntax tree recursively from its root, by The generator build the syntax tree recursively from its root, by
considering all operators that could be used for a given tree size (for 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 considered operators. The default priorities for each operator can
be seen with =--dump-priorities=: be seen with =--dump-priorities=:
#+BEGIN_SRC sh :results verbatim :exports both #+BEGIN_SRC sh
randltl a b c --dump-priorities randltl a b c --dump-priorities
#+END_SRC #+END_SRC
#+RESULTS: #+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 following example disables 6 operators, and augments the priority of
=U= to 3 to favor its occurrence. =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' randltl -n 5 a b c --ltl-priorities 'xor=0,implies=0,equiv=0,W=0,M=0,X=0,U=3'
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
: 1
: 1 U b
: 0 : 0
: F!((b U !a) U Gc) : b
: !b U G(b R c) : 1
: !F(1 U ((a U c) U b))
: 1 U G!b
When using =-r= to simplify generated formulas, beware that these When using =-r= to simplify generated formulas, beware that these
rewritings may use operators that you disabled during the initial 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 the random formula. The =--tree-size= option has no influence on the
weak-fairness formula appended. weak-fairness formula appended.
#+BEGIN_SRC sh :results verbatim :exports both #+BEGIN_SRC sh
randltl -n 5 a b c --weak-fairness randltl -n 5 a b c --weak-fairness
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
: GFb : 0
: ((b | XXa) M Ga) & GFa & GFc : (!Fb | F!Fc) & GFa & GFb & GFc
: GFb & GFc & !(!((a U Gb) U b) U GFa) : GFa & GFb & GFc & F(a xor b)
: GFb & GFa & GFc & F(!X!b U (!c M 1)) : (a | b) & GFa & GFb & GFc & (Ga -> Gc)
: GFb & GFa & GFc & Xc : GFa & GFb & GFc & (GXb U (Fc U (Fc | (a R b))))
Boolean formulas may be output with the =-B= option: 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 randltl -B -n 5 a b c
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
: !b : !(b -> !c)
: b & !b : c xor (b | c)
: b : !(a & (a xor b))
: !c xor (!a xor b) : 0
: !a -> (!c <-> (b xor !(a xor !b))) : !b -> c
In that case, priorities should be set with =--boolean-priorities=. 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 PSL operator (this is even more so the case when simplifications are
enabled with =-r=). enabled with =-r=).
#+BEGIN_SRC sh :results verbatim :exports both #+BEGIN_SRC sh
randltl -P -n 5 a b c randltl -P -n 5 a b c
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
: 1
: a R c
: F({[*0] | {{[*0] | a[*]}}[*]}[]-> 0)
: (a | ((a U c) M a)) M 1
: 0 : 0
: b
: !(a W b)
: 1
: (a U !b) <-> (!a -> Gb)
As shown with the =--dump-priorities= output below, tweaking the As shown with the =--dump-priorities= output below, tweaking the
priorities used to generated PSL formulas requires three different priorities used to generated PSL formulas requires three different
options: options:
#+BEGIN_SRC sh :results verbatim :exports both #+BEGIN_SRC sh
randltl -P a b c --dump-priorities randltl -P a b c --dump-priorities
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
@ -295,6 +307,8 @@ eword 1
boolform 1 boolform 1
star 1 star 1
star_b 1 star_b 1
fstar 1
fstar_b 1
and 1 and 1
andNLM 1 andNLM 1
or 1 or 1

View file

@ -3,6 +3,7 @@
#+DESCRIPTION: Spot command-line tools for minimizing ω-automata #+DESCRIPTION: Spot command-line tools for minimizing ω-automata
#+INCLUDE: setup.org #+INCLUDE: setup.org
#+HTML_LINK_UP: tools.html #+HTML_LINK_UP: tools.html
#+PROPERTY: header-args:sh :results verbatim :exports both
#+NAME: version #+NAME: version
#+BEGIN_SRC sh :exports none #+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 * 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 is built into the Spot library, so that no temporary files are used to
store the problem. 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 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 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 of the builtin version of PicoSAT, define
#+BEGIN_SRC sh #+BEGIN_SRC sh :exports code
export SPOT_SATSOLVER='glucose -verb=0 -model %I >%O' export SPOT_SATSOLVER='glucose -verb=0 -model %I >%O'
#+END_SRC #+END_SRC
We assume the SAT solver follows the input/output conventions of the 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, However =-D= is not a guarantee to obtain a deterministic automaton,
even if one exists. For instance, =-D= fails to produce a 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. non-deterministic automaton.
#+BEGIN_SRC sh :results verbatim :exports both #+BEGIN_SRC sh
ltl2tgba -D 'GF(a <-> XXb)' --stats='states=%s, det=%d' ltl2tgba -D 'a U X(b | GF!b)' --stats='states=%s, det=%d'
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
: states=9, det=0 : states=4, det=0
Option =-x tba-det= enables an additional Option =-x tba-det= enables an additional
determinization procedure, that would otherwise not be used by =-D= 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 On our example, =-x tba-det= successfully produces a deterministic
TBA, but a non-minimal one: TBA, but a non-minimal one:
#+BEGIN_SRC sh :results verbatim :exports both #+BEGIN_SRC sh
ltl2tgba -D -x tba-det 'GF(a <-> XXb)' --stats='states=%s, det=%d' ltl2tgba -D -x tba-det 'a U X(b | GF!b)' --stats='states=%s, det=%d'
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
: states=7, det=1 : states=9, det=1
Option =-x sat-minimize= will turn-on SAT-based minimization. It also 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. implies =-x tba-det=, so there is no need to supply both options.
#+BEGIN_SRC sh :results verbatim :exports both #+BEGIN_SRC sh
ltl2tgba -D -x sat-minimize 'GF(a <-> XXb)' --stats='states=%s, det=%d' ltl2tgba -D -x sat-minimize 'a U X(b | GF!b)' --stats='states=%s, det=%d'
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
: states=4, det=1 : states=5, det=1
We can draw it: We can draw it:
#+NAME: gfaexxb3 #+NAME: gfaexxb3
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh :exports code
ltl2tgba -D -x sat-minimize 'GF(a <-> XXb)' -d ltl2tgba -D -x sat-minimize 'a U X(b | GF!b)' -d
#+END_SRC #+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 #+BEGIN_SRC dot :file gfaexxb3.svg :var txt=gfaexxb3 :exports results
$txt $txt
@ -166,46 +134,8 @@ result will of course be slightly bigger.
#+NAME: gfaexxb4 #+NAME: gfaexxb4
#+BEGIN_SRC sh :results verbatim :exports code #+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 #+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 #+BEGIN_SRC dot :file gfaexxb4.svg :var txt=gfaexxb4 :exports results
$txt $txt
@ -214,10 +144,11 @@ $txt
[[file:gfaexxb4.svg]] [[file:gfaexxb4.svg]]
There are cases where =ltl2tgba='s =tba-det= algorithm fails to produce a deterministic automaton. There are cases where =ltl2tgba='s =tba-det= algorithm fails to
In that case, SAT-based minimization is simply skipped. For instance: 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' ltl2tgba -D -x sat-minimize 'G(F(!b & (X!a M (F!a & F!b))) U !b)' --stats='states=%s, det=%d'
#+END_SRC #+END_SRC
#+RESULTS: #+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 without being syntactic recurrences.) [[file:ltlfilt.org][=ltlfilt=]] can be instructed to
print only formulas that are syntactic recurrences: 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)' ltlfilt --syntactic-recurrence -f 'G(F(!b & (X!a M (F!a & F!b))) U !b)'
#+END_SRC #+END_SRC
#+RESULTS: #+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 output is guaranteed to be deterministic if and only if the input DRA
expresses a recurrence property. 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 | ltlfilt --remove-wm -f 'G(F(!b & (X!a M (F!a & F!b))) U !b)' -l |
ltl2dstar --ltl2nba=spin:ltl2tgba@-Ds - - | ltl2dstar --ltl2nba=spin:ltl2tgba@-Ds - - |
dstar2tgba -D --stats='input(states=%S) output(states=%s, acc-sets=%a, det=%d)' 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 options as =ltl2tgba=. For instance we can see that the smallest DTBA
has call_size(arg="%s -x sat-minimize")[:results raw] states: 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 | ltlfilt --remove-wm -f 'G(F(!b & (X!a M (F!a & F!b))) U !b)' -l |
ltl2dstar --ltl2nba=spin:ltl2tgba@-Ds - - | ltl2dstar --ltl2nba=spin:ltl2tgba@-Ds - - |
dstar2tgba -D -x sat-minimize --stats='input(states=%S) output(states=%s, acc-sets=%a, det=%d)' 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 * More acceptance sets
The formula "=G(F(!b & (X!a M (F!a & F!b))) U !b)=" can in fact be minimized into an The formula "=G(F(!b & (X!a M (F!a & F!b))) U !b)=" can in fact be
even smaller automaton if we use multiple acceptance sets. minimized into an even smaller automaton if we use multiple acceptance
sets.
Unfortunately because =dstar2tgba= does not know the formula being Unfortunately because =dstar2tgba= does not know the formula being
translated, and it always convert a DRA into a DBA (with a single 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 number of acceptance sets can however be specified on the command-line
with option =-x sat-acc=M=. For instance: 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 | ltlfilt --remove-wm -f 'G(F(!b & (X!a M (F!a & F!b))) U !b)' -l |
ltl2dstar --ltl2nba=spin:ltl2tgba@-Ds - - | 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)' 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 For our example, let us first generate a deterministic Rabin
automaton with [[http://www.ltl2dstar.de/][=ltl2dstar=]]. automaton with [[http://www.ltl2dstar.de/][=ltl2dstar=]].
#+BEGIN_SRC sh :results silent :exports both #+BEGIN_SRC sh :results silent
ltlfilt -f 'FGa | FGb' -l | ltlfilt -f 'FGa | FGb' -l |
ltl2dstar --ltl2nba=spin:ltl2tgba@-Ds --output-format=hoa - - > output.hoa ltl2dstar --ltl2nba=spin:ltl2tgba@-Ds --output-format=hoa - - > output.hoa
#+END_SRC #+END_SRC
Let's draw it: Let's draw it:
#+NAME: autfiltsm1 #+NAME: autfiltsm1
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh :exports code
autfilt output.hoa --dot autfilt output.hoa --dot
#+END_SRC #+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 #+BEGIN_SRC dot :file autfiltsm1.svg :var txt=autfiltsm1 :exports results
$txt $txt
@ -466,7 +363,7 @@ transition-based version (the output may change depending on the SAT
solver used): solver used):
#+NAME: autfiltsm2 #+NAME: autfiltsm2
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh :exports code
autfilt --sat-minimize output.hoa --dot autfilt --sat-minimize output.hoa --dot
#+END_SRC #+END_SRC
@ -479,7 +376,7 @@ $txt
We can also attempt to build a state-based version with We can also attempt to build a state-based version with
#+NAME: autfiltsm3 #+NAME: autfiltsm3
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh :exports code
autfilt -S --sat-minimize output.hoa --dot autfilt -S --sat-minimize output.hoa --dot
#+END_SRC #+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: Let's try with generalized co-Büchi for instance:
#+NAME: autfiltsm4 #+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 autfilt -S --sat-minimize='acc="generalized-co-Buchi 2"' output.hoa --dot
#+END_SRC #+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 #+BEGIN_SRC dot :file autfiltsm4.svg :var txt=autfiltsm4 :exports results
$txt $txt
#+END_SRC #+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 attempt to create a co-Büchi automaton with
#+NAME: autfiltsm5 #+NAME: autfiltsm5
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh :exports code
autfilt -S --sat-minimize='acc="Fin(0)"' output.hoa --dot autfilt -S --sat-minimize='acc="Fin(0)"' output.hoa --dot
#+END_SRC #+END_SRC
#+RESULTS: autfiltsm5 #+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: smaller than the output. Let's take this small TGBA as input:
#+NAME: autfiltsm6 #+NAME: autfiltsm6
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh :exports code
ltl2tgba 'GFa & GFb' >output2.hoa ltl2tgba 'GFa & GFb' >output2.hoa
autfilt output2.hoa --dot autfilt output2.hoa --dot
#+END_SRC #+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 #+BEGIN_SRC dot :file autfiltsm6.svg :var txt=autfiltsm6 :exports results
$txt $txt
#+END_SRC #+END_SRC
@ -607,10 +461,10 @@ $txt
If we attempt to minimize it into a transition-based Büchi automaton, 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 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 #+NAME: autfiltsm7
#+BEGIN_SRC sh :results verbatim :exports both #+BEGIN_SRC sh
autfilt --sat-minimize='acc="Buchi"' output2.hoa autfilt --sat-minimize='acc="Buchi"' output2.hoa
echo $? echo $?
#+END_SRC #+END_SRC
@ -620,7 +474,7 @@ echo $?
However if we allow more states, it will work: However if we allow more states, it will work:
#+NAME: autfiltsm8 #+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 autfilt --sat-minimize='acc="Buchi",max-states=3' output2.hoa --dot
#+END_SRC #+END_SRC
@ -692,7 +546,7 @@ Compare the following, where parity acceptance is used, but the
automaton is not colored: automaton is not colored:
#+NAME: autfiltsm9 #+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 autfilt -S --sat-minimize='acc="parity max even 3"' output2.hoa --dot
#+END_SRC #+END_SRC
@ -707,7 +561,7 @@ $txt
belong to exactly one acceptance set: belong to exactly one acceptance set:
#+NAME: autfiltsm10 #+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 autfilt -S --sat-minimize='acc="parity max even 3",colored' output2.hoa --dot
#+END_SRC #+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 file, the minimization function will append statistics about each of
its iterations in this file. its iterations in this file.
#+BEGIN_SRC sh :results verbatim :exports both #+BEGIN_SRC sh
rm -f stats.csv rm -f stats.csv
export SPOT_SATLOG=stats.csv export SPOT_SATLOG=stats.csv
ltlfilt -f 'Ga R (F!b & (c U b))' -l | ltlfilt -f 'Ga R (F!b & (c U b))' -l |
ltl2dstar --ltl2nba=spin:ltl2tgba@-Ds - - | 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)' 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 #+END_SRC
#+RESULTS: #+RESULTS:
: input(states=11) output(states=5, acc-sets=2, det=1) : 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 Here is the contents of the =stats.csv= file:
: 10,5,,,,13600,1543042,59,3,187,0, #+begin_src sh :exports results :results output raw
: 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--" sed '1a\
: 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--" |-|
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: The generated CSV file use the following columns:
- =input.states=: the number of states of the reference automaton at this step - =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 above example, the DRA produced by =ltl2dstar= had 11 states.
In the first line of the =stats.csv= file, you can see the In the first line of the =stats.csv= file, you can see the
minimization function had a 10-state input, which means that minimization function had a 8-state input, which means that
=dstar2tgba= first reduced the 11-state (complete) DRA into a 10-state =dstar2tgba= first reduced the 11-state (complete) DRA into a 8-state
(complete) DBA before calling the SAT-based minimization. This first (complete) DBA before calling the SAT-based minimization (the fact
line shows the SAT-based minimization for a (complete) 5-state DTGBA that the input was reduced to a *DBA* is not very obvious from this
and failing to find one. Then on the next line it looks for a 7-state trace), This first line shows the SAT-based minimization for a
solution, finds one. Finally, it finds a (complete) 6-state solution, (complete) 5-state DTGBA and failing to find one. Then on the next
now using the 7-state version as reference automaton to further line it looks for a 6-state solution, finds one. Finally, it looks
simplify the problem. 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 The final output is reported with 5 states, because by default we
output trim automata. If the =--complete= option had been given, the 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 #+EMAIL: spot@lrde.epita.fr
#+HTML_LINK_HOME: index.html #+HTML_LINK_HOME: index.html
#+MACRO: SPOTVERSION 2.7.2 #+MACRO: SPOTVERSION 2.7.2

View file

@ -3,6 +3,7 @@
#+DESCRIPTION: List of all the command-line tools installed by Spot {{{SPOTVERSION}}} #+DESCRIPTION: List of all the command-line tools installed by Spot {{{SPOTVERSION}}}
#+INCLUDE: setup.org #+INCLUDE: setup.org
#+HTML_LINK_UP: index.html #+HTML_LINK_UP: index.html
#+PROPERTY: header-args:sh :results verbatim :exports both
This document introduces command-line tools that are installed with This document introduces command-line tools that are installed with
the Spot library. We give some examples to highlight possible 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: on the left:
#+NAME: helloworld #+NAME: helloworld
#+BEGIN_SRC sh :results verbatim :exports both #+BEGIN_SRC sh
echo Hello World echo Hello World
#+END_SRC #+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 Additionally, the man pages of these tools also contains additional
references about the algorithms or data sources used. 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: num toc helloworld SRC LTL PSL randltl ltlfilt genltl
# LocalWords: scalable ltl tgba Büchi automata tgta ltlcross eval # LocalWords: scalable ltl tgba Büchi automata tgta ltlcross eval
# LocalWords: setenv concat getenv setq # LocalWords: setenv concat getenv setq

View file

@ -3,6 +3,9 @@
#+DESCRIPTION: Code example for parsing and printing formulas in Spot #+DESCRIPTION: Code example for parsing and printing formulas in Spot
#+INCLUDE: setup.org #+INCLUDE: setup.org
#+HTML_LINK_UP: tut.html #+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. 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.). using different options such as (=--spin=, =--lbt=, =--latex=, etc.).
Full parentheses can also be requested using =-p=. Full parentheses can also be requested using =-p=.
#+BEGIN_SRC sh :results verbatim :exports both #+BEGIN_SRC sh
ltlfilt -f '[]<>p0 || <>[]p1' ltlfilt -f '[]<>p0 || <>[]p1'
formula='& & G p0 p1 p2' formula='& & G p0 p1 p2'
ltlfilt --lbt-input -f "$formula" --latex ltlfilt --lbt-input -f "$formula" --latex
@ -39,7 +42,7 @@ other syntaxes.)
Here are the same operations in Python Here are the same operations in Python
#+BEGIN_SRC python :results output :exports both #+BEGIN_SRC python
import spot import spot
print(spot.formula('[]<>p0 || <>[]p1')) print(spot.formula('[]<>p0 || <>[]p1'))
f = spot.formula('& & G p0 p1 p2') f = spot.formula('& & G p0 p1 p2')
@ -70,7 +73,7 @@ above in the python bindings. Here parse errors would be returned as
exceptions. exceptions.
#+NAME: 1stex #+NAME: 1stex
#+BEGIN_SRC C++ :results verbatim :exports both #+BEGIN_SRC C++
#include <iostream> #include <iostream>
#include <spot/tl/parse.hh> #include <spot/tl/parse.hh>
#include <spot/tl/print.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: Here is how to call the infix parser explicitly:
#+BEGIN_SRC C++ :results verbatim :exports both #+BEGIN_SRC C++
#include <string> #include <string>
#include <iostream> #include <iostream>
#include <spot/tl/parse.hh> #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 is equivalent to =a U b=. You could decide to continue with the
"fixed" formula if you wish. Here is an example: "fixed" formula if you wish. Here is an example:
#+BEGIN_SRC C++ :results verbatim :exports both #+BEGIN_SRC C++
#include <string> #include <string>
#include <iostream> #include <iostream>
#include <spot/tl/parse.hh> #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 The only difference here is the call to =parse_prefix_ltl()= instead
of =parse_infix_psl()=. of =parse_infix_psl()=.
#+BEGIN_SRC C++ :results verbatim :exports both #+BEGIN_SRC C++
#include <string> #include <string>
#include <iostream> #include <iostream>
#include <spot/tl/parse.hh> #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 For instance, let's see what happens if a PSL formulas is passed to
=print_spin_ltl=: =print_spin_ltl=:
#+BEGIN_SRC C++ :results verbatim :exports both #+BEGIN_SRC C++
#include <string> #include <string>
#include <iostream> #include <iostream>
#include <spot/tl/parse.hh> #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. The first is to simply diagnose non-LTL formulas.
#+BEGIN_SRC C++ :results verbatim :exports code #+BEGIN_SRC C++ :exports code
#include <string> #include <string>
#include <iostream> #include <iostream>
#include <spot/tl/parse.hh> #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 prepared to reject the formula anyway. In our example, we are lucky
(maybe because it was carefully chosen...): (maybe because it was carefully chosen...):
#+BEGIN_SRC C++ :results verbatim :exports both #+BEGIN_SRC C++
#include <string> #include <string>
#include <iostream> #include <iostream>
#include <spot/tl/parse.hh> #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 workaround in Spot is to double-quote any arbitrary atomic
proposition: proposition:
#+BEGIN_SRC sh :results verbatim :exports both #+BEGIN_SRC sh
echo compare echo compare
ltlfilt -f '"a > 4" U "b < 5"' ltlfilt -f '"a > 4" U "b < 5"'
echo and 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 parser finds a parenthetical block it does not understand, it simply
assume that this block represents an atomic proposition. 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)' ltlfilt --lenient -f '(a > 4) U (b < 5)'
#+END_SRC #+END_SRC
@ -373,7 +376,7 @@ ltlfilt --lenient -f '(a > 4) U (b < 5)'
Lenient parsing is risky, because any parenthesized sub-formula that Lenient parsing is risky, because any parenthesized sub-formula that
is a syntax-error will be treated as an atomic proposition: 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' ltlfilt --lenient -f '(a U ) U c'
#+END_SRC #+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 to easily change the way a formula should be output when using the
=format()= method of strings. =format()= method of strings.
#+BEGIN_SRC python :results output :exports both #+BEGIN_SRC python
import spot import spot
formula = spot.formula('a U b U "$strange[0]=name"') formula = spot.formula('a U b U "$strange[0]=name"')
print("""\ print("""\
@ -418,7 +421,7 @@ produced from the formula.
The complete list of specifier that apply to formulas can always be The complete list of specifier that apply to formulas can always be
printed with =help(spot.formula.__format__)=: printed with =help(spot.formula.__format__)=:
#+BEGIN_SRC python :results output :exports results #+BEGIN_SRC python :exports results
import spot import spot
help(spot.formula.__format__) help(spot.formula.__format__)
#+END_SRC #+END_SRC

View file

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

View file

@ -3,6 +3,8 @@
#+DESCRIPTION: Code example for constructing and transforming formulas in Spot #+DESCRIPTION: Code example for constructing and transforming formulas in Spot
#+INCLUDE: setup.org #+INCLUDE: setup.org
#+HTML_LINK_UP: tut.html #+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 This page explains how to build formulas and how to iterate over their
syntax trees. syntax trees.
@ -29,7 +31,7 @@ as in =formula::And({arg1, arg2, arg3})=.
Here is the list of supported operators: Here is the list of supported operators:
#+BEGIN_SRC C++ #+BEGIN_SRC C++ :exports code
// atomic proposition // atomic proposition
formula::ap(string) formula::ap(string)
// constants // 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 The second part of the following example shows how to print some
detail of the top-level operator in the formula. detail of the top-level operator in the formula.
#+BEGIN_SRC C++ :results verbatim :exports both #+BEGIN_SRC C++
#include <iostream> #include <iostream>
#include <spot/tl/formula.hh> #include <spot/tl/formula.hh>
#include <spot/tl/print.hh> #include <spot/tl/print.hh>
@ -136,7 +138,7 @@ detail of the top-level operator in the formula.
The Python equivalent is similar: The Python equivalent is similar:
#+BEGIN_SRC python :results output :exports both #+BEGIN_SRC python
import spot import spot
# Build FGa -> (GFb & GFc) # 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. time time by not exploring further.
#+NAME: gcount_cpp #+NAME: gcount_cpp
#+BEGIN_SRC C++ :results verbatim :exports both #+BEGIN_SRC C++
#include <iostream> #include <iostream>
#include <spot/tl/formula.hh> #include <spot/tl/formula.hh>
#include <spot/tl/print.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: in a formula:
#+NAME: xchg_fg_cpp #+NAME: xchg_fg_cpp
#+BEGIN_SRC C++ :results verbatim :exports both #+BEGIN_SRC C++
#include <iostream> #include <iostream>
#include <spot/tl/formula.hh> #include <spot/tl/formula.hh>
#include <spot/tl/print.hh> #include <spot/tl/print.hh>
@ -275,7 +277,7 @@ in a formula:
} }
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS: xchg_fg_cpp
: before: FGa -> (GFb & GF(b & c & d)) : before: FGa -> (GFb & GF(b & c & d))
: after: GFa -> (FGb & FG(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 in the first example]], we could pass a reference to this
variable: variable:
#+BEGIN_SRC C++ :results verbatim :exports both #+BEGIN_SRC C++
#include <iostream> #include <iostream>
#include <spot/tl/formula.hh> #include <spot/tl/formula.hh>
#include <spot/tl/print.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 that counts the number of exchanges performed. First, we do it
without lambda: without lambda:
#+BEGIN_SRC C++ :results verbatim :exports both #+BEGIN_SRC C++
#include <iostream> #include <iostream>
#include <spot/tl/formula.hh> #include <spot/tl/formula.hh>
#include <spot/tl/print.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 large penalty cost. We can work around that by assuming that that
address will be passed as an argument (=self=) to the lambda: address will be passed as an argument (=self=) to the lambda:
#+BEGIN_SRC C++ :results verbatim :exports both #+BEGIN_SRC C++
#include <iostream> #include <iostream>
#include <spot/tl/formula.hh> #include <spot/tl/formula.hh>
#include <spot/tl/print.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 syntax. Python only supports a very limited form of lambda
expressions, so we have to write a standard function instead: expressions, so we have to write a standard function instead:
#+BEGIN_SRC python :results output :exports both #+BEGIN_SRC python
import spot import spot
gcount = 0 gcount = 0
@ -450,7 +452,7 @@ b & c & d
Here is the =F= and =G= exchange: Here is the =F= and =G= exchange:
#+BEGIN_SRC python :results output :exports both #+BEGIN_SRC python
import spot import spot
def xchg_fg(i): def xchg_fg(i):

View file

@ -3,6 +3,9 @@
#+DESCRIPTION: Code example for testing the equivalence of two LTL or PSL formulas #+DESCRIPTION: Code example for testing the equivalence of two LTL or PSL formulas
#+INCLUDE: setup.org #+INCLUDE: setup.org
#+HTML_LINK_UP: tut.html #+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 This page shows how to test whether two LTL/PSL formulas are
equivalent, i.e., if they denote the same languages. 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 LTL formula and retain only those equivalent to =f=. So this gives an easy
way to test the equivalence of two formulas: 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' ltlfilt -f '(a U b) U a' --equivalent-to 'b U a'
#+END_SRC #+END_SRC
#+RESULTS: #+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 a=. You may want to add =-c= to count the number of formula output if
you prefer a 1/0 answer: 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' ltlfilt -c -f '(a U b) U a' --equivalent-to 'b U a'
#+END_SRC #+END_SRC
#+RESULTS: #+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 We could also write this check by doing [[file:tut10.org][the translation]] and emptiness
check ourselves. For instance: check ourselves. For instance:
#+BEGIN_SRC python :results output :exports both #+BEGIN_SRC python
import spot import spot
def implies(f, g): 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: This can also be done via a =language_containment_checker= object:
#+BEGIN_SRC python :results output :exports both #+BEGIN_SRC python
import spot import spot
f = spot.formula("(a U b) U a") f = spot.formula("(a U b) U a")
g = spot.formula("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 or the =language_containment_checker=. Note that the
=are_equivalent()= function also work with automata. =are_equivalent()= function also work with automata.
#+BEGIN_SRC C++ :results verbatim :exports both #+BEGIN_SRC C++
#include <iostream> #include <iostream>
#include <spot/tl/parse.hh> #include <spot/tl/parse.hh>
#include <spot/twaalgos/contains.hh> #include <spot/twaalgos/contains.hh>
@ -113,18 +116,18 @@ int main()
#+RESULTS: #+RESULTS:
: Equivalent : Equivalent
#+BEGIN_SRC C++ :results verbatim :exports both #+BEGIN_SRC C++
#include <iostream> #include <iostream>
#include <spot/tl/parse.hh> #include <spot/tl/parse.hh>
#include <spot/tl/contain.hh> #include <spot/tl/contain.hh>
int main() int main()
{ {
spot::formula f = spot::parse_formula("(a U b) U a"); spot::formula f = spot::parse_formula("(a U b) U a");
spot::formula g = spot::parse_formula("b U a"); spot::formula g = spot::parse_formula("b U a");
spot::language_containment_checker c; spot::language_containment_checker c;
std::cout << (c.equal(f, g) ? "Equivalent\n" : "Not equivalent\n"); std::cout << (c.equal(f, g) ? "Equivalent\n" : "Not equivalent\n");
} }
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:

View file

@ -3,12 +3,15 @@
#+DESCRIPTION: Code example for translating formulas in Spot #+DESCRIPTION: Code example for translating formulas in Spot
#+INCLUDE: setup.org #+INCLUDE: setup.org
#+HTML_LINK_UP: tut.html #+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. Here is how to translate an LTL (or PSL) formula into a never claim.
* Shell * Shell
#+BEGIN_SRC sh :results verbatim :exports both #+BEGIN_SRC sh
ltl2tgba --spin 'GFa -> GFb' ltl2tgba --spin 'GFa -> GFb'
#+END_SRC #+END_SRC
@ -17,23 +20,23 @@ ltl2tgba --spin 'GFa -> GFb'
never { /* F(GFb | G!a) */ never { /* F(GFb | G!a) */
T0_init: T0_init:
if if
:: ((!(a))) -> goto accept_S0 :: (true) -> goto T0_init
:: ((true)) -> goto T0_init :: (b) -> goto accept_S1
:: ((b)) -> goto accept_S2 :: (!(a)) -> goto accept_S2
fi; fi;
accept_S0: accept_S1:
if if
:: ((!(a))) -> goto accept_S0 :: (b) -> goto accept_S1
:: (!(b)) -> goto T0_S3
fi; fi;
accept_S2: accept_S2:
if if
:: ((b)) -> goto accept_S2 :: (!(a)) -> goto accept_S2
:: ((!(b))) -> goto T0_S3
fi; fi;
T0_S3: T0_S3:
if if
:: ((b)) -> goto accept_S2 :: (b) -> goto accept_S1
:: ((!(b))) -> goto T0_S3 :: (!(b)) -> goto T0_S3
fi; fi;
} }
#+end_example #+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: So the translation is actually a one-liner in Python:
#+BEGIN_SRC python :results output :exports both #+BEGIN_SRC python
import spot import spot
print(spot.formula('GFa -> GFb').translate('BA').to_str('spin')) print(spot.formula('GFa -> GFb').translate('BA').to_str('spin'))
#+END_SRC #+END_SRC
@ -57,23 +60,23 @@ print(spot.formula('GFa -> GFb').translate('BA').to_str('spin'))
never { never {
T0_init: T0_init:
if if
:: ((!(a))) -> goto accept_S0 :: (true) -> goto T0_init
:: ((true)) -> goto T0_init :: (b) -> goto accept_S1
:: ((b)) -> goto accept_S2 :: (!(a)) -> goto accept_S2
fi; fi;
accept_S0: accept_S1:
if if
:: ((!(a))) -> goto accept_S0 :: (b) -> goto accept_S1
:: (!(b)) -> goto T0_S3
fi; fi;
accept_S2: accept_S2:
if if
:: ((b)) -> goto accept_S2 :: (!(a)) -> goto accept_S2
:: ((!(b))) -> goto T0_S3
fi; fi;
T0_S3: T0_S3:
if if
:: ((b)) -> goto accept_S2 :: (b) -> goto accept_S1
:: ((!(b))) -> goto T0_S3 :: (!(b)) -> goto T0_S3
fi; 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) =translate()= can also be used as a function (as opposed to a method)
that takes a formula (possibly as a string) as first argument: that takes a formula (possibly as a string) as first argument:
#+BEGIN_SRC python :results output :exports both #+BEGIN_SRC python
import spot import spot
print(spot.translate('GFa -> GFb', 'BA').to_str('spin')) print(spot.translate('GFa -> GFb', 'BA').to_str('spin'))
#+END_SRC #+END_SRC
@ -93,23 +96,23 @@ print(spot.translate('GFa -> GFb', 'BA').to_str('spin'))
never { never {
T0_init: T0_init:
if if
:: ((!(a))) -> goto accept_S0 :: (true) -> goto T0_init
:: ((true)) -> goto T0_init :: (b) -> goto accept_S1
:: ((b)) -> goto accept_S2 :: (!(a)) -> goto accept_S2
fi; fi;
accept_S0: accept_S1:
if if
:: ((!(a))) -> goto accept_S0 :: (b) -> goto accept_S1
:: (!(b)) -> goto T0_S3
fi; fi;
accept_S2: accept_S2:
if if
:: ((b)) -> goto accept_S2 :: (!(a)) -> goto accept_S2
:: ((!(b))) -> goto T0_S3
fi; fi;
T0_S3: T0_S3:
if if
:: ((b)) -> goto accept_S2 :: (b) -> goto accept_S1
:: ((!(b))) -> goto T0_S3 :: (!(b)) -> goto T0_S3
fi; fi;
} }
@ -127,7 +130,7 @@ various preferences (like small or deterministic) or characteristic
(complete, unambiguous) for the resulting automaton. Finally, the (complete, unambiguous) for the resulting automaton. Finally, the
output as a never claim is done via the =print_never_claim= function. 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 <iostream>
#include <spot/tl/parse.hh> #include <spot/tl/parse.hh>
#include <spot/twaalgos/translate.hh> #include <spot/twaalgos/translate.hh>
@ -151,22 +154,22 @@ output as a never claim is done via the =print_never_claim= function.
never { never {
T0_init: T0_init:
if if
:: (p1) -> goto accept_S0
:: (true) -> goto T0_init :: (true) -> goto T0_init
:: (p0) -> goto accept_S2 :: (p0) -> goto accept_S1
:: (p1) -> goto accept_S2
fi; fi;
accept_S0: accept_S1:
if if
:: (p1) -> goto accept_S0 :: (p0) -> goto accept_S1
:: (!(p0)) -> goto T0_S3
fi; fi;
accept_S2: accept_S2:
if if
:: (p0) -> goto accept_S2 :: (p1) -> goto accept_S2
:: (!(p0)) -> goto T0_S3
fi; fi;
T0_S3: T0_S3:
if if
:: (p0) -> goto accept_S2 :: (p0) -> goto accept_S1
:: (!(p0)) -> goto T0_S3 :: (!(p0)) -> goto T0_S3
fi; fi;
} }
@ -176,7 +179,7 @@ T0_S3:
The Python version of =translate()= is documented as follows: The Python version of =translate()= is documented as follows:
#+BEGIN_SRC python :results output :exports both #+BEGIN_SRC python :exports results
import spot import spot
help(spot.translate) help(spot.translate)
#+END_SRC #+END_SRC
@ -185,22 +188,30 @@ help(spot.translate)
#+begin_example #+begin_example
Help on function translate in module spot: 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. Translate a formula into an automaton.
Keep in mind that pref expresses just a preference that may not be Keep in mind that 'Deterministic' expresses just a preference that
satisfied. may not be satisfied.
The optional arguments should be strings among the following: The optional arguments should be strings among the following:
- at most one in 'TGBA', 'BA', or 'Monitor' - at most one in 'TGBA', 'BA', or 'Monitor', 'generic',
(type of automaton to build) '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' - at most one in 'Small', 'Deterministic', 'Any'
(preferred characteristics of the produced automaton) (preferred characteristics of the produced automaton)
- at most one in 'Low', 'Medium', 'High' - at most one in 'Low', 'Medium', 'High'
(optimization level) (optimization level)
- any combination of 'Complete', 'Unambiguous', and - any combination of 'Complete', 'Unambiguous',
'StateBasedAcceptance' (or 'SBAcc' for short) '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 #+end_example

View file

@ -3,6 +3,9 @@
#+DESCRIPTION: Code example for using Spot to translating formulas in monitors #+DESCRIPTION: Code example for using Spot to translating formulas in monitors
#+INCLUDE: setup.org #+INCLUDE: setup.org
#+HTML_LINK_UP: tut.html #+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 monitor is a special type of automaton that is supposed to /monitor/
a running system and move accordingly. A monitor detects an error 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*. immediately after *red*.
#+NAME: tut11a #+NAME: tut11a
#+BEGIN_SRC sh :results verbatim :exports none #+BEGIN_SRC sh :exports none
ltl2tgba -D -M '!F(red & Xyellow)' -d ltl2tgba -D -M '!F(red & Xyellow)' -d
#+END_SRC #+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 To build the above deterministic monitor using [[file:ltl2tgba.org][=ltl2tgba=]], we simply
pass option =-M= (for monitor) and =-D= (for deterministic). 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))' ltl2tgba -D -M '!F(red & X(yellow))'
#+END_SRC #+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 claim]] except that we explicitly require a deterministic monitor and
output in the [[file:hoa.org][HOA format]]. output in the [[file:hoa.org][HOA format]].
#+BEGIN_SRC python :results output :exports both #+BEGIN_SRC python
import spot import spot
print(spot.translate('!F(red & X(yellow))', 'monitor', 'det').to_str('HOA')) print(spot.translate('!F(red & X(yellow))', 'monitor', 'det').to_str('HOA'))
#+END_SRC #+END_SRC
@ -97,7 +100,7 @@ State: 1
The code very similar to [[file:tut10.org][the never claim example]]. 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 <iostream>
#include <spot/tl/parse.hh> #include <spot/tl/parse.hh>
#include <spot/twaalgos/translate.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 monitorable correspond to the class of [[file:hierarchy.org::#safety][safety properties]]. You can
check that an LTL formula is a safety by using: 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))' ltlfilt --count --safety -f '!F(red & X(yellow))'
#+END_SRC #+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 following formula: =G(press -> red U green)=. Unfortunately it is not
a safety property: a safety property:
#+BEGIN_SRC sh :results verbatim :exports code #+BEGIN_SRC sh :epilogue true
ltlfilt --count --safety -f 'G(press -> red U green)' ltlfilt --count --safety -f 'G(press -> red U green)'
#+END_SRC #+END_SRC
#+BEGIN_SRC sh :results verbatim :exports results
ltlfilt --count --safety -f 'G(press -> red U green)'
true
#+END_SRC
#+RESULTS: #+RESULTS:
: 0 : 0
Nonetheless, we can still build a monitor for it: Nonetheless, we can still build a monitor for it:
#+NAME: tut11b #+NAME: tut11b
#+BEGIN_SRC sh :results verbatim :exports none #+BEGIN_SRC sh :exports none
ltl2tgba -D -M 'G(press -> red U green)' -d ltl2tgba -D -M 'G(press -> red U green)' -d
#+END_SRC #+END_SRC
#+BEGIN_SRC dot :file tut11b.svg :var txt=tut11b :exports results #+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 without using =spot::translator=. Unless you plan to customize some
of these steps, we recommend you use =spot::translator= instead. of these steps, we recommend you use =spot::translator= instead.
#+BEGIN_SRC C++ :results verbatim :exports both #+BEGIN_SRC C++
#include <iostream> #include <iostream>
#include <spot/tl/parse.hh> #include <spot/tl/parse.hh>
#include <spot/twaalgos/ltl2tgba_fm.hh> #include <spot/twaalgos/ltl2tgba_fm.hh>

View file

@ -3,20 +3,23 @@
#+DESCRIPTION: Code example for using Spot to translate LTLf formulas #+DESCRIPTION: Code example for using Spot to translate LTLf formulas
#+INCLUDE: setup.org #+INCLUDE: setup.org
#+HTML_LINK_UP: tut.html #+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 LTL operators used by Spot are defined over infinite words, and
the various type of automata supported are all \omega-automata, i.e., the various type of automata supported are all \omega-automata, i.e.,
automata over infinite words. 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 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 build a finite automaton that recognize some LTLf (i.e. LTL with
finite semantics) property. The plan is as follows: 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. 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 2. Rewrite this formula in a way that embeds the semantics of LTLf in
LTL. First, introduce a new atomic proposition =alive= that will 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"). call_from_ltlf(f="(a U b) & Fc").
3. Convert the resulting formula into a Büchi automaton: 3. Convert the resulting formula into a Büchi automaton:
#+name: tut12a #+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 ltlfilt --from-ltlf -f "(a U b) & Fc" | ltl2tgba -B -d
#+end_src #+end_src
#+BEGIN_SRC dot :file tut12a.svg :var txt=tut12a :exports results #+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 4. Remove the =alive= property, and, while we are at it, simplify the
Büchi automaton: Büchi automaton:
#+name: tut12b #+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 ltlfilt --from-ltlf -f "(a U b) & Fc" | ltl2tgba -B | autfilt --remove-ap=alive -B --small -d
#+end_src #+end_src
#+BEGIN_SRC dot :file tut12b.svg :var txt=tut12b :exports results #+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). Interpreting the resulting Büchi automaton as a finite
automaton is out of scope for Spot. 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" | ltlfilt --from-ltlf -f "(a U b) & Fc" |
ltl2tgba -B | ltl2tgba -B |
autfilt --remove-ap=alive -B --small 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 =translate()=, but in this case removing the atomic proposition allows
more simplification opportunities.) more simplification opportunities.)
#+begin_src python :results output :exports both #+begin_src python
import spot import spot
# Translate LTLf to Büchi. # Translate LTLf to Büchi.
aut = spot.from_ltlf('(a U b) & Fc').translate('ba') aut = spot.from_ltlf('(a U b) & Fc').translate('ba')
@ -163,16 +166,16 @@ The Python functions =translate()= and =postprocess()= are convenient
wrappers around the =spot::translator= and =spot::postprocessor= wrappers around the =spot::translator= and =spot::postprocessor=
objects that we need to use here. objects that we need to use here.
#+begin_src cpp :results verbatim :exports both #+begin_src C++
#include <iostream> #include <iostream>
#include <spot/tl/parse.hh> #include <spot/tl/parse.hh>
#include <spot/tl/ltlf.hh> #include <spot/tl/ltlf.hh>
#include <spot/twaalgos/translate.hh> #include <spot/twaalgos/translate.hh>
#include <spot/twaalgos/hoa.hh> #include <spot/twaalgos/hoa.hh>
#include <spot/twaalgos/remprop.hh> #include <spot/twaalgos/remprop.hh>
int main() int main()
{ {
spot::parsed_formula pf = spot::parse_infix_psl("(a U b) & Fc"); spot::parsed_formula pf = spot::parse_infix_psl("(a U b) & Fc");
if (pf.format_errors(std::cerr)) if (pf.format_errors(std::cerr))
return 1; return 1;
@ -193,7 +196,7 @@ objects that we need to use here.
print_hoa(std::cout, aut) << '\n'; print_hoa(std::cout, aut) << '\n';
return 0; return 0;
} }
#+end_src #+end_src
#+RESULTS: #+RESULTS:

View file

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

View file

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

View file

@ -3,6 +3,8 @@
#+DESCRIPTION: Code example for constructing ω-automata in Spot #+DESCRIPTION: Code example for constructing ω-automata in Spot
#+INCLUDE: setup.org #+INCLUDE: setup.org
#+HTML_LINK_UP: tut.html #+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. This example demonstrates how to create an automaton and then print it.
@ -19,7 +21,7 @@ automata in Spot.
:CUSTOM_ID: cpp :CUSTOM_ID: cpp
:END: :END:
#+BEGIN_SRC C++ :results verbatim :exports both :wrap SRC hoa #+BEGIN_SRC C++
#include <iostream> #include <iostream>
#include <spot/twaalgos/hoa.hh> #include <spot/twaalgos/hoa.hh>
#include <spot/twa/twagraph.hh> #include <spot/twa/twagraph.hh>
@ -63,7 +65,7 @@ automata in Spot.
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
#+BEGIN_SRC hoa #+begin_SRC hoa
HOA: v1 HOA: v1
States: 3 States: 3
Start: 0 Start: 0
@ -80,11 +82,11 @@ State: 1
State: 2 State: 2
[0 | 1] 1 {0 1} [0 | 1] 1 {0 1}
--END-- --END--
#+END_SRC #+end_SRC
** Python ** Python
#+BEGIN_SRC python :results output :exports both :wrap SRC hoa #+BEGIN_SRC python
import spot import spot
import buddy import buddy
@ -124,7 +126,7 @@ State: 2
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
#+BEGIN_SRC hoa #+begin_SRC hoa
HOA: v1 HOA: v1
States: 3 States: 3
Start: 0 Start: 0
@ -141,7 +143,7 @@ State: 1
State: 2 State: 2
[0 | 1] 1 {0 1} [0 | 1] 1 {0 1}
--END-- --END--
#+END_SRC #+end_SRC
* Büchi automaton, with state-based acceptance * Büchi automaton, with state-based acceptance
:PROPERTIES: :PROPERTIES:
@ -172,7 +174,7 @@ whenever possible".
** C++ ** C++
#+BEGIN_SRC C++ :results verbatim :exports both :wrap SRC hoa #+BEGIN_SRC C++
#include <iostream> #include <iostream>
#include <spot/twaalgos/hoa.hh> #include <spot/twaalgos/hoa.hh>
#include <spot/twa/twagraph.hh> #include <spot/twa/twagraph.hh>
@ -240,7 +242,7 @@ State: 2
** Python ** Python
#+BEGIN_SRC python :results output :exports both :wrap SRC hoa #+BEGIN_SRC python
import spot import spot
import buddy import buddy
@ -313,7 +315,7 @@ Arbitrary acceptance condition can be set with =set_acceptance=.
** C++ ** C++
#+BEGIN_SRC C++ :results verbatim :exports both :wrap SRC hoa #+BEGIN_SRC C++
#include <iostream> #include <iostream>
#include <spot/twaalgos/hoa.hh> #include <spot/twaalgos/hoa.hh>
#include <spot/twa/twagraph.hh> #include <spot/twa/twagraph.hh>
@ -362,7 +364,7 @@ State: 2
** Python ** Python
#+BEGIN_SRC python :results output :exports both :wrap SRC hoa #+BEGIN_SRC python
import spot import spot
import buddy import buddy
@ -384,3 +386,22 @@ State: 2
print(aut.to_str('hoa')) print(aut.to_str('hoa'))
#+END_SRC #+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 #+DESCRIPTION: Code example for constructing alternating ω-automata in Spot
#+INCLUDE: setup.org #+INCLUDE: setup.org
#+HTML_LINK_UP: tut.html #+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 This example demonstrates how to create the following alternating
co-Büchi automaton (recognizing =GFa=) and then print it. co-Büchi automaton (recognizing =GFa=) and then print it.
#+NAME: tut23-dot #+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 autfilt --dot <<EOF
$txt $txt
EOF EOF
@ -33,7 +36,7 @@ edges (declared with =new_edge()=) and universal edges (declared with
:END: :END:
#+NAME: tut23-cpp #+NAME: tut23-cpp
#+BEGIN_SRC C++ :results verbatim :exports both :wrap SRC hoa #+BEGIN_SRC C++ :wrap SRC hoa
#include <iostream> #include <iostream>
#include <spot/twaalgos/hoa.hh> #include <spot/twaalgos/hoa.hh>
#include <spot/twa/twagraph.hh> #include <spot/twa/twagraph.hh>
@ -80,15 +83,15 @@ edges (declared with =new_edge()=) and universal edges (declared with
#+END_SRC #+END_SRC
#+RESULTS: tut23-cpp #+RESULTS: tut23-cpp
#+BEGIN_SRC hoa #+begin_SRC hoa
HOA: v1 HOA: v1
States: 3 States: 3
Start: 0 Start: 0
AP: 1 "a" AP: 1 "a"
acc-name: co-Buchi acc-name: co-Buchi
Acceptance: 1 Fin(0) Acceptance: 1 Fin(0)
properties: univ-branch trans-labels explicit-labels trans-acc complete properties: trans-labels explicit-labels trans-acc complete
properties: deterministic properties: deterministic univ-branch
--BODY-- --BODY--
State: 0 State: 0
[0] 0 [0] 0
@ -99,11 +102,11 @@ State: 1
State: 2 State: 2
[t] 2 [t] 2
--END-- --END--
#+END_SRC #+end_SRC
* Python * Python
#+BEGIN_SRC python :results output :exports both :wrap SRC hoa #+BEGIN_SRC python :wrap SRC hoa
import spot import spot
import buddy import buddy

View file

@ -3,6 +3,8 @@
#+DESCRIPTION: Code example for iterating of alternating ω-automata in Spot #+DESCRIPTION: Code example for iterating of alternating ω-automata in Spot
#+INCLUDE: setup.org #+INCLUDE: setup.org
#+HTML_LINK_UP: tut.html #+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 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 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]]. [[file:tut21.org][custom automaton printer]].
#+NAME: nonalt-body #+NAME: nonalt-body
#+BEGIN_SRC C++ #+BEGIN_SRC C++ :export code
std::cout << "Initial state: " << aut->get_init_state_number() << '\n'; std::cout << "Initial state: " << aut->get_init_state_number() << '\n';
const spot::bdd_dict_ptr& dict = aut->get_dict(); const spot::bdd_dict_ptr& dict = aut->get_dict();
@ -98,7 +100,7 @@ for (unsigned s = 0; s < n; ++s)
#+END_SRC #+END_SRC
#+NAME: nonalt-one #+NAME: nonalt-one
#+BEGIN_SRC C++ :exports none :noweb strip-export :results verbatim #+BEGIN_SRC C++ :exports none
<<nonalt-main>> <<nonalt-main>>
void custom_print(spot::twa_graph_ptr& aut) 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. decide whether to enclose the destinations in braces.
#+NAME: nonalt-body2 #+NAME: nonalt-body2
#+BEGIN_SRC C++ #+BEGIN_SRC C++ :export code
unsigned init = aut->get_init_state_number(); unsigned init = aut->get_init_state_number();
std::cout << "Initial state:"; std::cout << "Initial state:";
if (aut->is_univ_dest(init)) if (aut->is_univ_dest(init))
@ -169,7 +171,7 @@ decide whether to enclose the destinations in braces.
#+END_SRC #+END_SRC
#+NAME: nonalt-two #+NAME: nonalt-two
#+BEGIN_SRC C++ :exports none :noweb strip-export :results verbatim #+BEGIN_SRC C++ :exports none
<<nonalt-main>> <<nonalt-main>>
void custom_print(spot::twa_graph_ptr& aut) void custom_print(spot::twa_graph_ptr& aut)
{ {
@ -187,7 +189,7 @@ decide whether to enclose the destinations in braces.
Here is the Python version of this code: Here is the Python version of this code:
#+BEGIN_SRC python :results output :exports both #+BEGIN_SRC python
import spot import spot
aut = spot.automaton("tut24.hoa") aut = spot.automaton("tut24.hoa")

View file

@ -3,17 +3,18 @@
#+DESCRIPTION: Code example for converting ω-automata in Spot #+DESCRIPTION: Code example for converting ω-automata in Spot
#+INCLUDE: setup.org #+INCLUDE: setup.org
#+HTML_LINK_UP: tut.html #+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=: 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 ltldo ltl2dstar -f 'F(Xp1 xor XXp1)' > tut30.hoa
#+END_SRC #+END_SRC
#+RESULTS:
#+NAME: tut30in #+NAME: tut30in
#+BEGIN_SRC sh :results verbatim :exports none #+BEGIN_SRC sh :exports none
autfilt tut30.hoa --dot autfilt tut30.hoa --dot
#+END_SRC #+END_SRC
@ -39,11 +40,11 @@ not only be changed to Büchi, but simplification routines (useless
SCCs removal, simulation-based reductions, acceptance sets SCCs removal, simulation-based reductions, acceptance sets
simplifications, WDBA-minimization, ...) will also be applied. 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 autfilt -B -D tut30.hoa
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
#+BEGIN_SRC hoa #+begin_SRC hoa
HOA: v1 HOA: v1
States: 5 States: 5
Start: 1 Start: 1
@ -51,7 +52,7 @@ AP: 1 "p1"
acc-name: Buchi acc-name: Buchi
Acceptance: 1 Inf(0) Acceptance: 1 Inf(0)
properties: trans-labels explicit-labels state-acc complete properties: trans-labels explicit-labels state-acc complete
properties: deterministic weak properties: deterministic very-weak
--BODY-- --BODY--
State: 0 {0} State: 0 {0}
[t] 0 [t] 0
@ -67,40 +68,13 @@ State: 4
[!0] 0 [!0] 0
[0] 4 [0] 4
--END-- --END--
#+END_SRC #+end_SRC
#+NAME: tut30out #+NAME: tut30out
#+BEGIN_SRC sh :results verbatim :exports none #+BEGIN_SRC sh :exports none
autfilt -B -D -d tut30.hoa autfilt -B -D -d tut30.hoa
#+END_SRC #+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 #+BEGIN_SRC dot :file tut30out.svg :var txt=tut30out :exports results
$txt $txt
#+END_SRC #+END_SRC
@ -118,7 +92,7 @@ the result further.
The Python version uses the =postprocess()= routine: 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 import spot
aut = spot.automaton('tut30.hoa').postprocess('BA', 'deterministic') aut = spot.automaton('tut30.hoa').postprocess('BA', 'deterministic')
print(aut.to_str('hoa')) print(aut.to_str('hoa'))
@ -153,7 +127,7 @@ State: 4
The =postprocess()= function has an interface similar to The =postprocess()= function has an interface similar to
[[file:tut10.org][the =translate()= function discussed previously]]: [[file:tut10.org][the =translate()= function discussed previously]]:
#+BEGIN_SRC python :results output :exports both #+BEGIN_SRC python
import spot import spot
help(spot.postprocess) help(spot.postprocess)
#+END_SRC #+END_SRC
@ -162,7 +136,7 @@ help(spot.postprocess)
#+begin_example #+begin_example
Help on function postprocess in module spot: Help on function postprocess in module spot:
postprocess(automaton, *args) postprocess(automaton, *args, formula=None, xargs=None)
Post process an automaton. Post process an automaton.
This applies a number of simlification algorithms, depending on This applies a number of simlification algorithms, depending on
@ -171,17 +145,29 @@ postprocess(automaton, *args)
not already 'Deterministic'. not already 'Deterministic'.
The optional arguments should be strings among the following: The optional arguments should be strings among the following:
- at most one in 'Generic', 'TGBA', 'BA', or 'Monitor' - at most one in 'Generic', 'TGBA', 'BA', or 'Monitor',
(type of automaton to build) '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' - at most one in 'Small', 'Deterministic', 'Any'
(preferred characteristics of the produced automaton) (preferred characteristics of the produced automaton)
- at most one in 'Low', 'Medium', 'High' - at most one in 'Low', 'Medium', 'High'
(optimization level) (optimization level)
- any combination of 'Complete' and 'StateBasedAcceptance' - any combination of 'Complete', 'StateBasedAcceptance'
(or 'SBAcc' for short) (or 'SBAcc' for short), and 'Colored (only for parity
acceptance)
The default corresponds to 'generic', 'small' and 'high'. 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 #+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 =postprocessor= object, configure it, and then call it for each
automaton to process. automaton to process.
#+BEGIN_SRC C++ :results verbatim :exports both :wrap SRC hoa #+BEGIN_SRC C++ :wrap SRC hoa
#include <iostream> #include <iostream>
#include <spot/parseaut/public.hh> #include <spot/parseaut/public.hh>
#include <spot/twaalgos/postproc.hh> #include <spot/twaalgos/postproc.hh>
@ -219,7 +205,7 @@ automaton to process.
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
#+BEGIN_SRC hoa #+begin_SRC hoa
HOA: v1 HOA: v1
States: 5 States: 5
Start: 1 Start: 1
@ -227,7 +213,7 @@ AP: 1 "p1"
acc-name: Buchi acc-name: Buchi
Acceptance: 1 Inf(0) Acceptance: 1 Inf(0)
properties: trans-labels explicit-labels state-acc complete properties: trans-labels explicit-labels state-acc complete
properties: deterministic weak properties: deterministic very-weak
--BODY-- --BODY--
State: 0 {0} State: 0 {0}
[t] 0 [t] 0
@ -243,8 +229,8 @@ State: 4
[!0] 0 [!0] 0
[0] 4 [0] 4
--END-- --END--
#+END_SRC #+end_SRC
#+BEGIN_SRC sh :results silent :exports results #+BEGIN_SRC sh :results silent
rm -f tut30.hoa rm -f tut30.hoa
#+END_SRC #+END_SRC

View file

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

View file

@ -3,6 +3,7 @@
#+DESCRIPTION: Explanation of the explicit and on-the-fly automata interfaces in Spot #+DESCRIPTION: Explanation of the explicit and on-the-fly automata interfaces in Spot
#+INCLUDE: setup.org #+INCLUDE: setup.org
#+HTML_LINK_UP: tut.html #+HTML_LINK_UP: tut.html
#+PROPERTY: header-args:C+++ :results verbatim :exports both
When exploring automata (i.e., following its transition structure), 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 From a state number =s=, it is possible to iterate over all successors
by doing a =for= loop on =out(s)=, as in: by doing a =for= loop on =out(s)=, as in:
#+BEGIN_SRC C++ :results verbatim :exports both #+BEGIN_SRC C++
#include <iostream> #include <iostream>
#include <spot/twa/twagraph.hh> #include <spot/twa/twagraph.hh>
#include <spot/tl/parse.hh> #include <spot/tl/parse.hh>
@ -188,9 +189,9 @@ by doing a =for= loop on =out(s)=, as in:
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
: 2->0 : 0->0
: 2->1 : 0->1
: 2->2 : 0->2
In the above lines, =aut->out(s)= delegates to In the above lines, =aut->out(s)= delegates to
=aut->get_graphs().out(s)= and returns a =state_out<graph_t>= =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 container with =begin()= and =end()= methods. The ranged-for loop
syntax of C++ works exactly as if we had typed 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? // 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 // In any case, do not spell out the types of tmp and i, as those
// should be considered internal details. // 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 In fact after operators are inlined and useless temporary variables
removed, the above loop compiles to something equivalent to this: 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 // 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 // helps (e.g., if you want to pause the loop and then resume it, as
// we will do later). // 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 vector of visited states in order to not visit them twice, and recurse
on all successors of the given state. on all successors of the given state.
#+BEGIN_SRC C++ :results verbatim :exports both #+BEGIN_SRC C++
#include <iostream> #include <iostream>
#include <spot/twa/twagraph.hh> #include <spot/twa/twagraph.hh>
#include <spot/tl/parse.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 accessible transitions in a "DFS-ish" way, but without producing
exactly the same output as above. exactly the same output as above.
#+BEGIN_SRC C++ :results verbatim :exports both #+BEGIN_SRC C++
#include <iostream> #include <iostream>
#include <stack> #include <stack>
#include <spot/twa/twagraph.hh> #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 stores the number of the next edge leaving the same source
state, so this is enough to remember where we are. state, so this is enough to remember where we are.
#+BEGIN_SRC C++ :results verbatim :exports both #+BEGIN_SRC C++
#include <iostream> #include <iostream>
#include <stack> #include <stack>
#include <spot/twa/twagraph.hh> #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 To summarize, here is a crude loop over the successors of the initial
state: state:
#+BEGIN_SRC C++ :results verbatim :exports both #+BEGIN_SRC C++
#include <iostream> #include <iostream>
#include <spot/twa/twa.hh> #include <spot/twa/twa.hh>
#include <spot/tl/parse.hh> #include <spot/tl/parse.hh>
@ -608,9 +609,9 @@ state:
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
: 2->0 : 0->0
: 2->1 : 0->1
: 2->2 : 0->2
Notice that a =twa_succ_iterator= allows iterating over outgoing Notice that a =twa_succ_iterator= allows iterating over outgoing
edges, but only offers access to =dst()=, =acc()=, and =cond()= for 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 the loop could continue. This allows rewriting the above code as
follows: follows:
#+BEGIN_SRC C++ #+BEGIN_SRC C++ :exports code
void example(spot::const_twa_ptr aut) void example(spot::const_twa_ptr aut)
{ {
const spot::state* s = aut->get_init_state(); 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 Using C++11's ranged =for= loop, this example can be reduced to the
following equivalent code: following equivalent code:
#+BEGIN_SRC C++ :results verbatim :exports both #+BEGIN_SRC C++
#include <iostream> #include <iostream>
#include <spot/twa/twa.hh> #include <spot/twa/twa.hh>
#include <spot/tl/parse.hh> #include <spot/tl/parse.hh>
@ -683,9 +684,9 @@ following equivalent code:
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
: 2->0 : 0->0
: 2->1 : 0->1
: 2->2 : 0->2
This works in a similar way as =out(s)= in the explicit interface. This works in a similar way as =out(s)= in the explicit interface.
Calling =aut->succ(s)= creates a fake container 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 anymore. This tracking can be done using the data structure we use to
remember what states we have already seen. remember what states we have already seen.
#+BEGIN_SRC C++ :results verbatim :exports both #+BEGIN_SRC C++
#include <iostream> #include <iostream>
#include <unordered_set> #include <unordered_set>
#include <spot/twa/twa.hh> #include <spot/twa/twa.hh>
@ -754,10 +755,10 @@ remember what states we have already seen.
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
: 2->0
: 0->0 : 0->0
: 2->1 : 0->1
: 1->1 : 1->1
: 0->2
: 2->2 : 2->2
** Recursive DFS (v2) ** 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: 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 <iostream>
#include <spot/twa/twa.hh> #include <spot/twa/twa.hh>
#include <spot/tl/parse.hh> #include <spot/tl/parse.hh>
@ -809,10 +810,10 @@ With this class, the recursive code can be simplified down to this:
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
: 2->0
: 0->0 : 0->0
: 2->1 : 0->1
: 1->1 : 1->1
: 0->2
: 2->2 : 2->2
Note how this completely hides all the calls to =state::destroy()=. 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 source, so we better store that in the stack as well if we want to
print it. print it.
#+BEGIN_SRC C++ :results verbatim :exports both #+BEGIN_SRC C++
#include <iostream> #include <iostream>
#include <stack> #include <stack>
#include <spot/twa/twa.hh> #include <spot/twa/twa.hh>
@ -883,8 +884,8 @@ print it.
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
: 2->0
: 0->0 : 0->0
: 2->1 : 0->1
: 1->1 : 1->1
: 0->2
: 2->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 If Spot 1.2.6 was installed in =/usr/local=, its headers are
in =/usr/local/include/spot=. One would to write include statements in =/usr/local/include/spot=. One would to write include statements
such as such as
#+BEGIN_SRC c++ #+BEGIN_SRC C++
#include <tgba/tgba.hh> #include <tgba/tgba.hh>
#include <ltl/formula.hh> #include <ltl/formula.hh>
#+END_SRC #+END_SRC
@ -126,7 +126,7 @@ directory.
If Spot 2.0 is installed in =/usr/local=, its headers are still in 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 =/usr/local/include/spot= however the =spot/= directory is and should
always be used to refer to the header: 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/twa/twa.hh> // the new name of tgba/tgba.hh
#include <spot/tl/formula.hh> // the new name of ltl/formula.hh #include <spot/tl/formula.hh> // the new name of ltl/formula.hh
#+END_SRC #+END_SRC
@ -454,7 +454,7 @@ name:
handle those larger acceptance conditions, or restricted to handle those larger acceptance conditions, or restricted to
generalized Büchi acceptance. The typical way to ensure generalized Büchi acceptance. The typical way to ensure
that an =input= automaton has generalized Büchi acceptance is that an =input= automaton has generalized Büchi acceptance is
#+BEGIN_SRC c++ #+BEGIN_SRC C++
if (!input->acc().is_generalized_buchi()) if (!input->acc().is_generalized_buchi())
throw std::runtime_error throw std::runtime_error
("myalgorithm() can only works with generalized Büchi acceptance"); ("myalgorithm() can only works with generalized Büchi acceptance");
@ -600,7 +600,6 @@ for (auto i: aut->succ(s))
* Various renamings * Various renamings
:PROPERTIES: :PROPERTIES:
:CUSTOM_ID: renamings :CUSTOM_ID: renamings
:END: :END:
@ -611,7 +610,7 @@ for (auto i: aut->succ(s))
| old name | new name | comment | | old name | new name | comment |
|-------------------------------------------------------------+---------------------------------------------+-----------------------------------------------------------| |-------------------------------------------------------------+---------------------------------------------+-----------------------------------------------------------|
| ~dstar_parse()~ | ~parse_aut()~ | single parser for all automata | | ~dstar_parse()~ | ~parse_aut()~ | single parser for all automata |
| ~dtgba_complement()~ | ~dtwa_complement()~ | | | ~dtgba_complement()~ | ~dualize()~ | |
| ~dupexp_bfs()~ | | deleted | | ~dupexp_bfs()~ | | deleted |
| ~dupexp_dfs()~ | ~make_twa_graph()~ | | | ~dupexp_dfs()~ | ~make_twa_graph()~ | |
| ~format_parse_aut_errors()~ | ~parsed_aut::format_errors()~ | | | ~format_parse_aut_errors()~ | ~parsed_aut::format_errors()~ | |