diff --git a/doc/org/autcross.org b/doc/org/autcross.org index 7a09e66ec..201be9abc 100644 --- a/doc/org/autcross.org +++ b/doc/org/autcross.org @@ -3,6 +3,7 @@ #+DESCRIPTION: Spot command-line tool for cross-comparing the output of automaton processors. #+INCLUDE: setup.org #+HTML_LINK_UP: tools.html +#+PROPERTY: header-args:sh :results verbatim :exports both =autcross= is a tool for cross-comparing the output of tools that transform automata. It works similarly to [[file:ltlcross.org][=ltlcross=]] except that @@ -33,7 +34,7 @@ and will appear in the CSV file if such a file is output. Each tool should be specified as a string that uses some of the following character sequences: -#+BEGIN_SRC sh :results verbatim :exports results +#+BEGIN_SRC sh :exports results autcross --help | sed -n '/character sequences:/,/^$/p' | sed '1d;$d' #+END_SRC #+RESULTS: @@ -55,31 +56,26 @@ Another tool that can complement automata is =ltl2dstar=, using the syntax =ltl2dstar -B --complement-input=yes %H %O=. So to compare the results of these two tools we could use: -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :prologue "exec 2>&1" randaut -B -n 3 a b | autcross 'autfilt --complement %H >%O' 'ltl2dstar --complement-input=yes -B %H %O' #+END_SRC -#+BEGIN_SRC sh :results verbatim :exports output -randaut -B -n 3 a b | -autcross 'autfilt --complement %H >%O' 'ltl2dstar --complement-input=yes -B %H %O' 2>&1 -#+END_SRC - #+RESULTS: #+begin_example -:1.1-45.7 -Running [A0]: autfilt --complement 'lcr-i0-Nr1xZO' >'lcr-o0-urHakt' -Running [A1]: ltl2dstar -B --complement-input=yes 'lcr-i0-mmkgH7' 'lcr-o1-ABdm4L' +Running [A0]: autfilt --complement 'lcr-i0-lOYLT5' >'lcr-o0-HB5WGO' +Running [A1]: ltl2dstar --complement-input=yes -B 'lcr-i0-UIX3wx' 'lcr-o1-f8abng' Performing sanity checks and gathering statistics... -:46.1-92.7 -Running [A0]: autfilt --complement 'lcr-i1-5kMYrq' >'lcr-o0-9kvBP4' -Running [A1]: ltl2dstar -B --complement-input=yes 'lcr-i1-lVlGfJ' 'lcr-o1-BexLFn' +Running [A0]: autfilt --complement 'lcr-i1-Eq2WdZ' >'lcr-o0-CvfJ4H' +Running [A1]: ltl2dstar --complement-input=yes -B 'lcr-i1-736tYq' 'lcr-o1-YvkfS9' Performing sanity checks and gathering statistics... -:93.1-137.7 -Running [A0]: autfilt --complement 'lcr-i2-rjvy61' >'lcr-o0-rKKlxG' -Running [A1]: ltl2dstar -B --complement-input=yes 'lcr-i2-Musr0k' 'lcr-o1-LyAxtZ' +Running [A0]: autfilt --complement 'lcr-i2-6ahOMS' >'lcr-o0-HdynHB' +Running [A1]: ltl2dstar --complement-input=yes -B 'lcr-i2-9PcREk' 'lcr-o1-XcblC3' Performing sanity checks and gathering statistics... No problem detected. @@ -87,12 +83,12 @@ No problem detected. In this example, we generate 3 random Büchi automata (because =ltl2dstar= expects Büchi automata as input) using [[file:randaut.org][=randaut=]], and pipe -them to =autcross=. For each of those automata, =autcross= display +them to =autcross=. For each of those automata, =autcross= displays the source location of that automaton (here =-= indicates that the automaton is read from standard input, and this is followed by =beginline.column-endline.colum= specifying the position of that -automaton in the input. If the automata had names, they would -be displayed as well. +automaton in the input. If the automata had names, they would be +displayed as well. Then, each tool is called using temporary files to exchange the automata, and the resulting automata are then compared. The last line @@ -103,7 +99,7 @@ To simplify the use of some known tools, a set of predefined shorthands are available. Those can be listed with the =--list-shorthands= option. -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh autcross --list-shorthands #+END_SRC #+RESULTS: @@ -112,9 +108,11 @@ If a COMMANDFMT does not use any %-sequence, and starts with one of the following words, then the string on the right is appended. autfilt %H>%O - seminator %H>%O + dstar2tgba %H>%O ltl2dstar -B %H %O + nba2dpa <%H>%O nba2ldpa <%H>%O + seminator %H>%O Any {name} and directory component is skipped for the purpose of matching those prefixes. So for instance @@ -125,7 +123,7 @@ will be changed into What this implies is our previous example could be shortened to: -#+BEGIN_SRC sh :results silent :exports code +#+BEGIN_SRC sh :exports code randaut -B -n 3 a b | autcross 'autfilt --complement' 'ltl2dstar --complement-input=yes' #+END_SRC @@ -146,31 +144,26 @@ Second, we pass a =--csv= option to =autcross= to save statistics in a file. -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :prologue "exec 2>&1" randaut -B -n 3 a b --name="automaton %L" | autcross 'autfilt --complement' 'ltl2dstar --complement-input=yes' --csv=autcross.csv #+END_SRC -#+BEGIN_SRC sh :results verbatim :exports results -randaut -B -n 3 a b --name="automaton %L" | -autcross 'autfilt --complement' 'ltl2dstar --complement-input=yes' --csv=autcross.csv 2>&1 -#+END_SRC - #+RESULTS: #+begin_example -:1.1-46.7 automaton 0 -Running [A0]: autfilt --complement 'lcr-i0-QHReWu'>'lcr-o0-0eTOmZ' -Running [A1]: ltl2dstar --complement-input=yes -B 'lcr-i0-jsoPPt' 'lcr-o1-66bQiY' +Running [A0]: autfilt --complement 'lcr-i0-YPfmR5'>'lcr-o0-Z1bT0A' +Running [A1]: ltl2dstar --complement-input=yes -B 'lcr-i0-DpL2i6' 'lcr-o1-gpYcBB' Performing sanity checks and gathering statistics... -:47.1-94.7 automaton 1 -Running [A0]: autfilt --complement 'lcr-i1-IubpMs'>'lcr-o0-dfmYfX' -Running [A1]: ltl2dstar --complement-input=yes -B 'lcr-i1-13NXLr' 'lcr-o1-zSwXhW' +Running [A0]: autfilt --complement 'lcr-i1-mxsGU6'>'lcr-o0-fPCaeC' +Running [A1]: ltl2dstar --complement-input=yes -B 'lcr-i1-2hgYD7' 'lcr-o1-S4xM3C' Performing sanity checks and gathering statistics... -:95.1-140.7 automaton 2 -Running [A0]: autfilt --complement 'lcr-i2-g5bDOq'>'lcr-o0-X71ilV' -Running [A1]: ltl2dstar --complement-input=yes -B 'lcr-i2-og1mUp' 'lcr-o1-QVurtU' +Running [A0]: autfilt --complement 'lcr-i2-YU1Qu8'>'lcr-o0-hwVVVD' +Running [A1]: ltl2dstar --complement-input=yes -B 'lcr-i2-MLmVq9' 'lcr-o1-edfVVE' Performing sanity checks and gathering statistics... No problem detected. @@ -178,17 +171,27 @@ No problem detected. After this execution, the file =autcross.csv= contains the following: -#+BEGIN_SRC sh :results verbatim :exports results -cat autcross.csv +#+BEGIN_SRC sh :results output raw :exports results +sed 's/"//g +1a\ +|-| +s/--/@@html:--@@/g +s/^/| / +s/$/ |/ +s/,/|/g +' autcross.csv #+END_SRC + +#+ATTR_HTML: :class csv-table #+RESULTS: -: "input.source","input.name","input.ap","input.states","input.edges","input.transitions","input.acc_sets","input.scc","input.nondetstates","input.nondeterministic","input.alternating","tool","exit_status","exit_code","time","output.ap","output.states","output.edges","output.transitions","output.acc_sets","output.scc","output.nondetstates","output.nondeterministic","output.alternating" -: "-:1.1-46.7","automaton 0",2,10,26,26,1,1,6,0,0,"autfilt --complement","ok",0,0.0129685,2,27,95,108,3,2,0,0,0 -: "-:1.1-46.7","automaton 0",2,10,26,26,1,1,6,0,0,"ltl2dstar --complement-input=yes","ok",0,0.00202496,2,34,121,136,6,2,0,9,0 -: "-:47.1-94.7","automaton 1",2,10,28,28,1,1,4,0,0,"autfilt --complement","ok",0,0.0128458,2,58,216,232,3,2,0,9,0 -: "-:47.1-94.7","automaton 1",2,10,28,28,1,1,4,0,0,"ltl2dstar --complement-input=yes","ok",0,0.0026184,2,74,268,296,6,2,0,8,0 -: "-:95.1-140.7","automaton 2",2,10,26,26,1,2,6,0,0,"autfilt --complement","ok",0,0.0127144,2,21,69,84,2,4,0,20,0 -: "-:95.1-140.7","automaton 2",2,10,26,26,1,2,6,0,0,"ltl2dstar --complement-input=yes","ok",0,0.00180888,2,24,74,96,2,4,0,35,0 +| input.source | input.name | input.ap | input.states | input.edges | input.transitions | input.acc_sets | input.scc | input.nondetstates | input.nondeterministic | input.alternating | tool | exit_status | exit_code | time | output.ap | output.states | output.edges | output.transitions | output.acc_sets | output.scc | output.nondetstates | output.nondeterministic | output.alternating | +|--------------+-------------+----------+--------------+-------------+-------------------+----------------+-----------+--------------------+------------------------+-------------------+-------------------------------------------+-------------+-----------+------------+-----------+---------------+--------------+--------------------+-----------------+------------+---------------------+-------------------------+--------------------| +| -:1.1-46.7 | automaton 0 | 2 | 10 | 26 | 26 | 1 | 1 | 6 | 1 | 0 | autfilt @@html:--@@complement | ok | 0 | 0.0217727 | 2 | 26 | 91 | 104 | 5 | 2 | 0 | 0 | 0 | +| -:1.1-46.7 | automaton 0 | 2 | 10 | 26 | 26 | 1 | 1 | 6 | 1 | 0 | ltl2dstar @@html:--@@complement-input=yes | ok | 0 | 0.00293471 | 2 | 34 | 121 | 136 | 6 | 2 | 0 | 0 | 0 | +| -:47.1-94.7 | automaton 1 | 2 | 10 | 28 | 28 | 1 | 1 | 4 | 1 | 0 | autfilt @@html:--@@complement | ok | 0 | 0.0212838 | 2 | 54 | 197 | 216 | 3 | 2 | 0 | 0 | 0 | +| -:47.1-94.7 | automaton 1 | 2 | 10 | 28 | 28 | 1 | 1 | 4 | 1 | 0 | ltl2dstar @@html:--@@complement-input=yes | ok | 0 | 0.00403921 | 2 | 74 | 268 | 296 | 6 | 2 | 0 | 0 | 0 | +| -:95.1-140.7 | automaton 2 | 2 | 10 | 26 | 26 | 1 | 2 | 6 | 1 | 0 | autfilt @@html:--@@complement | ok | 0 | 0.0205316 | 2 | 21 | 66 | 84 | 2 | 4 | 0 | 0 | 0 | +| -:95.1-140.7 | automaton 2 | 2 | 10 | 26 | 26 | 1 | 2 | 6 | 1 | 0 | ltl2dstar @@html:--@@complement-input=yes | ok | 0 | 0.00263697 | 2 | 24 | 74 | 96 | 2 | 4 | 0 | 0 | 0 | This file can then be loaded in any spreadsheet or statistical application. @@ -213,21 +216,37 @@ tools are the command specified on the command line. Like with =ltlcross=, this can be adjusted by using a command specification of the form ={short name}actual command=. -For instance - -#+BEGIN_SRC sh :results verbatim :exports both +For instance: +#+NAME: autcross2 +#+BEGIN_SRC sh :exports code randaut -B -n 3 a b --name="automaton %L" | autcross '{AF}autfilt --complement' '{L2D}ltl2dstar --complement-input=yes' --csv #+END_SRC +#+BEGIN_SRC sh :results output raw :exports results :noweb yes +sed 's/"//g +s/--/@@html:--@@/g +s/^/| / +s/$/ |/ +s/,/|/g +$d +1a\ +|-| +' <> +EOF +#+END_SRC + +#+ATTR_HTML: :class csv-table #+RESULTS: -: "input.source","input.name","input.ap","input.states","input.edges","input.transitions","input.acc_sets","input.scc","input.nondetstates","input.nondeterministic","input.alternating","tool","exit_status","exit_code","time","output.ap","output.states","output.edges","output.transitions","output.acc_sets","output.scc","output.nondetstates","output.nondeterministic","output.alternating" -: "-:1.1-46.7","automaton 0",2,10,26,26,1,1,6,0,0,"AF","ok",0,0.039722,2,27,95,108,3,2,0,0,0 -: "-:1.1-46.7","automaton 0",2,10,26,26,1,1,6,0,0,"L2D","ok",0,0.00640371,2,34,121,136,6,2,0,9,0 -: "-:47.1-94.7","automaton 1",2,10,28,28,1,1,4,0,0,"AF","ok",0,0.0400776,2,58,216,232,3,2,0,9,0 -: "-:47.1-94.7","automaton 1",2,10,28,28,1,1,4,0,0,"L2D","ok",0,0.00489558,2,74,268,296,6,2,0,20,0 -: "-:95.1-140.7","automaton 2",2,10,26,26,1,2,6,0,0,"AF","ok",0,0.0220585,2,21,69,84,2,4,0,7,0 -: "-:95.1-140.7","automaton 2",2,10,26,26,1,2,6,0,0,"L2D","ok",0,0.00329786,2,24,74,96,2,4,0,23,0 +| input.source | input.name | input.ap | input.states | input.edges | input.transitions | input.acc_sets | input.scc | input.nondetstates | input.nondeterministic | input.alternating | tool | exit_status | exit_code | time | output.ap | output.states | output.edges | output.transitions | output.acc_sets | output.scc | output.nondetstates | output.nondeterministic | output.alternating | +|--------------+-------------+----------+--------------+-------------+-------------------+----------------+-----------+--------------------+------------------------+-------------------+------+-------------+-----------+------------+-----------+---------------+--------------+--------------------+-----------------+------------+---------------------+-------------------------+--------------------| +| -:1.1-46.7 | automaton 0 | 2 | 10 | 26 | 26 | 1 | 1 | 6 | 1 | 0 | AF | ok | 0 | 0.0239042 | 2 | 26 | 91 | 104 | 5 | 2 | 0 | 0 | 0 | +| -:1.1-46.7 | automaton 0 | 2 | 10 | 26 | 26 | 1 | 1 | 6 | 1 | 0 | L2D | ok | 0 | 0.00315407 | 2 | 34 | 121 | 136 | 6 | 2 | 0 | 0 | 0 | +| -:47.1-94.7 | automaton 1 | 2 | 10 | 28 | 28 | 1 | 1 | 4 | 1 | 0 | AF | ok | 0 | 0.0218867 | 2 | 54 | 197 | 216 | 3 | 2 | 0 | 0 | 0 | +| -:47.1-94.7 | automaton 1 | 2 | 10 | 28 | 28 | 1 | 1 | 4 | 1 | 0 | L2D | ok | 0 | 0.00413592 | 2 | 74 | 268 | 296 | 6 | 2 | 0 | 0 | 0 | +| -:95.1-140.7 | automaton 2 | 2 | 10 | 26 | 26 | 1 | 2 | 6 | 1 | 0 | AF | ok | 0 | 0.0211636 | 2 | 21 | 66 | 84 | 2 | 4 | 0 | 0 | 0 | +| -:95.1-140.7 | automaton 2 | 2 | 10 | 26 | 26 | 1 | 2 | 6 | 1 | 0 | L2D | ok | 0 | 0.0028508 | 2 | 24 | 74 | 96 | 2 | 4 | 0 | 0 | 0 | * Language preserving transformation @@ -264,28 +283,23 @@ To simulate a problem, let's compare pretend we want verify that =autfilt --complement= preserves the input language (clearly it does not, since it actually complement the language of the automaton). -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :prologue "exec 2>&1" :epilogue true randaut -B -n 3 a b --name="automaton %L" | autcross --language-preserved 'autfilt --complement' #+END_SRC -#+BEGIN_SRC sh :results verbatim :exports output -randaut -B -n 3 a b --name="automaton %L" | -autcross --language-preserved 'autfilt --complement' 2>&1 -#+END_SRC - #+RESULTS: #+begin_example -:1.1-46.7 automaton 0 -Running [A0]: autfilt --complement 'lcr-i0-3gRqrd'>'lcr-o0-ubUpHb' +Running [A0]: autfilt --complement 'lcr-i0-ttpQt9'>'lcr-o0-elszrt' Performing sanity checks and gathering statistics... error: A0*Comp(input) is nonempty; both automata accept the infinite word: - !a & !b; a & !b; cycle{!a & !b; a & !b; !a & b; !a & b; !a & !b; !a & b; !a & b; !a & !b} + cycle{!a & !b; a & !b} error: input*Comp(A0) is nonempty; both automata accept the infinite word: !a & !b; !a & !b; cycle{!a & !b; !a & b; a & b} -:47.1-94.7 automaton 1 -Running [A0]: autfilt --complement 'lcr-i1-JxFi09'>'lcr-o0-oQGbj8' +Running [A0]: autfilt --complement 'lcr-i1-rFJYtN'>'lcr-o0-66sow7' Performing sanity checks and gathering statistics... error: A0*Comp(input) is nonempty; both automata accept the infinite word: !a & b; cycle{a & !b} @@ -293,10 +307,10 @@ error: input*Comp(A0) is nonempty; both automata accept the infinite word: !a & b; a & !b; cycle{!a & b; a & b} -:95.1-140.7 automaton 2 -Running [A0]: autfilt --complement 'lcr-i2-SQT7E6'>'lcr-o0-kWt404' +Running [A0]: autfilt --complement 'lcr-i2-00isDr'>'lcr-o0-R6BwKL' Performing sanity checks and gathering statistics... error: A0*Comp(input) is nonempty; both automata accept the infinite word: - a & !b; !a & !b; cycle{a & !b; !a & b} + !a & b; cycle{!a & !b} error: input*Comp(A0) is nonempty; both automata accept the infinite word: cycle{!a & b; !a & b; !a & !b; a & !b; a & !b; !a & !b} @@ -349,29 +363,24 @@ makes sense if you only care about the output of =--csv=. The verbose option can be useful to troubleshoot problems or simply follow the list of transformations and tests performed by =autcross=. -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :prologue "exec 2>&1" :epilogue true randaut -B -n 1 a b --name="automaton %L" | autcross 'autfilt --complement' 'ltl2dstar --complement-input=yes' --verbose #+END_SRC -#+BEGIN_SRC sh :results verbatim :exports results -randaut -B -n 1 a b --name="automaton %L" | -autcross 'autfilt --complement' 'ltl2dstar --complement-input=yes' --verbose 2>&1 -#+END_SRC - #+RESULTS: #+begin_example -:1.1-46.7 automaton 0 info: input (10 st.,26 ed.,1 sets) -Running [A0]: autfilt --complement 'lcr-i0-oZm5P2'>'lcr-o0-O4P0IB' -Running [A1]: ltl2dstar --complement-input=yes -B 'lcr-i0-gEwlJa' 'lcr-o1-wSaHJJ' +Running [A0]: autfilt --complement 'lcr-i0-KHA9NI'>'lcr-o0-BSYDwC' +Running [A1]: ltl2dstar --complement-input=yes -B 'lcr-i0-DjL8hw' 'lcr-o1-PASD3p' info: collected automata: -info: A0 (27 st.,95 ed.,3 sets) deterministic complete +info: A0 (26 st.,91 ed.,5 sets) deterministic complete info: A1 (34 st.,121 ed.,6 sets) deterministic complete Performing sanity checks and gathering statistics... info: getting rid of any Fin acceptance... -info: A0 (27 st.,95 ed.,3 sets) -> (58 st.,203 ed.,2 sets) -info: Comp(A0) (27 st.,95 ed.,3 sets) -> (51 st.,188 ed.,1 sets) +info: A0 (26 st.,91 ed.,5 sets) -> (83 st.,287 ed.,2 sets) +info: Comp(A0) (26 st.,91 ed.,5 sets) -> (76 st.,281 ed.,3 sets) info: A1 (34 st.,121 ed.,6 sets) -> (64 st.,228 ed.,3 sets) info: Comp(A1) (34 st.,121 ed.,6 sets) -> (34 st.,121 ed.,1 sets) info: check_empty A0*Comp(A1) @@ -380,14 +389,6 @@ info: check_empty A1*Comp(A0) No problem detected. #+end_example -# LocalWords: utf autcross SETUPFILE html HOA neverclaim dstar's Nr -# LocalWords: autfilt dstar randaut lcr xZO urHakt mmkgH ABdm kMYrq -# LocalWords: kvBP lVlGfJ BexLFn rjvy rKKlxG Musr LyAxtZ shorthands -# LocalWords: COMMANDFMT seminator nba ldpa QHReWu eTOmZ jsoPPt ilV -# LocalWords: bQiY IubpMs dfmYfX NXLr zSwXhW bDOq og mUp QVurtU ap -# LocalWords: ok complementation Ai Aj gRqrd ubUpHb JxFi oQGbj SQT -# LocalWords: kWt Eo Xsc WXgCB vLwKMQ tI SXF qqlE KXplk ZFTCz PNY -# LocalWords: hUAK IjnFhD cWys ZqjdQh * Use-cases for =%M= If the input automata are named, it is possible to use =%M= in some @@ -404,70 +405,60 @@ LTL formula encoded in the name of the automaton). That LTL formula is not in a syntax supported by =ltl2dstar=, so we call =ltl2dstar= via [[file:ltldo.org][=ltldo=]] to arrange that. -#+BEGIN_SRC sh :results silent :export code +#+BEGIN_SRC sh :prologue "exec 2>&1" :epilogue true genltl --eh-patterns=1..3 | ltl2tgba | autcross 'autfilt -P -D' 'ltldo ltl2dstar -f %M >%O' #+END_SRC -#+BEGIN_SRC sh :results verbatim :export results -genltl --eh-patterns=1..3 | ltl2tgba | - autcross 'autfilt -P -D' 'ltldo ltl2dstar -f %M >%O' 2>&1 -#+END_SRC - #+RESULTS: #+begin_example -:1.1-16.7 p0 U (p1 & Gp2) -Running [A0]: autfilt -P -D 'lcr-i0-rBSCo9'>'lcr-o0-xyRJhy' -Running [A1]: ltldo ltl2dstar -f 'p0 U (p1 & Gp2)' >'lcr-o1-9uDUjX' +Running [A0]: autfilt -P -D 'lcr-i0-VyvQVJ'>'lcr-o0-fVtUyh' +Running [A1]: ltldo ltl2dstar -f 'p0 U (p1 & Gp2)' >'lcr-o1-4e57fP' Performing sanity checks and gathering statistics... -:17.1-34.7 p0 U (p1 & X(p2 U p3)) -Running [A0]: autfilt -P -D 'lcr-i1-LFDrvm'>'lcr-o0-6fBZGL' -Running [A1]: ltldo ltl2dstar -f 'p0 U (p1 & X(p2 U p3))' >'lcr-o1-AUXx0a' +Running [A0]: autfilt -P -D 'lcr-i1-cNgs1m'>'lcr-o0-MWSMMU' +Running [A1]: ltldo ltl2dstar -f 'p0 U (p1 & X(p2 U p3))' >'lcr-o1-2oVyBs' Performing sanity checks and gathering statistics... -:35.1-64.7 p0 U (p1 & X(p2 & F(p3 & XF(p4 & XF(p5 & XFp6))))) -Running [A0]: autfilt -P -D 'lcr-i2-UaZCtA'>'lcr-o0-hhbJWZ' -Running [A1]: ltldo ltl2dstar -f 'p0 U (p1 & X(p2 & F(p3 & XF(p4 & XF(p5 & XFp6)))))' >'lcr-o1-xhS4Ap' +Running [A0]: autfilt -P -D 'lcr-i2-Tgzsu0'>'lcr-o0-aOBmny' +Running [A1]: ltldo ltl2dstar -f 'p0 U (p1 & X(p2 & F(p3 & XF(p4 & XF(p5 & XFp6)))))' >'lcr-o1-Sg7al6' Performing sanity checks and gathering statistics... No problem detected. #+end_example -This example is a bit contrived, and in this case, an alternative would -be to use [[file:ltlcross.org][=ltlcross=]], as in: +The previous example was a bit contrived, and in this case, a saner +alternative would be to use [[file:ltlcross.org][=ltlcross=]], as in: -#+BEGIN_SRC sh :results silent :export code +#+BEGIN_SRC sh :prologue "exec 2>&1" :epilogue true genltl --eh-patterns=1..3 | ltlcross 'ltl2tgba %f | autfilt -P -D > %O' 'ltl2dstar' #+END_SRC -#+BEGIN_SRC sh :results verbatim :export results -genltl --eh-patterns=1..3 | - ltlcross 'ltl2tgba %f | autfilt -P -D > %O' 'ltl2dstar' 2>&1 -#+END_SRC - #+RESULTS: #+begin_example -:1: (p0) U ((p1) & (G(p2))) -Running [P0]: ltl2tgba '(p0) U ((p1) & (G(p2)))' | autfilt -P -D > 'lcr-o0-DnV1rm' -Running [P1]: ltl2dstar --output-format=hoa 'lcr-i0-jBLulv' 'lcr-o1-epwYeE' -Running [N0]: ltl2tgba '!((p0) U ((p1) & (G(p2))))' | autfilt -P -D > 'lcr-o0-8bVQ9M' -Running [N1]: ltl2dstar --output-format=hoa 'lcr-i0-5oAAdW' 'lcr-o1-W7elh5' +Running [P0]: ltl2tgba '(p0) U ((p1) & (G(p2)))' | autfilt -P -D > 'lcr-o0-6iPt1N' +Running [P1]: ltl2dstar --output-format=hoa 'lcr-i0-iZ22aA' 'lcr-o1-xyBCkm' +Running [N0]: ltl2tgba '!((p0) U ((p1) & (G(p2))))' | autfilt -P -D > 'lcr-o0-UL2Ju8' +Running [N1]: ltl2dstar --output-format=hoa 'lcr-i0-FyS5HU' 'lcr-o1-Xy3rVG' Performing sanity checks and gathering statistics... -:2: (p0) U ((p1) & (X((p2) U (p3)))) -Running [P0]: ltl2tgba '(p0) U ((p1) & (X((p2) U (p3))))' | autfilt -P -D > 'lcr-o0-xMdCve' -Running [P1]: ltl2dstar --output-format=hoa 'lcr-i1-OJU1Sn' 'lcr-o1-wOCsgx' -Running [N0]: ltl2tgba '!((p0) U ((p1) & (X((p2) U (p3)))))' | autfilt -P -D > 'lcr-o0-SzgmFG' -Running [N1]: ltl2dstar --output-format=hoa 'lcr-i1-8iIddQ' 'lcr-o1-zBV5KZ' +Running [P0]: ltl2tgba '(p0) U ((p1) & (X((p2) U (p3))))' | autfilt -P -D > 'lcr-o0-3veUbt' +Running [P1]: ltl2dstar --output-format=hoa 'lcr-i1-Rceyvf' 'lcr-o1-YXtcP1' +Running [N0]: ltl2tgba '!((p0) U ((p1) & (X((p2) U (p3)))))' | autfilt -P -D > 'lcr-o0-imCn9N' +Running [N1]: ltl2dstar --output-format=hoa 'lcr-i1-Q49LwA' 'lcr-o1-xF2aUm' Performing sanity checks and gathering statistics... -:3: (p0) U ((p1) & (X((p2) & (F((p3) & (X(F((p4) & (X(F((p5) & (X(F(p6)))))))))))))) -Running [P0]: ltl2tgba '(p0) U ((p1) & (X((p2) & (F((p3) & (X(F((p4) & (X(F((p5) & (X(F(p6))))))))))))))' | autfilt -P -D > 'lcr-o0-FEA6s9' -Running [P1]: ltl2dstar --output-format=hoa 'lcr-i2-E0Ikpj' 'lcr-o1-ppDzlt' -Running [N0]: ltl2tgba '!((p0) U ((p1) & (X((p2) & (F((p3) & (X(F((p4) & (X(F((p5) & (X(F(p6)))))))))))))))' | autfilt -P -D > 'lcr-o0-jqlelD' -Running [N1]: ltl2dstar --output-format=hoa 'lcr-i2-IwU1uN' 'lcr-o1-6YdQEX' +Running [P0]: ltl2tgba '(p0) U ((p1) & (X((p2) & (F((p3) & (X(F((p4) & (X(F((p5) & (X(F(p6))))))))))))))' | autfilt -P -D > 'lcr-o0-xdVyk9' +Running [P1]: ltl2dstar --output-format=hoa 'lcr-i2-UpeRPV' 'lcr-o1-4GM9kI' +Running [N0]: ltl2tgba '!((p0) U ((p1) & (X((p2) & (F((p3) & (X(F((p4) & (X(F((p5) & (X(F(p6)))))))))))))))' | autfilt -P -D > 'lcr-o0-J9yARu' +Running [N1]: ltl2dstar --output-format=hoa 'lcr-i2-1IDzrh' 'lcr-o1-Ck5y13' Performing sanity checks and gathering statistics... No problem detected. @@ -476,3 +467,16 @@ No problem detected. However in practice you could also use the =name:= field of the input automaton, combined with =%M= in the tool specification, to designate an alternate filename to load, or some key to look up somewhere. + +#+BEGIN_SRC sh :results silent :exports results +rm -f autcross.csv +#+END_SRC + +# LocalWords: utf autcross SETUPFILE html HOA neverclaim dstar's Nr +# LocalWords: autfilt dstar randaut lcr xZO urHakt mmkgH ABdm kMYrq +# LocalWords: kvBP lVlGfJ BexLFn rjvy rKKlxG Musr LyAxtZ shorthands +# LocalWords: COMMANDFMT seminator nba ldpa QHReWu eTOmZ jsoPPt ilV +# LocalWords: bQiY IubpMs dfmYfX NXLr zSwXhW bDOq og mUp QVurtU ap +# LocalWords: ok complementation Ai Aj gRqrd ubUpHb JxFi oQGbj SQT +# LocalWords: kWt Eo Xsc WXgCB vLwKMQ tI SXF qqlE KXplk ZFTCz PNY +# LocalWords: hUAK IjnFhD cWys ZqjdQh diff --git a/doc/org/autfilt.org b/doc/org/autfilt.org index 1dca632ae..be51cfcd5 100644 --- a/doc/org/autfilt.org +++ b/doc/org/autfilt.org @@ -3,6 +3,7 @@ #+DESCRIPTION: Spot command-line tool for filtering, tranforming, and converting ω-automata. #+INCLUDE: setup.org #+HTML_LINK_UP: tools.html +#+PROPERTY: header-args:sh :results verbatim :exports both The =autfilt= tool can filter, transform, and convert a stream of automata. @@ -32,7 +33,7 @@ By default the output uses the HOA format. This can be changed using [[file:oaut.org][the common output options]] like =--spin=, =--lbtt=, =--dot=, =--stats=... -#+BEGIN_SRC sh :results silent :exports both +#+BEGIN_SRC sh :results silent cat >example.hoa <aut-ex1.hoa<❶) & Fin() & Inf()) | (Inf()&Inf()) | Inf()> - 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
>] - 0 -> 1 [label=>] - 0 -> 2 [label=>] - 1 [label="1"] - 1 -> 0 [label=>] - 1 -> 1 [label=>] - 1 -> 2 [label=>] - 2 [label="2"] - 2 -> 0 [label=] - 2 -> 1 [label=>] - 2 -> 2 [label=>] -} -#+end_example - #+BEGIN_SRC dot :file autfilt-ex1.svg :var txt=autfilt-ex1 :exports results $txt #+END_SRC #+RESULTS: -[[file:autfilt-ex1.svgz]] +[[file:autfilt-ex1.svg]] Using =-S= will "push" the acceptance membership of the transitions to the states: #+NAME: autfilt-ex2 -#+BEGIN_SRC sh :results verbatim :exports code -autfilt -S aut-ex1.hoa --dot= +#+BEGIN_SRC sh +autfilt -S aut-ex1.hoa --dot #+END_SRC -#+RESULTS: autfilt-ex2 -#+begin_example -digraph G { - rankdir=LR - label=<(Fin() & Fin() & Inf()) | (Inf()&Inf()) | Inf()> - 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=<1>] - 0 -> 1 [label=
] - 0 -> 2 [label=] - 1 [label=<1
>] - 1 -> 0 [label=] - 1 -> 6 [label=
] - 1 -> 7 [label=] - 2 [label=<2
>] - 2 -> 3 [label=] - 2 -> 4 [label=
] - 2 -> 5 [label=] - 3 [label=<3>] - 3 -> 0 [label=<1>] - 3 -> 1 [label=] - 3 -> 2 [label=] - 4 [label=<4
>] - 4 -> 0 [label=] - 4 -> 6 [label=
] - 4 -> 7 [label=] - 5 [label=<5
>] - 5 -> 3 [label=] - 5 -> 4 [label=
] - 5 -> 5 [label=] - 6 [label=<6
>] - 6 -> 0 [label=] - 6 -> 6 [label=
] - 6 -> 7 [label=] - 7 [label=<7
>] - 7 -> 3 [label=] - 7 -> 4 [label=
] - 7 -> 5 [label=] -} -#+end_example - #+BEGIN_SRC dot :file autfilt-ex2.svg :var txt=autfilt-ex2 :exports results $txt #+END_SRC @@ -610,37 +593,10 @@ $txt Using =--cnf-acceptance= simply rewrites the acceptance condition in Conjunctive Normal Form: #+NAME: autfilt-ex3 -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh autfilt --cnf-acceptance aut-ex1.hoa --dot #+END_SRC -#+RESULTS: autfilt-ex3 -#+begin_example -digraph G { - rankdir=LR - label=<(Inf() | Inf() | Inf()) & (Fin() | Inf() | Inf())> - 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
>] - 0 -> 1 [label=>] - 0 -> 2 [label=>] - 1 [label="1"] - 1 -> 0 [label=>] - 1 -> 1 [label=
>] - 1 -> 2 [label=>] - 2 [label="2"] - 2 -> 0 [label=] - 2 -> 1 [label=>] - 2 -> 2 [label=>] -} -#+end_example - #+BEGIN_SRC dot :file autfilt-ex3.svg :var txt=autfilt-ex3 :exports results $txt #+END_SRC @@ -654,40 +610,10 @@ of Fin-acceptance: this usually requires adding non-deterministic jumps to altered copies of strongly-connected components. #+NAME: autfilt-ex4 -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh autfilt --remove-fin aut-ex1.hoa --dot #+END_SRC -#+RESULTS: autfilt-ex4 -#+begin_example -digraph G { - rankdir=LR - label=⓿) | Inf() | (Inf()&Inf())> - 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
>] - 0 -> 1 [label=>] - 0 -> 2 [label=>] - 1 [label="1"] - 1 -> 0 [label=>] - 1 -> 1 [label=
>] - 1 -> 2 [label=>] - 2 [label="2"] - 2 -> 0 [label=] - 2 -> 1 [label=] - 2 -> 2 [label=] - 2 -> 3 [label=] - 3 [label="3"] - 3 -> 3 [label=>] -} -#+end_example - #+BEGIN_SRC dot :file autfilt-ex4.svg :var txt=autfilt-ex4 :exports results $txt #+END_SRC @@ -700,35 +626,10 @@ transitions they contain. The acceptance condition will be updated to reflect the fact that these sets can never be visited. #+NAME: autfilt-ex5 -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh autfilt --mask-acc=1,2 aut-ex1.hoa --dot #+END_SRC -#+RESULTS: autfilt-ex5 -#+begin_example -digraph G { - rankdir=LR - label=❶) & Inf()> - 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
>] - 0 -> 1 [label=>] - 1 [label="1"] - 1 -> 0 [label=] - 1 -> 2 [label=
>] - 1 -> 1 [label=>] - 2 [label="2"] - 2 -> 0 [label=>] - 2 -> 2 [label=>] -} -#+end_example - #+BEGIN_SRC dot :file autfilt-ex5.svg :var txt=autfilt-ex5 :exports results $txt #+END_SRC @@ -737,6 +638,9 @@ $txt [[file:autfilt-ex5.svg]] ** Atomic proposition removal + :PROPERTIES: + :header-args:sh: :results verbatim :exports code + :END: Atomic propositions can be removed from an automaton in three ways: - use ~--remove-ap=a~ to remove =a= by existential quantification, i.e., both =a= and its negation will be replaced by true. @@ -747,37 +651,10 @@ Atomic propositions can be removed from an automaton in three ways: Here are the results of these three options on our example: #+NAME: autfilt-ex6a -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh autfilt --remove-ap=a aut-ex1.hoa --dot #+END_SRC -#+RESULTS: autfilt-ex6a -#+begin_example -digraph G { - rankdir=LR - label=<(Fin() & Fin() & Inf()) | (Inf()&Inf()) | Inf()> - 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
>] - 0 -> 1 [label=<1
>] - 0 -> 2 [label=<1
>] - 1 [label="1"] - 1 -> 0 [label=>] - 1 -> 1 [label=>] - 1 -> 2 [label=>] - 2 [label="2"] - 2 -> 0 [label=] - 2 -> 1 [label=>] - 2 -> 2 [label=>] -} -#+end_example - #+BEGIN_SRC dot :file autfilt-ex6a.svg :var txt=autfilt-ex6a :exports results $txt #+END_SRC @@ -786,31 +663,10 @@ $txt [[file:autfilt-ex6a.svg]] #+NAME: autfilt-ex6b -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh autfilt --remove-ap=a=0 aut-ex1.hoa --dot #+END_SRC -#+RESULTS: autfilt-ex6b -#+begin_example -digraph G { - rankdir=LR - label=<(Fin() & Fin() & Inf()) | (Inf()&Inf()) | Inf()> - 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
>] - 0 -> 1 [label=<1
>] - 1 [label="1"] - 1 -> 0 [label=] - 1 -> 1 [label=>] -} -#+end_example - #+BEGIN_SRC dot :file autfilt-ex6b.svg :var txt=autfilt-ex6b :exports results $txt #+END_SRC @@ -819,12 +675,10 @@ $txt [[file:autfilt-ex6b.svg]] #+NAME: autfilt-ex6c -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh autfilt --remove-ap=a=1 aut-ex1.hoa --dot #+END_SRC -#+RESULTS: autfilt-ex6c - #+BEGIN_SRC dot :file autfilt-ex6c.svg :var txt=autfilt-ex6c :exports results $txt #+END_SRC @@ -833,11 +687,15 @@ $txt [[file:autfilt-ex6c.svg]] ** Testing word acceptance + :PROPERTIES: + :header-args:sh: :results verbatim :exports both + :END: + The following example checks whether the formula ~a U b U c~ accepts the word ~a&!b&!c; cycle{!a&!b&c}~. -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltl2tgba 'a U b U c' | autfilt --accept-word 'a&!b&!c; cycle{!a&!b&c}' -q && echo "word accepted" #+END_SRC @@ -851,7 +709,7 @@ words =a&!b;cycle{!a&!b}= and =!a&!b;cycle{a&b}= yet reject any word of the form =cycle{b}=, and display the associated formula (which was stored as the name of the automaton by =ltl2tgba=). -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh randltl -n -1 a b | ltlfilt --simplify --uniq | ltl2tgba | autfilt --accept-word='a&!b;cycle{!a&!b}' --accept-word='!a&!b;cycle{a&b}' \ --reject-word='cycle{b}' --stats=%M -n 10 @@ -881,7 +739,7 @@ in a pipeline and preserve the formula name in the HOA output. For example Here is a list of 5 LTL formulas that =ltl2dstar= converts to Rabin automata that have exactly 4 states: -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh randltl -n -1 a b | ltlfilt --simplify --remove-wm | ltldo ltl2dstar --name=%f | autfilt --states=4 --stats=%M -n 5 #+END_SRC @@ -895,7 +753,7 @@ randltl -n -1 a b | ltlfilt --simplify --remove-wm | ** Decorations :PROPERTIES: - :CUSTOM_ID: decorations + :header-args:sh: :results verbatim :exports code :END: We know from a previous exemple that formula =a U b U c= accepts the @@ -903,7 +761,7 @@ word =b; cycle{c}=. We can actually highlight the corresponding run in the automaton: #+NAME: highlight-word -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh ltl2tgba 'a U b U c' | autfilt --highlight-word='a&!b&!c; cycle{!a&!b&c}' -d #+END_SRC @@ -945,7 +803,7 @@ transition may only have one color so late highlights will overwrite previous ones. #+NAME: highlight-word2 -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh ltl2tgba 'a U b U c' | autfilt --highlight-word=5,'a&!b&!c; cycle{!a&!b&c}' \ --highlight-word=4,'!a&b&!c; cycle{!a&!b&c}' -d @@ -989,40 +847,11 @@ highlight states or edges where nondeterministic choices need to be made. #+NAME: highlight-nondet -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh ltl2tgba 'F((b R a) W Gb)' | autfilt --highlight-nondet-states=5 --highlight-nondet-edges=1 -d #+END_SRC -#+RESULTS: highlight-nondet -#+begin_example -digraph G { - rankdir=LR - node [shape="circle"] - node [style="filled", fillcolor="#ffffa0"] - fontname="Lato" - node [fontname="Lato"] - edge [fontname="Lato"] - edge[arrowhead=vee, arrowsize=.7] - I [label="", style=invis, width=0] - I -> 1 - 0 [label="0"] - 0 -> 0 [label=>] - 1 [label="1", style="bold,filled", color="#F15854"] - 1 -> 0 [label=, style=bold, color="#5DA5DA"] - 1 -> 1 [label=<1>, style=bold, color="#5DA5DA"] - 1 -> 2 [label=
] - 1 -> 3 [label=] - 2 [label="2"] - 2 -> 0 [label=] - 2 -> 2 [label=>] - 2 -> 3 [label=>] - 3 [label="3"] - 3 -> 2 [label=>] - 3 -> 3 [label=>] -} -#+end_example - #+BEGIN_SRC dot :file autfilt-hlnondet.svg :var txt=highlight-nondet :exports results $txt #+END_SRC diff --git a/doc/org/compile.org b/doc/org/compile.org index 49bb4c9a6..7eaf6dae8 100644 --- a/doc/org/compile.org +++ b/doc/org/compile.org @@ -3,6 +3,7 @@ #+DESCRIPTION: How to compile C++14 programs using Spot #+INCLUDE: setup.org #+HTML_LINK_UP: tut.html +#+PROPERTY: header-args:C+++ :results verbatim :exports both This page is not about compiling Spot itself (for this, please refer to the [[file:install.org][installation instructions]]), but about how to compile and @@ -14,7 +15,7 @@ As an example we will take the following simple program, stored in a file called =hello.cc=: #+NAME: hello-word -#+BEGIN_SRC C++ :results verbatim :exports both +#+BEGIN_SRC C++ #include #include @@ -30,7 +31,7 @@ greetings and the Spot version: #+RESULTS: hello-word : Hello world! -: This is Spot 1.99.6a. +: This is Spot 2.7.2.dev. To successfully compile this example program, we need a C++ compiler, diff --git a/doc/org/concepts.org b/doc/org/concepts.org index 6fe52c5bb..a94433ce4 100644 --- a/doc/org/concepts.org +++ b/doc/org/concepts.org @@ -3,6 +3,7 @@ #+DESCRIPTION: Informal explanation of various concepts used in Spot. #+INCLUDE: setup.org #+HTML_LINK_UP: index.html +#+PROPERTY: header-args:sh :results verbatim :exports none This page documents some of the concepts used in Spot, and whose knowledge is usually assumed throughout the documentation. The @@ -128,7 +129,7 @@ For instance here is a Büchi automaton that accepts only words in which $a$ is always true, and $b$ is true infinitely often. #+NAME: buchi-example1 -#+BEGIN_SRC sh :results verbatim :exports none +#+BEGIN_SRC sh ltl2tgba 'G(a) & GF(b)' -B -d #+END_SRC @@ -149,7 +150,7 @@ the [[#ltl][LTL formula]] =G(door_open -> light_on)= that specifies that =light_on= should be true whenever =door_open= is true. #+NAME: buchi-example2 -#+BEGIN_SRC sh :results verbatim :exports none +#+BEGIN_SRC sh ltl2tgba 'G(door_open -> light_on)' -d -C #+END_SRC @@ -183,7 +184,7 @@ all runs in which at all point $a$ is true iff $b$ is true at the next instant. #+NAME: buchi-example3 -#+BEGIN_SRC sh :results verbatim :exports none +#+BEGIN_SRC sh ltl2tgba 'G(a <-> Xb)' -B -d #+END_SRC #+BEGIN_SRC dot :file concept-buchi3.svg :var txt=buchi-example3 :exports results @@ -210,7 +211,7 @@ have been aggregated in an edge. Here is a simple example: #+NAME: te1 -#+BEGIN_SRC sh :results verbatim :exports none +#+BEGIN_SRC sh cat >concept-te.hoa < Xb)=. #+NAME: concepts-alt -#+BEGIN_SRC sh :results verbatim :exports none +#+BEGIN_SRC sh autfilt -d.ba < tmp.$$ ltl2tgba -s6 'p0 | GFp1' | pr -w80 -m -t tmp.$$ - rm tmp.$$ @@ -665,7 +666,7 @@ accept_all: accept_all: #+end_example #+NAME: never-ex1 -#+BEGIN_SRC sh :results verbatim :exports none +#+BEGIN_SRC sh ltl2tgba -Bd 'p0 | GFp1' #+END_SRC #+BEGIN_SRC dot :file concept-never1.svg :var txt=never-ex1 :exports results @@ -697,7 +698,7 @@ LTL to (state-based) generalized Büchi automata, and then used by For instance the Büchi automaton we used as an example for never claims can be encoded as follows: -#+BEGIN_SRC sh :results verbatim :exports results +#+BEGIN_SRC sh :exports results ltl2tgba --ba --lbtt 'p0 | GFp1' #+END_SRC @@ -727,7 +728,7 @@ The format has been extended in two ways. First, LBTT extended it to support transition-based acceptance. This is indicated by a =t= on the first line: -#+BEGIN_SRC sh :results verbatim :exports results +#+BEGIN_SRC sh :exports results ltl2tgba --lbtt 'p0 | GFp1' #+END_SRC @@ -748,7 +749,7 @@ ltl2tgba --lbtt 'p0 | GFp1' #+end_example #+NAME: lbtt-ex2 -#+BEGIN_SRC sh :results verbatim :exports none +#+BEGIN_SRC sh ltl2tgba -d 'p0 | GFp1' #+END_SRC #+BEGIN_SRC dot :file concept-lbtt2.svg :var txt=lbtt-ex2 :exports results @@ -781,7 +782,7 @@ preferred. =ltl2dstar= can now also output HOA directly. Here is one Rabin automaton in the DSTAR format: -#+BEGIN_SRC sh :results verbatim :exports results +#+BEGIN_SRC sh :exports results echo '| F G p0 G F p1' | ltl2dstar --output-format=native - - #+END_SRC @@ -821,7 +822,7 @@ Acc-Sig: +0 +1 #+end_example #+NAME: dstar-example1 -#+BEGIN_SRC sh :results verbatim :exports none +#+BEGIN_SRC sh echo '| F G p0 G F p1' | ltl2dstar --output-format=native - - | autfilt -d #+END_SRC #+BEGIN_SRC dot :file concept-dstar.svg :var txt=dstar-example1 :exports results @@ -840,7 +841,7 @@ The [[http://adl.github.io/hoaf/][HOA format]] inherits several features from th extends it in many ways, including support for non-deterministic automata, alternating automata, and for arbitrary acceptance conditions. -#+BEGIN_SRC sh :results verbatim :exports results +#+BEGIN_SRC sh :exports results ltldo ltl2dstar -f 'FGp0 | GFp1' --name=%f #+END_SRC @@ -880,7 +881,7 @@ State: 3 {1 3} #+end_example #+NAME: hoa1 -#+BEGIN_SRC sh :results verbatim :exports none +#+BEGIN_SRC sh ltldo ltl2dstar -f 'FGp0 | GFp1' -d #+END_SRC #+BEGIN_SRC dot :file concept-hoa.svg :var txt=hoa1 :exports results @@ -994,7 +995,7 @@ automaton can then be simplified using several algorithms depending on what opti Here is for instance a translation of ={(1;1)[*]}[]->a= discussed [[#psl][above]]. #+NAME: ltl2tgba1 -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :exports code ltl2tgba '{(1;1)[*]}[]->a' -d #+END_SRC #+BEGIN_SRC dot :file concept-ltl2tgba.svg :var txt=ltl2tgba1 :exports results diff --git a/doc/org/csv.org b/doc/org/csv.org index b4de8e44a..bfb6fb689 100644 --- a/doc/org/csv.org +++ b/doc/org/csv.org @@ -3,6 +3,7 @@ #+DESCRIPTION: Examples showing how to read and write CSV files using Spot's command-line tools. #+INCLUDE: setup.org #+HTML_LINK_UP: tools.html +#+PROPERTY: header-args:sh :results verbatim :exports both This page discusses features available in Spot's command-line tools to produce an consume CSV files. @@ -17,7 +18,7 @@ For instance here is how we could use =genltl= to generate a CSV file with three columns: the family name of the formula, its parameter, and the formula itself. -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh genltl --and-gf=1..5 --u-left=1..5 --format='%F,%L,%f' > gen.csv cat gen.csv #+END_SRC @@ -45,7 +46,7 @@ For instance, the following command will translate all the previous formulas, and show the resulting number of states (=%s=) and edges (=%e=) of the automaton constructed for each formula. -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh genltl --and-gf=1..5 --u-left=1..5 | ltl2tgba --stats '%f,%s,%e' #+END_SRC #+RESULTS: @@ -66,7 +67,7 @@ If the translated formulas may contain commas, or double quotes, this simple output may prove difficult to process by other tools. For instance consider the translation of the following two formulas: -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltl2tgba -f Xa -f 'G("switch == on" -> F"tab[3,5] < 12")' --stats '%f,%s,%e' #+END_SRC #+RESULTS: @@ -77,7 +78,7 @@ The second line of this input does no conform to [[https://www.rfc-editor.org/rf non-escaped fields are not allowed to contain comma or double quotes. To fix this, simply double-quote the =%f= in the argument to =--stats=: -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltl2tgba -f Xa -f 'G("switch == on" -> F"tab[3,5] < 12")' --stats '"%f",%s,%e' #+END_SRC @@ -102,7 +103,7 @@ to support the specification of a CSV column. The notation For instance let's consider the file =gen.csv= built with the first command of this page. It contains: -#+BEGIN_SRC sh :results verbatim :exports results +#+BEGIN_SRC sh :exports results cat gen.csv #+END_SRC #+RESULTS: @@ -122,7 +123,7 @@ u-left,5,(((p1 U p2) U p3) U p4) U p5 We can run =ltl2tgba= on the third column to produce the same output as in a previous example: -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltl2tgba -F gen.csv/3 --stats '%f,%s,%e' #+END_SRC #+RESULTS: @@ -143,7 +144,7 @@ When =ltlfilt= is used on a CSV file, it will preserve the text before and after the matched formula in the CSV file. For instance: -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltlfilt -F gen.csv/3 --size-min=8 --relabel=abc #+END_SRC #+RESULTS: @@ -162,7 +163,7 @@ string. For instance this moves the first two columns after the formulas. -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltlfilt -F gen.csv/3 --size-min=8 --format='"%f",%<' #+END_SRC #+RESULTS: @@ -190,7 +191,7 @@ Typical uses of =ltlfilt= on CSV file include: Some CSV files contain a header lines that should not be processed. For instance the CSV files produced by =ltlcross= have such a line: -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh randltl -n 2 a b | ltlfilt --remove-wm | ltlcross --csv=results.csv 'ltl2tgba -s %f >%N' 'ltl3ba -f %s >%N' cat results.csv @@ -209,7 +210,7 @@ cat results.csv If we run =ltlfilt= on the first column, it will process the =formula= header as if it was an LTL formula. -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltlfilt -F results.csv/1 --format='%f' --unique #+END_SRC @@ -223,7 +224,7 @@ ltlfilt -F results.csv/1 --format='%f' --unique In such case, the syntax =FILENAME/-COL= (with a minus sign before the column number) can be used to discard the first line of a CSV file. -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltlfilt -F results.csv/-1 --format='%f' --unique #+END_SRC @@ -238,7 +239,7 @@ ltlfilt -F results.csv/-1 --format='%f' --unique The =--stats= option of tools that generate automata can be used to generate CSV files that embed automata. For instance -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh genltl --dac=1..3 | ltl2tgba --stats='"%f","%e edges","%h"' > csv-aut.csv cat csv-aut.csv #+END_SRC @@ -258,7 +259,7 @@ syntax we used previously, but by default it will just output the automata. If you want to preserve the entire line, you should use =%<= and =%>= in the =--stats= format. -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh autfilt csv-aut.csv/3 --states=2..3 --stats='%<,"%h"' #+END_SRC @@ -271,7 +272,7 @@ Another source of automata in CSV format is =ltlcross=. Using options =--automata= it will record the automata produced by each tool into the CSV file: -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh genltl --dac=1..3 | ltlcross --csv=result.csv --automata ltl2tgba cat result.csv #+END_SRC diff --git a/doc/org/dstar2tgba.org b/doc/org/dstar2tgba.org index f4f304ab3..dcd538931 100644 --- a/doc/org/dstar2tgba.org +++ b/doc/org/dstar2tgba.org @@ -3,6 +3,7 @@ #+DESCRIPTION: Spot command-line tool for converting automata into Transition-based Generalized Büchi Automata. #+INCLUDE: setup.org #+HTML_LINK_UP: tools.html +#+PROPERTY: header-args:sh :results verbatim :exports both This tool converts automata into transition-based generalized Büchi automata, a.k.a., TGBA. It can also produce Büchi automata on request @@ -35,85 +36,57 @@ The following command instructs =ltl2dstar= to: Additionally we use =ltlfilt= to convert our formula to the prefix format used by =ltl2dstar=. -#+BEGIN_SRC sh :results silent :exports both +#+BEGIN_SRC sh :results silent ltlfilt -f '(a U b) & GFb' -l | ltl2dstar --ltl2nba=spin:ltl2tgba@-Ds - fagfb #+END_SRC By looking at the file =fagfb= you can see the =ltl2dsar= actually produced a 4-state DRA: -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh cat fagfb #+END_SRC #+RESULTS: #+begin_example DRA v2 explicit -Comment: "Safra[NBA=3]" +Comment: "DBA2DRA[NBA=3]" States: 4 Acceptance-Pairs: 1 -Start: 2 +Start: 1 AP: 2 "a" "b" --- State: 0 -Acc-Sig: +0 -3 -3 +Acc-Sig: +0 +0 0 0 State: 1 -Acc-Sig: -0 -1 -1 -1 +Acc-Sig: +0 1 +3 +3 State: 2 Acc-Sig: -1 2 -0 -0 +2 +3 +3 State: 3 -Acc-Sig: +Acc-Sig: +0 +2 +2 3 3 -0 -0 #+end_example Let's display this automaton with =autfilt=: #+NAME: fagfb -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :exports code autfilt fagfb --dot #+END_SRC -#+RESULTS: fagfb -#+begin_example -digraph G { - rankdir=LR - label=⓿) & Inf()> - 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
>] - 0 -> 0 [label=] - 0 -> 3 [label=] - 1 [label=<1
>] - 1 -> 1 [label=<1>] - 2 [label=<2>] - 2 -> 0 [label=] - 2 -> 1 [label=] - 2 -> 2 [label=
] - 3 [label=<3>] - 3 -> 0 [label=] - 3 -> 3 [label=] -} -#+end_example - #+BEGIN_SRC dot :file fagfb.svg :var txt=fagfb :exports results $txt #+END_SRC @@ -127,31 +100,9 @@ a Monitor, using the same options as [[file:ltl2tgba.org][=ltl2tgba=]]. For instance here is the conversion to a Büchi automaton (=-B=): #+NAME: fagfb2ba -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :exports code dstar2tgba -B fagfb -d #+END_SRC -#+RESULTS: fagfb2ba -#+begin_example -digraph G { - rankdir=LR - node [shape="circle"] - fontname="Lato" - node [fontname="Lato"] - edge [fontname="Lato"] - node[style=filled, fillcolor="#ffffa0"] edge[arrowhead=vee, arrowsize=.7] - I [label="", style=invis, width=0] - I -> 1 - 0 [label="0", peripheries=2] - 0 -> 0 [label=] - 0 -> 2 [label=] - 1 [label="1"] - 1 -> 0 [label=] - 1 -> 1 [label=] - 2 [label="2"] - 2 -> 0 [label=] - 2 -> 2 [label=] -} -#+end_example #+BEGIN_SRC dot :file fagfb2ba.svg :var txt=fagfb2ba :exports results $txt @@ -165,7 +116,7 @@ a complete automaton. But we could as well require the output as a never claim for Spin (option =-s=): -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh dstar2tgba -s fagfb #+END_SRC #+RESULTS: @@ -173,18 +124,18 @@ dstar2tgba -s fagfb never { T0_init: if - :: (b) -> goto accept_S0 :: ((a) && (!(b))) -> goto T0_init + :: (b) -> goto accept_S2 fi; -accept_S0: +T0_S1: if - :: (b) -> goto accept_S0 - :: (!(b)) -> goto T0_S2 + :: (!(b)) -> goto T0_S1 + :: (b) -> goto accept_S2 fi; -T0_S2: +accept_S2: if - :: (b) -> goto accept_S0 - :: (!(b)) -> goto T0_S2 + :: (!(b)) -> goto T0_S1 + :: (b) -> goto accept_S2 fi; } #+end_example @@ -197,7 +148,7 @@ T0_S2: Here is the translation of =GFa | GFb= to a 4-state Streett automaton: #+NAME: gfafgb -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :exports code ltlfilt -f 'GFa & GFb' -l | ltl2dstar --automata=streett --ltl2nba=spin:ltl2tgba@-Ds - gfagfb autfilt --dot gfagfb #+END_SRC @@ -214,30 +165,9 @@ $txt And now its conversion by =dstar2tgba= to a 1-state TGBA. #+NAME: gfagfb2ba -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :exports code dstar2tgba gfagfb -d #+END_SRC -#+RESULTS: gfagfb2ba -#+begin_example -digraph "" { - rankdir=LR - label=⓿)&Inf()
[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=] - 0 -> 0 [label=>] - 0 -> 0 [label=
>] - 0 -> 0 [label=>] -} -#+end_example #+BEGIN_SRC dot :file gfagfb2ba.svg :var txt=gfagfb2ba :exports results $txt @@ -267,7 +197,7 @@ The last two steps are shared with =ltl2tgba= and use the same options. The type of automaton to produce can be selected using the =-B= or =-M= switches: -#+BEGIN_SRC sh :results verbatim :exports results +#+BEGIN_SRC sh :exports results dstar2tgba --help | sed -n '/Output automaton type:/,/^$/p' | sed '1d;$d' #+END_SRC @@ -283,7 +213,7 @@ dstar2tgba --help | sed -n '/Output automaton type:/,/^$/p' | sed '1d;$d' And these may be refined by a simplification goal, should the post-processor routine had a choice to make: -#+BEGIN_SRC sh :results verbatim :exports results +#+BEGIN_SRC sh :exports results dstar2tgba --help | sed -n '/Simplification goal:/,/^$/p' | sed '1d;$d' #+END_SRC #+RESULTS: @@ -295,7 +225,7 @@ dstar2tgba --help | sed -n '/Simplification goal:/,/^$/p' | sed '1d;$d' The effort put into post-processing can be limited with the =--low= or =--medium= options: -#+BEGIN_SRC sh :results verbatim :exports results +#+BEGIN_SRC sh :exports results dstar2tgba --help | sed -n '/Simplification level:/,/^$/p' | sed '1d;$d' #+END_SRC #+RESULTS: @@ -308,7 +238,7 @@ should you find =dstar2tgba= too slow. Finally, the output format can be changed with the following [[file:oaut.org][common ouput options]]: -#+BEGIN_SRC sh :results verbatim :exports results +#+BEGIN_SRC sh :exports results dstar2tgba --help | sed -n '/Output format:/,/^$/p' | sed '1d;$d' #+END_SRC #+RESULTS: @@ -377,7 +307,7 @@ of the input (Rabin) automaton, =%s=, the number of states of the output (Büchi) automaton, =%d=, whether the output automaton is deterministic, and =%p= whether the automaton is complete. -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh randltl -n -1 --tree-size=10..14 a b c | ltlfilt --remove-wm -r -u --size-min=3 -n 10 | while read f; do @@ -392,20 +322,20 @@ done #+begin_example (b | Fa) R Fc DRA: 9st.; BA: 9st.; det.? 1; complete? 1 -Ga U (Gc R (!a | Gc)) +Ga U G(!a | Gc) DRA: 7st.; BA: 7st.; det.? 0; complete? 0 GFc - DRA: 3st.; BA: 3st.; det.? 1; complete? 1 + DRA: 2st.; BA: 2st.; det.? 1; complete? 1 !a | (a R b) DRA: 3st.; BA: 2st.; det.? 1; complete? 0 -Xc R (G!c R (b | G!c)) - DRA: 4st.; BA: 2st.; det.? 1; complete? 0 +Xc R G(b | G!c) + DRA: 3st.; BA: 2st.; det.? 1; complete? 0 c & G(b | F(a & c)) DRA: 4st.; BA: 3st.; det.? 1; complete? 0 XXFc DRA: 4st.; BA: 4st.; det.? 1; complete? 1 XFc | Gb - DRA: 5st.; BA: 4st.; det.? 1; complete? 1 + DRA: 4st.; BA: 4st.; det.? 1; complete? 1 G(((!a & Gc) | (a & F!c)) U (!a | Ga)) DRA: 6st.; BA: 5st.; det.? 1; complete? 1 a & !b diff --git a/doc/org/genaut.org b/doc/org/genaut.org index 6dc9606f4..a4408704e 100644 --- a/doc/org/genaut.org +++ b/doc/org/genaut.org @@ -3,13 +3,14 @@ #+DESCRIPTION: Spot command-line tool that generates ω-automata from known patterns #+INCLUDE: setup.org #+HTML_LINK_UP: tools.html +#+PROPERTY: header-args:sh :results verbatim :exports both This tool outputs ω-automata generated from scalable patterns. These patterns are usually taken from the literature (see the [[./man/genaut.1.html][=genaut=]](1) man page for references). -#+BEGIN_SRC sh :results verbatim :exports results +#+BEGIN_SRC sh :exports results genaut --help | sed -n '/Pattern selection:/,/^$/p' | sed '1d;$d' #+END_SRC @@ -19,9 +20,9 @@ genaut --help | sed -n '/Pattern selection:/,/^$/p' | sed '1d;$d' : has at least 2^N/(2N+1) states. : --l-dsa=RANGE A deterministic Streett automaton with 4N states : with no equivalent deterministic Rabin automaton -: of less than n! states. +: of less than N! states. : --l-nba=RANGE A Büchi automaton with 3N+1 states whose -: complementary Streett automaton needs at least n! +: complementary Streett automaton needs at least N! : states. @@ -30,7 +31,7 @@ By default, the output format is [[file:hoa.org][HOA]], but this can be controll For instance: #+NAME: kscobuchi2 -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :exports code genaut --ks-nca=2 --dot #+END_SRC diff --git a/doc/org/genltl.org b/doc/org/genltl.org index 05ee72db8..55d836cdb 100644 --- a/doc/org/genltl.org +++ b/doc/org/genltl.org @@ -3,6 +3,7 @@ #+DESCRIPTION: Spot command-line tool that generates LTL formulas from known patterns #+INCLUDE: setup.org #+HTML_LINK_UP: tools.html +#+PROPERTY: header-args:sh :results verbatim :exports both This tool outputs LTL formulas that either comes from named lists of formulas, or from scalable patterns. @@ -12,7 +13,7 @@ These patterns are usually taken from the literature (see the given different names in different papers, so we alias different option names to the same pattern. -#+BEGIN_SRC sh :results verbatim :exports results +#+BEGIN_SRC sh :exports results genltl --help | sed -n '/Pattern selection:/,/^$/p' | sed '1d;$d' #+END_SRC #+RESULTS: @@ -32,10 +33,16 @@ genltl --help | sed -n '/Pattern selection:/,/^$/p' | sed '1d;$d' (range should be included in 1..55) --eh-patterns[=RANGE] Etessami and Holzmann [Concur'00] patterns (range should be included in 1..12) + --fxg-or=RANGE F(p0 | XG(p1 | XG(p2 | ... XG(pn)))) + --gf-equiv=RANGE (GFa1 & GFa2 & ... & GFan) <-> GFz + --gf-equiv-xn=RANGE GF(a <-> X^n(a)) + --gf-implies=RANGE (GFa1 & GFa2 & ... & GFan) -> GFz + --gf-implies-xn=RANGE GF(a -> X^n(a)) --gh-q=RANGE (F(p1)|G(p2))&(F(p2)|G(p3))&...&(F(pn)|G(p{n+1})) --gh-r=RANGE (GF(p1)|FG(p2))&(GF(p2)|FG(p3))&... &(GF(pn)|FG(p{n+1})) --go-theta=RANGE !((GF(p1)&GF(p2)&...&GF(pn)) -> G(q->F(r))) + --gxf-and=RANGE G(p0 & XF(p1 & XF(p2 & ... XF(pn)))) --hkrss-patterns[=RANGE], --liberouter-patterns[=RANGE] Holeček et al. patterns from the Liberouter project (range should be included in 1..55) @@ -43,11 +50,19 @@ genltl --help | sed -n '/Pattern selection:/,/^$/p' | sed '1d;$d' --kr-nlogn=RANGE quasilinear formula with doubly exponential DBA --kv-psi=RANGE, --kr-n2=RANGE quadratic formula with doubly exponential DBA + --ms-example=RANGE[,RANGE] + GF(a1&X(a2&X(a3&...Xan)))&F(b1&F(b2&F(b3&...&Xbm))) + --ms-phi-h=RANGE FG(a|b)|FG(!a|Xb)|FG(a|XXb)|FG(!a|XXXb)|... + --ms-phi-r=RANGE (FGa{n}&GFb{n})|((FGa{n-1}|GFb{n-1})&(...)) + --ms-phi-s=RANGE (FGa{n}|GFb{n})&((FGa{n-1}&GFb{n-1})|(...)) --or-fg=RANGE, --ccj-xi=RANGE FG(p1)|FG(p2)|...|FG(pn) --or-g=RANGE, --gh-s=RANGE G(p1)|G(p2)|...|G(pn) --or-gf=RANGE, --gh-c1=RANGE GF(p1)|GF(p2)|...|GF(pn) + --p-patterns[=RANGE], --beem-patterns[=RANGE], --p[=RANGE] + Pelánek [Spin'07] patterns from BEEM (range + should be included in 1..20) --r-left=RANGE (((p1 R p2) R p3) ... R pn) --r-right=RANGE (p1 R (p2 R (... R pn))) --rv-counter=RANGE n-bit counter @@ -57,6 +72,12 @@ genltl --help | sed -n '/Pattern selection:/,/^$/p' | sed '1d;$d' --rv-counter-linear=RANGE n-bit counter (linear size) --sb-patterns[=RANGE] Somenzi and Bloem [CAV'00] patterns (range should be included in 1..27) + --sejk-f=RANGE[,RANGE] f(0,j)=(GFa0 U X^j(b)), f(i,j)=(GFai U + G(f(i-1,j))) + --sejk-j=RANGE (GFa1&...&GFan) -> (GFb1&...&GFbn) + --sejk-k=RANGE (GFa1|FGb1)&...&(GFan|FGbn) + --sejk-patterns[=RANGE] φ₁,φ₂,φ₃ from Sikert et al's [CAV'16] + paper (range should be included in 1..3) --tv-f1=RANGE G(p -> (q | Xq | ... | XX...Xq) --tv-f2=RANGE G(p -> (q | X(q | X(... | Xq))) --tv-g1=RANGE G(p -> (q & Xq & ... & XX...Xq) @@ -70,7 +91,7 @@ genltl --help | sed -n '/Pattern selection:/,/^$/p' | sed '1d;$d' An example is probably all it takes to understand how this tool works: -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh genltl --and-gf=1..5 --u-left=1..5 #+END_SRC #+RESULTS: @@ -94,7 +115,7 @@ For instance here is the same formulas, but formatted in a way that is suitable for being included in a LaTeX table. -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh genltl --and-gf=1..5 --u-left=1..5 --latex --format='%F & %L & $%f$ \\' #+END_SRC #+RESULTS: @@ -115,19 +136,19 @@ Note that for the =--lbt= syntax, each formula is relabeled using =p0=, =p1=, ... before it is output, when the pattern (like =--ccj-alpha=) use different names. Compare: -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh genltl --ccj-alpha=3 #+END_SRC #+RESULTS: -: F(F(Fq3 & q2) & q1) & F(F(Fp3 & p2) & p1) +: F(p1 & F(p2 & Fp3)) & F(q1 & F(q2 & Fq3)) with -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh genltl --ccj-alpha=3 --lbt #+END_SRC #+RESULTS: -: & F & p2 F & p1 F p0 F & F & F p3 p4 p5 +: & F & p0 F & p1 F p2 F & p3 F & p4 F p5 This is because most tools using =lbt='s syntax require atomic propositions to have the form =pNN=. @@ -140,181 +161,181 @@ and =--sb-patterns=. With these options, the range is used to select a subset of the list of formulas. Without range, all formulas are used. Here is the complete list: -#+BEGIN_SRC sh :results verbatim :exports both - genltl --dac --eh --hkrss --p --sb --format=%F:%L,%f +#+BEGIN_SRC sh + genltl --dac --eh --hkrss --p --sb --format='%F=%L,%f' #+END_SRC #+RESULTS: #+begin_example -dac-patterns:1,G!p0 -dac-patterns:2,Fp0 -> (!p1 U p0) -dac-patterns:3,G(p0 -> G!p1) -dac-patterns:4,G((p0 & !p1 & Fp1) -> (!p2 U p1)) -dac-patterns:5,G((p0 & !p1) -> (!p2 W p1)) -dac-patterns:6,Fp0 -dac-patterns:7,!p0 W (!p0 & p1) -dac-patterns:8,G!p0 | F(p0 & Fp1) -dac-patterns:9,G((p0 & !p1) -> (!p1 W (!p1 & p2))) -dac-patterns:10,G((p0 & !p1) -> (!p1 U (!p1 & p2))) -dac-patterns:11,!p0 W (p0 W (!p0 W (p0 W G!p0))) -dac-patterns:12,Fp0 -> ((!p0 & !p1) U (p0 | ((!p0 & p1) U (p0 | ((!p0 & !p1) U (p0 | ((!p0 & p1) U (p0 | (!p1 U p0))))))))) -dac-patterns:13,Fp0 -> (!p0 U (p0 & (!p1 W (p1 W (!p1 W (p1 W G!p1)))))) -dac-patterns:14,G((p0 & Fp1) -> ((!p1 & !p2) U (p1 | ((!p1 & p2) U (p1 | ((!p1 & !p2) U (p1 | ((!p1 & p2) U (p1 | (!p2 U p1)))))))))) -dac-patterns:15,G(p0 -> ((!p1 & !p2) U (p2 | ((p1 & !p2) U (p2 | ((!p1 & !p2) U (p2 | ((p1 & !p2) U (p2 | (!p1 W p2) | Gp1))))))))) -dac-patterns:16,Gp0 -dac-patterns:17,Fp0 -> (p1 U p0) -dac-patterns:18,G(p0 -> Gp1) -dac-patterns:19,G((p0 & !p1 & Fp1) -> (p2 U p1)) -dac-patterns:20,G((p0 & !p1) -> (p2 W p1)) -dac-patterns:21,!p0 W p1 -dac-patterns:22,Fp0 -> (!p1 U (p0 | p2)) -dac-patterns:23,G!p0 | F(p0 & (!p1 W p2)) -dac-patterns:24,G((p0 & !p1 & Fp1) -> (!p2 U (p1 | p3))) -dac-patterns:25,G((p0 & !p1) -> (!p2 W (p1 | p3))) -dac-patterns:26,G(p0 -> Fp1) -dac-patterns:27,Fp0 -> ((p1 -> (!p0 U (!p0 & p2))) U p0) -dac-patterns:28,G(p0 -> G(p1 -> Fp2)) -dac-patterns:29,G((p0 & !p1 & Fp1) -> ((p2 -> (!p1 U (!p1 & p3))) U p1)) -dac-patterns:30,G((p0 & !p1) -> ((p2 -> (!p1 U (!p1 & p3))) W p1)) -dac-patterns:31,Fp0 -> (!p0 U (!p0 & p1 & X(!p0 U p2))) -dac-patterns:32,Fp0 -> (!p1 U (p0 | (!p1 & p2 & X(!p1 U p3)))) -dac-patterns:33,G!p0 | (!p0 U ((p0 & Fp1) -> (!p1 U (!p1 & p2 & X(!p1 U p3))))) -dac-patterns:34,G((p0 & Fp1) -> (!p2 U (p1 | (!p2 & p3 & X(!p2 U p4))))) -dac-patterns:35,G(p0 -> (Fp1 -> (!p1 U (p2 | (!p1 & p3 & X(!p1 U p4)))))) -dac-patterns:36,F(p0 & XFp1) -> (!p0 U p2) -dac-patterns:37,Fp0 -> (!(!p0 & p1 & X(!p0 U (!p0 & p2))) U (p0 | p3)) -dac-patterns:38,G!p0 | (!p0 U (p0 & (F(p1 & XFp2) -> (!p1 U p3)))) -dac-patterns:39,G((p0 & Fp1) -> (!(!p1 & p2 & X(!p1 U (!p1 & p3))) U (p1 | p4))) -dac-patterns:40,G(p0 -> ((!(!p1 & p2 & X(!p1 U (!p1 & p3))) U (p1 | p4)) | G!(p2 & XFp3))) -dac-patterns:41,G((p0 & XFp1) -> XF(p1 & Fp2)) -dac-patterns:42,Fp0 -> (((p1 & X(!p0 U p2)) -> X(!p0 U (p2 & Fp3))) U p0) -dac-patterns:43,G(p0 -> G((p1 & XFp2) -> X(!p2 U (p2 & Fp3)))) -dac-patterns:44,G((p0 & Fp1) -> (((p2 & X(!p1 U p3)) -> X(!p1 U (p3 & Fp4))) U p1)) -dac-patterns:45,G(p0 -> (((p1 & X(!p2 U p3)) -> X(!p2 U (p3 & Fp4))) U (p2 | G((p1 & X(!p2 U p3)) -> X(!p2 U (p3 & Fp4)))))) -dac-patterns:46,G(p0 -> F(p1 & XFp2)) -dac-patterns:47,Fp0 -> ((p1 -> (!p0 U (!p0 & p2 & X(!p0 U p3)))) U p0) -dac-patterns:48,G(p0 -> G(p1 -> (p2 & XFp3))) -dac-patterns:49,G((p0 & Fp1) -> ((p2 -> (!p1 U (!p1 & p3 & X(!p1 U p4)))) U p1)) -dac-patterns:50,G(p0 -> ((p1 -> (!p2 U (!p2 & p3 & X(!p2 U p4)))) U (p2 | G(p1 -> (p3 & XFp4))))) -dac-patterns:51,G(p0 -> F(p1 & !p2 & X(!p2 U p3))) -dac-patterns:52,Fp0 -> ((p1 -> (!p0 U (!p0 & p2 & !p3 & X((!p0 & !p3) U p4)))) U p0) -dac-patterns:53,G(p0 -> G(p1 -> (p2 & !p3 & X(!p3 U p4)))) -dac-patterns:54,G((p0 & Fp1) -> ((p2 -> (!p1 U (!p1 & p3 & !p4 & X((!p1 & !p4) U p5)))) U p1)) -dac-patterns:55,G(p0 -> ((p1 -> (!p2 U (!p2 & p3 & !p4 & X((!p2 & !p4) U p5)))) U (p2 | G(p1 -> (p3 & !p4 & X(!p4 U p5)))))) -eh-patterns:1,p0 U (p1 & Gp2) -eh-patterns:2,p0 U (p1 & X(p2 U p3)) -eh-patterns:3,p0 U (p1 & X(p2 & F(p3 & XF(p4 & XF(p5 & XFp6))))) -eh-patterns:4,F(p0 & XGp1) -eh-patterns:5,F(p0 & X(p1 & XFp2)) -eh-patterns:6,F(p0 & X(p1 U p2)) -eh-patterns:7,FGp0 | GFp1 -eh-patterns:8,G(p0 -> (p1 U p2)) -eh-patterns:9,G(p0 & XF(p1 & XF(p2 & XFp3))) -eh-patterns:10,GFp0 & GFp1 & GFp2 & GFp3 & GFp4 -eh-patterns:11,(p0 U (p1 U p2)) | (p1 U (p2 U p0)) | (p2 U (p0 U p1)) -eh-patterns:12,G(p0 -> (p1 U (Gp2 | Gp3))) -hkrss-patterns:1,G(Fp0 & F!p0) -hkrss-patterns:2,GFp0 & GF!p0 -hkrss-patterns:3,GF(!(p1 <-> Xp1) | !(p0 <-> Xp0)) -hkrss-patterns:4,GF(!(p1 <-> Xp1) | !(p0 <-> Xp0) | !(p2 <-> Xp2) | !(p3 <-> Xp3)) -hkrss-patterns:5,G!p0 -hkrss-patterns:6,G((p0 -> F!p0) & (!p0 -> Fp0)) -hkrss-patterns:7,G(p0 -> F(p0 & p1)) -hkrss-patterns:8,G(p0 -> F((!p0 & p1 & p2 & p3) -> Fp4)) -hkrss-patterns:9,G(p0 -> F!p1) -hkrss-patterns:10,G(p0 -> Fp1) -hkrss-patterns:11,G(p0 -> F(p1 -> Fp2)) -hkrss-patterns:12,G(p0 -> F((p1 & p2) -> Fp3)) -hkrss-patterns:13,G((p0 -> Fp1) & (p2 -> Fp3) & (p4 -> Fp5) & (p6 -> Fp7)) -hkrss-patterns:14,G(!p0 & !p1) -hkrss-patterns:15,G!(p0 & p1) -hkrss-patterns:16,G(p0 -> p1) -hkrss-patterns:17,G((p0 -> !p1) & (p1 -> !p0)) -hkrss-patterns:18,G(!p0 -> (p1 <-> !p2)) -hkrss-patterns:19,G((!p0 & (p1 | p2 | p3)) -> p4) -hkrss-patterns:20,G((p0 & p1) -> (p2 | !(p3 & p4))) -hkrss-patterns:21,G((!p0 & p1 & !p2 & !p3 & !p4) -> F(!p5 & !p6 & !p7 & !p8)) -hkrss-patterns:22,G((p0 & p1 & !p2 & !p3 & !p4) -> F(p5 & !p6 & !p7 & !p8)) -hkrss-patterns:23,G(!p0 -> !(p1 & p2 & p3 & p4 & p5)) -hkrss-patterns:24,G(!p0 -> ((p1 & p2 & p3 & p4) -> !p5)) -hkrss-patterns:25,G((p0 & p1) -> (p2 | p3 | !(p4 & p5))) -hkrss-patterns:26,G((!p0 & (p1 | p2 | p3 | p4)) -> (!p5 <-> p6)) -hkrss-patterns:27,G((p0 & p1) -> (p2 | p3 | p4 | !(p5 & p6))) -hkrss-patterns:28,G((p0 & p1) -> (p2 | p3 | p4 | p5 | !(p6 & p7))) -hkrss-patterns:29,G((p0 & p1 & !p2 & Xp2) -> X(p3 | X(!p1 | p3))) -hkrss-patterns:30,G((p0 & p1 & !p2 & Xp2) -> X(X!p1 | (p2 U (!p2 U (p2 U (!p1 | p3)))))) -hkrss-patterns:31,G(p0 & p1 & !p2 & Xp2) -> X(X!p1 | (p2 U (!p2 U (p2 U (!p1 | p3))))) -hkrss-patterns:32,G(p0 -> (p1 U (!p1 U (!p2 | p3)))) -hkrss-patterns:33,G(p0 -> (p1 U (!p1 U (p2 | p3)))) -hkrss-patterns:34,G((!p0 & p1) -> Xp2) -hkrss-patterns:35,G(p0 -> X(p0 | p1)) -hkrss-patterns:36,G((!(p1 <-> Xp1) | !(p0 <-> Xp0) | !(p2 <-> Xp2) | !(p3 <-> Xp3)) -> (X!p4 & X(!(!(p1 <-> Xp1) | !(p0 <-> Xp0) | !(p2 <-> Xp2) | !(p3 <-> Xp3)) U p4))) -hkrss-patterns:37,G((p0 & !p1 & Xp1 & Xp0) -> (p2 -> Xp3)) -hkrss-patterns:38,G(p0 -> X(!p0 U p1)) -hkrss-patterns:39,G((!p0 & Xp0) -> X((p0 U p1) | Gp0)) -hkrss-patterns:40,G((!p0 & Xp0) -> X(p0 U (p0 & !p1 & X(p0 & p1)))) -hkrss-patterns:41,G((!p0 & Xp0) -> X(p0 U (p0 & !p1 & X(p0 & p1 & (p0 U (p0 & !p1 & X(p0 & p1))))))) -hkrss-patterns:42,G((p0 & X!p0) -> X(!p0 U (!p0 & !p1 & X(!p0 & p1 & (!p0 U (!p0 & !p1 & X(!p0 & p1))))))) -hkrss-patterns:43,G((p0 & X!p0) -> X(!p0 U (!p0 & !p1 & X(!p0 & p1 & (!p0 U (!p0 & !p1 & X(!p0 & p1 & (!p0 U (!p0 & !p1 & X(!p0 & p1)))))))))) -hkrss-patterns:44,G((!p0 & Xp0) -> X(!(!p0 & Xp0) U (!p1 & Xp1))) -hkrss-patterns:45,G(!p0 | X(!p0 | X(!p0 | X(!p0 | X(!p0 | X(!p0 | X(!p0 | X(!p0 | X(!p0 | X(!p0 | X(!p0 | X!p0))))))))))) -hkrss-patterns:46,G((Xp0 -> p0) -> (p1 <-> Xp1)) -hkrss-patterns:47,G((Xp0 -> p0) -> ((p1 -> Xp1) & (!p1 -> X!p1))) -hkrss-patterns:48,!p0 U G!((p1 & p2) | (p3 & p4) | (p2 & p3) | (p2 & p4) | (p1 & p4) | (p1 & p3)) -hkrss-patterns:49,!p0 U p1 -hkrss-patterns:50,(p0 U p1) | Gp0 -hkrss-patterns:51,p0 & XG!p0 -hkrss-patterns:52,XG(p0 -> (G!p1 | (!Xp1 U p2))) -hkrss-patterns:53,XG((p0 & !p1) -> (G!p1 | (!p1 U p2))) -hkrss-patterns:54,XG((p0 & p1) -> ((p1 U p2) | Gp1)) -hkrss-patterns:55,Xp0 & G((!p0 & Xp0) -> XXp0) -p-patterns:1,G(p0 -> Fp1) -p-patterns:2,(GFp1 & GFp0) -> GFp2 -p-patterns:3,G(p0 -> (p1 & (p2 U p3))) -p-patterns:4,F(p0 | p1) -p-patterns:5,GF(p0 | p1) -p-patterns:6,(p0 U p1) -> ((p2 U p3) | Gp2) -p-patterns:7,G(p0 -> (!p1 U (p1 U (!p1 & (p2 R !p1))))) -p-patterns:8,G(p0 -> (p1 R !p2)) -p-patterns:9,G(!p0 -> Fp0) -p-patterns:10,G(p0 -> F(p1 | p2)) -p-patterns:11,!(!(p0 | p1) U p2) & G(p3 -> !(!(p0 | p1) U p2)) -p-patterns:12,G!p0 -> G!p1 -p-patterns:13,G(p0 -> (G!p1 | (!p2 U p1))) -p-patterns:14,G(p0 -> (p1 R (p1 | !p2))) -p-patterns:15,G((p0 & p1) -> (!p1 R (p0 | !p1))) -p-patterns:16,G(p0 -> F(p1 & p2)) -p-patterns:17,G(p0 -> (!p1 U (p1 U (p1 & p2)))) -p-patterns:18,G(p0 -> (!p1 U (p1 U (!p1 U (p1 U (p1 & p2)))))) -p-patterns:19,GFp0 -> GFp1 -p-patterns:20,GF(p0 | p1) & GF(p1 | p2) -sb-patterns:1,p0 U p1 -sb-patterns:2,p0 U (p1 U p2) -sb-patterns:3,!(p0 U (p1 U p2)) -sb-patterns:4,GFp0 -> GFp1 -sb-patterns:5,Fp0 U Gp1 -sb-patterns:6,Gp0 U p1 -sb-patterns:7,!(Fp0 <-> Fp1) -sb-patterns:8,!(GFp0 -> GFp1) -sb-patterns:9,!(GFp0 <-> GFp1) -sb-patterns:10,p0 R (p0 | p1) -sb-patterns:11,(Xp0 U Xp1) | !X(p0 U p1) -sb-patterns:12,(Xp0 U p1) | !X(p0 U (p0 & p1)) -sb-patterns:13,G(p0 -> Fp1) & ((Xp0 U p1) | !X(p0 U (p0 & p1))) -sb-patterns:14,G(p0 -> Fp1) & ((Xp0 U Xp1) | !X(p0 U p1)) -sb-patterns:15,G(p0 -> Fp1) -sb-patterns:16,!G(p0 -> X(p1 R p2)) -sb-patterns:17,!(FGp0 | FGp1) -sb-patterns:18,G(Fp0 & Fp1) -sb-patterns:19,Fp0 & F!p0 -sb-patterns:20,(p0 & Xp1) R X(((p2 U p3) R p0) U (p2 R p0)) -sb-patterns:21,Gp2 | (G(p0 | GFp1) & G(p2 | GF!p1)) | Gp0 -sb-patterns:22,Gp0 | Gp2 | (G(p0 | FGp1) & G(p2 | FG!p1)) -sb-patterns:23,!(Gp2 | (G(p0 | GFp1) & G(p2 | GF!p1)) | Gp0) -sb-patterns:24,!(Gp0 | Gp2 | (G(p0 | FGp1) & G(p2 | FG!p1))) -sb-patterns:25,G(p0 | XGp1) & G(p2 | XG!p1) -sb-patterns:26,G(p0 | (Xp1 & X!p1)) -sb-patterns:27,p0 | (p1 U p0) +dac-patterns=1,G!p0 +dac-patterns=2,Fp0 -> (!p1 U p0) +dac-patterns=3,G(p0 -> G!p1) +dac-patterns=4,G((p0 & !p1 & Fp1) -> (!p2 U p1)) +dac-patterns=5,G((p0 & !p1) -> (!p2 W p1)) +dac-patterns=6,Fp0 +dac-patterns=7,!p0 W (!p0 & p1) +dac-patterns=8,G!p0 | F(p0 & Fp1) +dac-patterns=9,G((p0 & !p1) -> (!p1 W (!p1 & p2))) +dac-patterns=10,G((p0 & !p1) -> (!p1 U (!p1 & p2))) +dac-patterns=11,!p0 W (p0 W (!p0 W (p0 W G!p0))) +dac-patterns=12,Fp0 -> ((!p0 & !p1) U (p0 | ((!p0 & p1) U (p0 | ((!p0 & !p1) U (p0 | ((!p0 & p1) U (p0 | (!p1 U p0))))))))) +dac-patterns=13,Fp0 -> (!p0 U (p0 & (!p1 W (p1 W (!p1 W (p1 W G!p1)))))) +dac-patterns=14,G((p0 & Fp1) -> ((!p1 & !p2) U (p1 | ((!p1 & p2) U (p1 | ((!p1 & !p2) U (p1 | ((!p1 & p2) U (p1 | (!p2 U p1)))))))))) +dac-patterns=15,G(p0 -> ((!p1 & !p2) U (p2 | ((p1 & !p2) U (p2 | ((!p1 & !p2) U (p2 | ((p1 & !p2) U (p2 | (!p1 W p2) | Gp1))))))))) +dac-patterns=16,Gp0 +dac-patterns=17,Fp0 -> (p1 U p0) +dac-patterns=18,G(p0 -> Gp1) +dac-patterns=19,G((p0 & !p1 & Fp1) -> (p2 U p1)) +dac-patterns=20,G((p0 & !p1) -> (p2 W p1)) +dac-patterns=21,!p0 W p1 +dac-patterns=22,Fp0 -> (!p1 U (p0 | p2)) +dac-patterns=23,G!p0 | F(p0 & (!p1 W p2)) +dac-patterns=24,G((p0 & !p1 & Fp1) -> (!p2 U (p1 | p3))) +dac-patterns=25,G((p0 & !p1) -> (!p2 W (p1 | p3))) +dac-patterns=26,G(p0 -> Fp1) +dac-patterns=27,Fp0 -> ((p1 -> (!p0 U (!p0 & p2))) U p0) +dac-patterns=28,G(p0 -> G(p1 -> Fp2)) +dac-patterns=29,G((p0 & !p1 & Fp1) -> ((p2 -> (!p1 U (!p1 & p3))) U p1)) +dac-patterns=30,G((p0 & !p1) -> ((p2 -> (!p1 U (!p1 & p3))) W p1)) +dac-patterns=31,Fp0 -> (!p0 U (!p0 & p1 & X(!p0 U p2))) +dac-patterns=32,Fp0 -> (!p1 U (p0 | (!p1 & p2 & X(!p1 U p3)))) +dac-patterns=33,G!p0 | (!p0 U ((p0 & Fp1) -> (!p1 U (!p1 & p2 & X(!p1 U p3))))) +dac-patterns=34,G((p0 & Fp1) -> (!p2 U (p1 | (!p2 & p3 & X(!p2 U p4))))) +dac-patterns=35,G(p0 -> (Fp1 -> (!p1 U (p2 | (!p1 & p3 & X(!p1 U p4)))))) +dac-patterns=36,F(p0 & XFp1) -> (!p0 U p2) +dac-patterns=37,Fp0 -> (!(!p0 & p1 & X(!p0 U (!p0 & p2))) U (p0 | p3)) +dac-patterns=38,G!p0 | (!p0 U (p0 & (F(p1 & XFp2) -> (!p1 U p3)))) +dac-patterns=39,G((p0 & Fp1) -> (!(!p1 & p2 & X(!p1 U (!p1 & p3))) U (p1 | p4))) +dac-patterns=40,G(p0 -> ((!(!p1 & p2 & X(!p1 U (!p1 & p3))) U (p1 | p4)) | G!(p2 & XFp3))) +dac-patterns=41,G((p0 & XFp1) -> XF(p1 & Fp2)) +dac-patterns=42,Fp0 -> (((p1 & X(!p0 U p2)) -> X(!p0 U (p2 & Fp3))) U p0) +dac-patterns=43,G(p0 -> G((p1 & XFp2) -> X(!p2 U (p2 & Fp3)))) +dac-patterns=44,G((p0 & Fp1) -> (((p2 & X(!p1 U p3)) -> X(!p1 U (p3 & Fp4))) U p1)) +dac-patterns=45,G(p0 -> (((p1 & X(!p2 U p3)) -> X(!p2 U (p3 & Fp4))) U (p2 | G((p1 & X(!p2 U p3)) -> X(!p2 U (p3 & Fp4)))))) +dac-patterns=46,G(p0 -> F(p1 & XFp2)) +dac-patterns=47,Fp0 -> ((p1 -> (!p0 U (!p0 & p2 & X(!p0 U p3)))) U p0) +dac-patterns=48,G(p0 -> G(p1 -> (p2 & XFp3))) +dac-patterns=49,G((p0 & Fp1) -> ((p2 -> (!p1 U (!p1 & p3 & X(!p1 U p4)))) U p1)) +dac-patterns=50,G(p0 -> ((p1 -> (!p2 U (!p2 & p3 & X(!p2 U p4)))) U (p2 | G(p1 -> (p3 & XFp4))))) +dac-patterns=51,G(p0 -> F(p1 & !p2 & X(!p2 U p3))) +dac-patterns=52,Fp0 -> ((p1 -> (!p0 U (!p0 & p2 & !p3 & X((!p0 & !p3) U p4)))) U p0) +dac-patterns=53,G(p0 -> G(p1 -> (p2 & !p3 & X(!p3 U p4)))) +dac-patterns=54,G((p0 & Fp1) -> ((p2 -> (!p1 U (!p1 & p3 & !p4 & X((!p1 & !p4) U p5)))) U p1)) +dac-patterns=55,G(p0 -> ((p1 -> (!p2 U (!p2 & p3 & !p4 & X((!p2 & !p4) U p5)))) U (p2 | G(p1 -> (p3 & !p4 & X(!p4 U p5)))))) +eh-patterns=1,p0 U (p1 & Gp2) +eh-patterns=2,p0 U (p1 & X(p2 U p3)) +eh-patterns=3,p0 U (p1 & X(p2 & F(p3 & XF(p4 & XF(p5 & XFp6))))) +eh-patterns=4,F(p0 & XGp1) +eh-patterns=5,F(p0 & X(p1 & XFp2)) +eh-patterns=6,F(p0 & X(p1 U p2)) +eh-patterns=7,FGp0 | GFp1 +eh-patterns=8,G(p0 -> (p1 U p2)) +eh-patterns=9,G(p0 & XF(p1 & XF(p2 & XFp3))) +eh-patterns=10,GFp0 & GFp1 & GFp2 & GFp3 & GFp4 +eh-patterns=11,(p0 U (p1 U p2)) | (p1 U (p2 U p0)) | (p2 U (p0 U p1)) +eh-patterns=12,G(p0 -> (p1 U (Gp2 | Gp3))) +hkrss-patterns=1,G(Fp0 & F!p0) +hkrss-patterns=2,GFp0 & GF!p0 +hkrss-patterns=3,GF(!(p1 <-> Xp1) | !(p0 <-> Xp0)) +hkrss-patterns=4,GF(!(p1 <-> Xp1) | !(p0 <-> Xp0) | !(p2 <-> Xp2) | !(p3 <-> Xp3)) +hkrss-patterns=5,G!p0 +hkrss-patterns=6,G((p0 -> F!p0) & (!p0 -> Fp0)) +hkrss-patterns=7,G(p0 -> F(p0 & p1)) +hkrss-patterns=8,G(p0 -> F((!p0 & p1 & p2 & p3) -> Fp4)) +hkrss-patterns=9,G(p0 -> F!p1) +hkrss-patterns=10,G(p0 -> Fp1) +hkrss-patterns=11,G(p0 -> F(p1 -> Fp2)) +hkrss-patterns=12,G(p0 -> F((p1 & p2) -> Fp3)) +hkrss-patterns=13,G((p0 -> Fp1) & (p2 -> Fp3) & (p4 -> Fp5) & (p6 -> Fp7)) +hkrss-patterns=14,G(!p0 & !p1) +hkrss-patterns=15,G!(p0 & p1) +hkrss-patterns=16,G(p0 -> p1) +hkrss-patterns=17,G((p0 -> !p1) & (p1 -> !p0)) +hkrss-patterns=18,G(!p0 -> (p1 <-> !p2)) +hkrss-patterns=19,G((!p0 & (p1 | p2 | p3)) -> p4) +hkrss-patterns=20,G((p0 & p1) -> (p2 | !(p3 & p4))) +hkrss-patterns=21,G((!p0 & p1 & !p2 & !p3 & !p4) -> F(!p5 & !p6 & !p7 & !p8)) +hkrss-patterns=22,G((p0 & p1 & !p2 & !p3 & !p4) -> F(p5 & !p6 & !p7 & !p8)) +hkrss-patterns=23,G(!p0 -> !(p1 & p2 & p3 & p4 & p5)) +hkrss-patterns=24,G(!p0 -> ((p1 & p2 & p3 & p4) -> !p5)) +hkrss-patterns=25,G((p0 & p1) -> (p2 | p3 | !(p4 & p5))) +hkrss-patterns=26,G((!p0 & (p1 | p2 | p3 | p4)) -> (!p5 <-> p6)) +hkrss-patterns=27,G((p0 & p1) -> (p2 | p3 | p4 | !(p5 & p6))) +hkrss-patterns=28,G((p0 & p1) -> (p2 | p3 | p4 | p5 | !(p6 & p7))) +hkrss-patterns=29,G((p0 & p1 & !p2 & Xp2) -> X(p3 | X(!p1 | p3))) +hkrss-patterns=30,G((p0 & p1 & !p2 & Xp2) -> X(X!p1 | (p2 U (!p2 U (p2 U (!p1 | p3)))))) +hkrss-patterns=31,G(p0 & p1 & !p2 & Xp2) -> X(X!p1 | (p2 U (!p2 U (p2 U (!p1 | p3))))) +hkrss-patterns=32,G(p0 -> (p1 U (!p1 U (!p2 | p3)))) +hkrss-patterns=33,G(p0 -> (p1 U (!p1 U (p2 | p3)))) +hkrss-patterns=34,G((!p0 & p1) -> Xp2) +hkrss-patterns=35,G(p0 -> X(p0 | p1)) +hkrss-patterns=36,G((!(p1 <-> Xp1) | !(p0 <-> Xp0) | !(p2 <-> Xp2) | !(p3 <-> Xp3)) -> (X!p4 & X(!(!(p1 <-> Xp1) | !(p0 <-> Xp0) | !(p2 <-> Xp2) | !(p3 <-> Xp3)) U p4))) +hkrss-patterns=37,G((p0 & !p1 & Xp1 & Xp0) -> (p2 -> Xp3)) +hkrss-patterns=38,G(p0 -> X(!p0 U p1)) +hkrss-patterns=39,G((!p0 & Xp0) -> X((p0 U p1) | Gp0)) +hkrss-patterns=40,G((!p0 & Xp0) -> X(p0 U (p0 & !p1 & X(p0 & p1)))) +hkrss-patterns=41,G((!p0 & Xp0) -> X(p0 U (p0 & !p1 & X(p0 & p1 & (p0 U (p0 & !p1 & X(p0 & p1))))))) +hkrss-patterns=42,G((p0 & X!p0) -> X(!p0 U (!p0 & !p1 & X(!p0 & p1 & (!p0 U (!p0 & !p1 & X(!p0 & p1))))))) +hkrss-patterns=43,G((p0 & X!p0) -> X(!p0 U (!p0 & !p1 & X(!p0 & p1 & (!p0 U (!p0 & !p1 & X(!p0 & p1 & (!p0 U (!p0 & !p1 & X(!p0 & p1)))))))))) +hkrss-patterns=44,G((!p0 & Xp0) -> X(!(!p0 & Xp0) U (!p1 & Xp1))) +hkrss-patterns=45,G(!p0 | X(!p0 | X(!p0 | X(!p0 | X(!p0 | X(!p0 | X(!p0 | X(!p0 | X(!p0 | X(!p0 | X(!p0 | X!p0))))))))))) +hkrss-patterns=46,G((Xp0 -> p0) -> (p1 <-> Xp1)) +hkrss-patterns=47,G((Xp0 -> p0) -> ((p1 -> Xp1) & (!p1 -> X!p1))) +hkrss-patterns=48,!p0 U G!((p1 & p2) | (p3 & p4) | (p2 & p3) | (p2 & p4) | (p1 & p4) | (p1 & p3)) +hkrss-patterns=49,!p0 U p1 +hkrss-patterns=50,(p0 U p1) | Gp0 +hkrss-patterns=51,p0 & XG!p0 +hkrss-patterns=52,XG(p0 -> (G!p1 | (!Xp1 U p2))) +hkrss-patterns=53,XG((p0 & !p1) -> (G!p1 | (!p1 U p2))) +hkrss-patterns=54,XG((p0 & p1) -> ((p1 U p2) | Gp1)) +hkrss-patterns=55,Xp0 & G((!p0 & Xp0) -> XXp0) +p-patterns=1,G(p0 -> Fp1) +p-patterns=2,(GFp1 & GFp0) -> GFp2 +p-patterns=3,G(p0 -> (p1 & (p2 U p3))) +p-patterns=4,F(p0 | p1) +p-patterns=5,GF(p0 | p1) +p-patterns=6,(p0 U p1) -> ((p2 U p3) | Gp2) +p-patterns=7,G(p0 -> (!p1 U (p1 U (!p1 & (p2 R !p1))))) +p-patterns=8,G(p0 -> (p1 R !p2)) +p-patterns=9,G(!p0 -> Fp0) +p-patterns=10,G(p0 -> F(p1 | p2)) +p-patterns=11,!(!(p0 | p1) U p2) & G(p3 -> !(!(p0 | p1) U p2)) +p-patterns=12,G!p0 -> G!p1 +p-patterns=13,G(p0 -> (G!p1 | (!p2 U p1))) +p-patterns=14,G(p0 -> (p1 R (p1 | !p2))) +p-patterns=15,G((p0 & p1) -> (!p1 R (p0 | !p1))) +p-patterns=16,G(p0 -> F(p1 & p2)) +p-patterns=17,G(p0 -> (!p1 U (p1 U (p1 & p2)))) +p-patterns=18,G(p0 -> (!p1 U (p1 U (!p1 U (p1 U (p1 & p2)))))) +p-patterns=19,GFp0 -> GFp1 +p-patterns=20,GF(p0 | p1) & GF(p1 | p2) +sb-patterns=1,p0 U p1 +sb-patterns=2,p0 U (p1 U p2) +sb-patterns=3,!(p0 U (p1 U p2)) +sb-patterns=4,GFp0 -> GFp1 +sb-patterns=5,Fp0 U Gp1 +sb-patterns=6,Gp0 U p1 +sb-patterns=7,!(Fp0 <-> Fp1) +sb-patterns=8,!(GFp0 -> GFp1) +sb-patterns=9,!(GFp0 <-> GFp1) +sb-patterns=10,p0 R (p0 | p1) +sb-patterns=11,(Xp0 U Xp1) | !X(p0 U p1) +sb-patterns=12,(Xp0 U p1) | !X(p0 U (p0 & p1)) +sb-patterns=13,G(p0 -> Fp1) & ((Xp0 U p1) | !X(p0 U (p0 & p1))) +sb-patterns=14,G(p0 -> Fp1) & ((Xp0 U Xp1) | !X(p0 U p1)) +sb-patterns=15,G(p0 -> Fp1) +sb-patterns=16,!G(p0 -> X(p1 R p2)) +sb-patterns=17,!(FGp0 | FGp1) +sb-patterns=18,G(Fp0 & Fp1) +sb-patterns=19,Fp0 & F!p0 +sb-patterns=20,(p0 & Xp1) R X(((p2 U p3) R p0) U (p2 R p0)) +sb-patterns=21,Gp2 | (G(p0 | GFp1) & G(p2 | GF!p1)) | Gp0 +sb-patterns=22,Gp0 | Gp2 | (G(p0 | FGp1) & G(p2 | FG!p1)) +sb-patterns=23,!(Gp2 | (G(p0 | GFp1) & G(p2 | GF!p1)) | Gp0) +sb-patterns=24,!(Gp0 | Gp2 | (G(p0 | FGp1) & G(p2 | FG!p1))) +sb-patterns=25,G(p0 | XGp1) & G(p2 | XG!p1) +sb-patterns=26,G(p0 | (Xp1 & X!p1)) +sb-patterns=27,p0 | (p1 U p0) #+end_example Note that ~--sb-patterns=2 --sb-patterns=4 --sb-patterns=21..22~ also @@ -323,7 +344,7 @@ have their complement formula listed as ~--sb-patterns=3 formula output by =genltl --sb-patterns= plus its negation, it will contain only 46 formulas, not 54. -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh genltl --sb | ltlfilt --uniq --count genltl --sb --pos --neg | ltlfilt --uniq --count #+END_SRC diff --git a/doc/org/hierarchy.org b/doc/org/hierarchy.org index 13c1bc4df..b19a6ab68 100644 --- a/doc/org/hierarchy.org +++ b/doc/org/hierarchy.org @@ -3,6 +3,7 @@ #+DESCRIPTION: Spot command-line tools for exploring the temporal hierarchy of Manna & Pnueli #+INCLUDE: setup.org #+HTML_LINK_UP: tools.html +#+PROPERTY: header-args:sh :results verbatim :exports both /A hierarchy of temporal properties/ was defined by Manna & Pnueli in their [[ftp://www-cs.stanford.edu/cs/theory/amir/hierarchy.ps][PODC'90 paper]]. @@ -83,7 +84,7 @@ Spot to denote the classes. The =--format=%h= option can be used to display the "class key" of the most precise class to which a formula belongs. -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltlfilt -f 'a U b' --format=%h #+END_SRC #+RESULTS: @@ -92,7 +93,7 @@ ltlfilt -f 'a U b' --format=%h If you find hard to remember the class name corresponding to the class keys, you can request verbose output with =%[v]h=: -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltlfilt -f 'a U b' --format='%[v]h' #+END_SRC #+RESULTS: @@ -102,7 +103,7 @@ But actually any /guarantee/ property is also an /obligation/, a /recurrence/, a /persistence/, and a /reactivity/ property. You can get the complete list of classes using =%[w]h= or =%[vw]h=: -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltlfilt -f 'a U b' --format='%[w]h = %[vw]h' #+END_SRC #+RESULTS: @@ -112,7 +113,7 @@ This =--format= option is also supported by =randltl=, =genltl=, and =ltlgrind=. So for instance if you want to classify the 55 LTL patterns of [[http://patterns.projects.cs.ksu.edu/documentation/patterns/ltl.shtml][Dwyers et al. (FMSP'98)]] using this hierarchy, try: -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh genltl --dac-patterns --format='%[v]h' | sort | uniq -c #+END_SRC @@ -139,7 +140,7 @@ three non-recurrence formulas, we can use =ltlfilt -v --recurrence= to remove all recurrence properties from the =genltl --dac-pattern= output: -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh genltl --dac-patterns | ltlfilt -v --recurrence --format='%[v]h, %f' #+END_SRC @@ -154,7 +155,7 @@ are automata-based, they work with PSL formulas as well. For instance, here is how to generate 10 random recurrence PSL formulas that are not LTL formulas, and that are not obligations: -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh randltl --psl -n -1 a b | ltlfilt -v --ltl | ltlfilt -v --obligation | @@ -193,18 +194,18 @@ sequences, we can use it with =%h= to split a list of formulas in 7 possible files. Here is a generation of 200 random LTL formulas binned into aptly named files: -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh randltl -n 200 a b -o random-%h.ltl wc -l random-?.ltl #+END_SRC #+RESULTS: -: 40 random-B.ltl +: 45 random-B.ltl : 49 random-G.ltl : 12 random-O.ltl : 21 random-P.ltl : 18 random-R.ltl -: 51 random-S.ltl +: 46 random-S.ltl : 9 random-T.ltl : 200 total @@ -229,7 +230,7 @@ is in class syntactic-C). Here is how to generate 10 random LTL formulas that describe safety properties but that are not in the syntactic-safety class: -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh randltl -n-1 a b | ltlfilt -v --syntactic-safety | ltlfilt --safety -n10 @@ -255,7 +256,7 @@ fragment. For instance =b M Gb= can be rewritten as just =Gb=, which belongs to this fragment. In this particular case, =ltlfilt --simplify= recognizes this: -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltlfilt --simplify -f 'b M Gb' #+END_SRC #+RESULTS: @@ -291,7 +292,7 @@ the translator could produce before determinization and minimization. For instance =Fa R b= is an obligation: -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltlfilt -f 'Fa R b' --format='%[v]h' #+END_SRC @@ -303,7 +304,7 @@ automaton (here we use =autfilt --highlight-nondet= to show where the non-determinism occurs): #+NAME: hier-oblig-1 -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :exports code ltl2tgba 'Fa R b' | autfilt --highlight-nondet -d #+END_SRC @@ -351,7 +352,7 @@ For instance, let us use =ltl2dstar= to construct a Streett automaton for the obligation property =Ga | XFb=. #+NAME: hier-oblig-3 -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :exports code ltldo 'ltl2dstar --automata=streett' -f 'Ga | XFb' -d #+END_SRC @@ -365,7 +366,7 @@ $txt We can now minimize this automaton with: #+NAME: hier-oblig-4 -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :exports code ltldo 'ltl2dstar --automata=streett' -f 'Ga | XFb' | autfilt -D -C -d #+END_SRC #+BEGIN_SRC dot :file hier-oblig-4.svg :var txt=hier-oblig-4 :exports results @@ -390,7 +391,7 @@ The output should be a terminal automaton in either case, An example is =a U Xb=: -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltlfilt -f 'a U Xb' --format='%[v]h' #+END_SRC @@ -399,7 +400,7 @@ ltlfilt -f 'a U Xb' --format='%[v]h' #+NAME: hier-guarantee-1 -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :exports code ltl2tgba 'a U Xb' | autfilt --highlight-nondet -d #+END_SRC #+BEGIN_SRC dot :file hier-guarantee-1.svg :var txt=hier-guarantee-1 :exports results @@ -410,7 +411,7 @@ $txt [[file:hier-guarantee-1.svg]] #+NAME: hier-guarantee-2 -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :exports code ltl2tgba -D 'a U Xb' -d #+END_SRC #+BEGIN_SRC dot :file hier-guarantee-2.svg :var txt=hier-guarantee-2 :exports results @@ -440,7 +441,7 @@ run are accepting. Here is an example: -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltlfilt -f '(a W Gb) M b' --format='%[v]h' #+END_SRC @@ -449,7 +450,7 @@ ltlfilt -f '(a W Gb) M b' --format='%[v]h' #+NAME: hier-safety-1 -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :exports code ltl2tgba '(a W Gb) M b' | autfilt --highlight-nondet -d #+END_SRC #+BEGIN_SRC dot :file hier-safety-1.svg :var txt=hier-safety-1 :exports results @@ -466,7 +467,7 @@ Using =-D= will fix that: it then produces a deterministic automaton that is guaranteed to be minimal, and where all runs are accepting. #+NAME: hier-safety-2 -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :exports code ltl2tgba -D '(a W Gb) M b' -d #+END_SRC #+BEGIN_SRC dot :file hier-safety-2.svg :var txt=hier-safety-2 :exports results @@ -485,7 +486,7 @@ acceptance (i.e. =t=). You can interpret this output as a monitor extended into valid ω-words). #+NAME: hier-safety-1m -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :exports code ltl2tgba -M '(a W Gb) M b' | autfilt --highlight-nondet -d #+END_SRC #+BEGIN_SRC dot :file hier-safety-1m.svg :var txt=hier-safety-1m :exports results @@ -496,7 +497,7 @@ ltl2tgba -M '(a W Gb) M b' | autfilt --highlight-nondet -d [[file:hier-safety-1m.svg]] #+NAME: hier-safety-2m -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :exports code ltl2tgba -M -D '(a W Gb) M b' -d #+END_SRC #+BEGIN_SRC dot :file hier-safety-2m.svg :var txt=hier-safety-2m :exports results @@ -530,7 +531,7 @@ transition-based acceptance will often produce shorter automata. The typical example is =GFa=, which can be translated into a 1-state transition-based Büchi automaton: -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltlfilt -f 'GFa' --format='%[v]h' #+END_SRC @@ -538,7 +539,7 @@ ltlfilt -f 'GFa' --format='%[v]h' : recurrence #+NAME: hier-recurrence-1 -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :exports code ltl2tgba 'GFa' -d #+END_SRC #+BEGIN_SRC dot :file hier-recurrence-1.svg :var txt=hier-recurrence-1 :exports results @@ -551,7 +552,7 @@ $txt Using state-based acceptance, at least two states are required. For instance: #+NAME: hier-recurrence-2 -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :exports code ltl2tgba -S 'GFa' -d #+END_SRC #+BEGIN_SRC dot :file hier-recurrence-2.svg :var txt=hier-recurrence-2 :exports results @@ -565,7 +566,7 @@ $txt Here is an example of a formula for which =ltl2tgba= does not produce a deterministic automaton, even with =-D=. -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltlfilt -f 'G(Gb | Fa)' --format='%[v]h' #+END_SRC @@ -573,7 +574,7 @@ ltlfilt -f 'G(Gb | Fa)' --format='%[v]h' : recurrence #+NAME: hier-recurrence-3 -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :exports code ltl2tgba -D 'G(Gb | Fa)' | autfilt --highlight-nondet -d #+END_SRC #+BEGIN_SRC dot :file hier-recurrence-3.svg :var txt=hier-recurrence-3 :exports results @@ -592,7 +593,7 @@ a /recurrence/ property), is to chain a few algorithms implemented in Spot: acceptance is desired. #+NAME: hier-recurrence-4 - #+BEGIN_SRC sh :results verbatim :exports code + #+BEGIN_SRC sh :exports code ltl2tgba -P -D 'G(Gb | Fa)' -d #+END_SRC #+BEGIN_SRC dot :file hier-recurrence-4.svg :var txt=hier-recurrence-4 :exports results @@ -607,7 +608,7 @@ a /recurrence/ property), is to chain a few algorithms implemented in Spot: generalized Rabin. #+NAME: hier-recurrence-5 - #+BEGIN_SRC sh :results verbatim :exports code + #+BEGIN_SRC sh :exports code ltl2tgba -P -D 'G(Gb | Fa)' | autfilt --generalized-rabin -d #+END_SRC @@ -649,7 +650,7 @@ a /recurrence/ property), is to chain a few algorithms implemented in Spot: simply get a larger deterministic automaton). #+NAME: hier-recurrence-7 - #+BEGIN_SRC sh :results verbatim :exports code + #+BEGIN_SRC sh :exports code ltl2tgba -P -D 'G(Gb | Fa)' | autfilt -S --generalized-rabin | autfilt -B -D -d @@ -668,7 +669,7 @@ passing =-S= to the first =autfilt= was optional, but in this case it helps producing a smaller automaton. Here is what we get without it: #+NAME: hier-recurrence-8 -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :exports code ltl2tgba -P -D 'G(Gb | Fa)' | autfilt --generalized-rabin | autfilt -B -D -d @@ -692,7 +693,7 @@ they cannot be represented by deterministic Büchi automata. The typical persistence formula is =FGa=, and using =-D= on this is hopeless. #+NAME: hier-persistence-1 -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :exports code ltl2tgba -D FGa -d #+END_SRC #+BEGIN_SRC dot :file hier-persistence-1.svg :var txt=hier-persistence-1 :exports results @@ -710,7 +711,7 @@ that =FGa= could be represented by a deterministic co-Büchi automaton. complementation ourselves: #+NAME: hier-persistence-2 -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :exports code ltlfilt --negate -f FGa | ltl2tgba -D | autfilt --complement -d @@ -746,7 +747,7 @@ automaton. Let's do that on the persistence formula =F(G!a | G(b U a))=, just for the fun of it. -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltlfilt -f 'F(G!a | G(b U a))' --format='%[v]h' #+END_SRC #+RESULTS: @@ -755,7 +756,7 @@ ltlfilt -f 'F(G!a | G(b U a))' --format='%[v]h' Unfortunately the default output of the translation is not weak: #+NAME: hier-persistence-3 -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :exports code ltl2tgba 'F(G!a | G(b U a))' -d #+END_SRC #+BEGIN_SRC dot :file hier-persistence-3.svg :var txt=hier-persistence-3 :exports results @@ -770,7 +771,7 @@ Büchi automaton for the complement, instead we get a non-deterministic generalized Büchi automaton: #+NAME: hier-persistence-4 -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :exports code ltlfilt --negate -f 'F(G!a | G(b U a))' | ltl2tgba -D | autfilt --highlight-nondet=5 -d @@ -787,7 +788,7 @@ determinizing this automaton into a Rabin automaton, and then back to deterministic Büchi: #+NAME: hier-persistence-5 -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :exports code ltlfilt --negate -f 'F(G!a | G(b U a))' | ltl2tgba -P -D | autfilt --generalized-rabin | @@ -804,7 +805,7 @@ This is a deterministic Büchi automaton for the negation of our formula. Now we can complement it to obtain a deterministic co-Büchi automaton for =F(G!a | G(b U a))=: #+NAME: hier-persistence-6 -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :exports code ltlfilt --negate -f 'F(G!a | G(b U a))' | ltl2tgba -P -D | autfilt --generalized-rabin | @@ -822,7 +823,7 @@ $txt And finally we convert the result back to Büchi: #+NAME: hier-persistence-7 -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :exports code ltlfilt --negate -f 'F(G!a | G(b U a))' | ltl2tgba -P -D | autfilt --generalized-rabin | diff --git a/doc/org/hoa.org b/doc/org/hoa.org index 0bf4a2bef..ed09fa990 100644 --- a/doc/org/hoa.org +++ b/doc/org/hoa.org @@ -2,6 +2,7 @@ #+DESCRIPTION: Details about support of the HOA format in Spot #+INCLUDE: setup.org #+HTML_LINK_UP: tools.html +#+PROPERTY: header-args:sh :results verbatim :exports both The [[http://adl.github.io/hoaf/][Hanoi Omega-Automa format]] is a textual representation of @@ -150,7 +151,7 @@ EOF #+RESULTS: -#+BEGIN_SRC sh :results verbatim :exports results :wrap SRC hoa +#+BEGIN_SRC sh :exports results :wrap SRC hoa sed -n '/--BODY/,/--END/p' stvstracc.hoa | grep -v -- -- #+END_SRC @@ -173,7 +174,7 @@ State: 2 will always be stored as a TωA with this transition structure: -#+BEGIN_SRC sh :results verbatim :exports results :wrap SRC hoa +#+BEGIN_SRC sh :exports results :wrap SRC hoa autfilt -Ht stvstracc.hoa | sed -n '/--BODY/,/--END/p' | grep -v -- -- #+END_SRC @@ -208,7 +209,7 @@ For instance in the following automaton, the outgoing transitions of each states belong to the same sets: #+NAME: state-based-example -#+BEGIN_SRC sh :results verbatim :exports both :wrap SRC hoa +#+BEGIN_SRC sh :wrap SRC hoa cat >sba.hoa <hw.hoa <decorate.hoa <[all]> + labelloc="t" node [shape="circle"] node [style="filled", fillcolor="#ffffa0"] fontname="Lato" node [fontname="Lato"] edge [fontname="Lato"] - edge[arrowhead=vee, arrowsize=.7] + node[fontsize=12] fontsize=12 stylesheet="spot.css" edge[arrowhead=vee, arrowsize=.7, fontsize=12] I [label="", style=invis, width=0] I -> 1 0 [label=<0>] - 0 -> 0 [label=<1>, taillabel="#1", style=bold, color="#F17CB0"] - 1 [label=<1>, style="bold,filled", color="#5DA5DA"] - 1 -> 2 [label=<1>, taillabel="#2", style=bold, color="#FAA43A"] - 2 [label=<2>, style="bold,filled", color="#B276B2"] + 0 -> 0 [label=<1>, taillabel="#1", style=bold, color="#FF4DA0"] + 1 [label=<1>, style="bold,filled", color="#1F78B4"] + 1 -> 2 [label=<1>, taillabel="#2", style=bold, color="#FF7F00"] + 2 [label=<2>, style="bold,filled", color="#6A3D9A"] 2 -> 0 [label=, taillabel="#3"] 2 -> 2 [label=, taillabel="#4"] } @@ -1031,7 +1034,7 @@ headers ~spot.highlight.states:~ and ~spot.highlight.edges:~ are both followed by a list of alternating state/edges numbers and color numbers. So in the above file, -#+BEGIN_SRC sh :results verbatim :exports results :wrap SRC hoa +#+BEGIN_SRC sh :exports results :wrap SRC hoa grep spot.highlight decorate.hoa #+END_SRC #+RESULTS: @@ -1058,7 +1061,7 @@ these lines when version 1.1 is selected. Compare: -#+BEGIN_SRC sh :results verbatim :exports both :wrap SRC hoa +#+BEGIN_SRC sh :wrap SRC hoa autfilt -H1 decorate.hoa; echo autfilt -H1.1 decorate.hoa #+END_SRC diff --git a/doc/org/ioltl.org b/doc/org/ioltl.org index f2dc6563e..641a19ef2 100644 --- a/doc/org/ioltl.org +++ b/doc/org/ioltl.org @@ -3,6 +3,7 @@ #+DESCRIPTION: Options for input and output of temporal logic formulas in Spot's command-line tools #+INCLUDE: setup.org #+HTML_LINK_UP: tools.html +#+PROPERTY: header-args:sh :results verbatim :exports both Spot supports different syntaxes for LTL/PSL formulas. This page documents the options, common to all tools where it makes sense, that @@ -12,14 +13,14 @@ are used to specify input and output of formula. All tools that read LTL/PSL formulas implement the following options: -#+BEGIN_SRC sh :results verbatim :exports results +#+BEGIN_SRC sh :exports results ltl2tgba --help | sed -n '/Input options:/,/^$/p' | sed '1d;$d' #+END_SRC #+RESULTS: : -f, --formula=STRING process the formula STRING : -F, --file=FILENAME[/COL] process each line of FILENAME as a formula; if COL : is a positive integer, assume a CSV file and read -: column COL; usea negative COL to drop the first +: column COL; use a negative COL to drop the first : line of the CSV file : --lbt-input read all formulas using LBT's prefix syntax : --lenient parenthesized blocks that cannot be parsed as @@ -97,21 +98,18 @@ consider =a + b < 2= as an atomic proposition. An unfortunate side-effect of =--lenient= parsing is that many syntax errors will not be caught. Compare the following syntax error: -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :prologue "exec 2>&1" :epilogue true ltlfilt -f '(a U b U) U c' #+END_SRC #+RESULTS: - -#+BEGIN_SRC sh :results verbatim :exports results -(ltlfilt -f '(a U b U) U c' 2>&1 | cat) | sed '/^$/d' -#+END_SRC -#+RESULTS: : >>> (a U b U) U c : ^ : syntax error, unexpected closing parenthesis +: : >>> (a U b U) U c : ^ : missing right operand for "until operator" +: With the same command in =--lenient= mode: @@ -146,7 +144,7 @@ used by [[http://www.ltl2dstar.de][ltl2dstar]]. All tools that output LTL/PSL formulas implement the following options: -#+BEGIN_SRC sh :results verbatim :exports results +#+BEGIN_SRC sh :exports results genltl --help | sed -n '/Output options:/,/^$/p' | sed '1d;$d' #+END_SRC #+RESULTS: @@ -154,14 +152,18 @@ genltl --help | sed -n '/Output options:/,/^$/p' | sed '1d;$d' -0, --zero-terminated-output separate output formulas with \0 instead of \n (for use with xargs -0) -8, --utf8 output using UTF-8 characters - --csv-escape quote the formula for use in a CSV file - --format=FORMAT specify how each line should be output (default: + --format=FORMAT, --stats=FORMAT + specify how each line should be output (default: "%f") -l, --lbt output in LBT's syntax --latex output using LaTeX macros + --negative, --negated output the negated versions of all formulas -o, --output=FORMAT send output to a file named FORMAT instead of standard output. The first formula sent to a file truncates it unless FORMAT starts with '>>'. + --positive output the positive versions of all formulas (done + by default, unless --negative is specified without + --positive) -p, --full-parentheses output fully-parenthesized formulas -s, --spin output in Spin's syntax --spot output in Spot's syntax (default) @@ -218,7 +220,7 @@ the above =%=-sequences. For instance the following invocation of [[file:randltl.org][=randltl=]] will create 5 random formulas, but in 5 different files: -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh randltl -n5 a b -o example-%L.ltl wc -l example-*.ltl #+END_SRC @@ -241,7 +243,7 @@ in LTL formulas), but you can use =xargs -0= to split the input on null characters. So for instance the following two invocations have nearly the same output: -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh genltl -0 --gh-q=1..4 | xargs -0 ltl2tgba --stats='%F,%f,%s' genltl --gh-q=1..4 | ltl2tgba -F- --stats='%F,%f,%s' #+END_SRC diff --git a/doc/org/ltl2tgba.org b/doc/org/ltl2tgba.org index 9dba89b8d..0b7e48c73 100644 --- a/doc/org/ltl2tgba.org +++ b/doc/org/ltl2tgba.org @@ -3,6 +3,7 @@ #+DESCRIPTION: Spot command-line tool for translating LTL into Transition-based Generalized Büchi Automata. #+INCLUDE: setup.org #+HTML_LINK_UP: tools.html +#+PROPERTY: header-args:sh :results verbatim :exports both This tool translates LTL or PSL formulas into different types of automata. @@ -31,7 +32,7 @@ less frequent.) Formulas to translate may be specified using [[file:ioltl.org][common input options for LTL/PSL formulas]]. -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltl2tgba -f 'Fa & GFb' #+END_SRC @@ -69,7 +70,7 @@ can easily be piped to other tools. To convert the automaton into a picture, or into vectorial format, use =--dot= or =-d= to request [[http://www.graphviz.org/][GraphViz output]] and process the result with =dot= or =dotty=. Typically, you could get a =pdf= of this TGBA using -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :exports code ltl2tgba "Fa & GFb" -d | dot -Tpdf > tgba.pdf #+END_SRC #+RESULTS: @@ -78,7 +79,7 @@ The result would look like this (note that in this documentation we use some [[file:oaut.org::#default-dot][environment variables]] to produce a more colorful output by default) #+NAME: dotex -#+BEGIN_SRC sh :results verbatim :exports none +#+BEGIN_SRC sh :exports none ltl2tgba "Fa & GFb" -d #+END_SRC #+RESULTS: dotex @@ -123,7 +124,7 @@ Here is a TGBA with multiple acceptance sets (we omit the call to =dot= to render the output of =ltl2tgba= from now on): #+NAME: dotex2 -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :exports code ltl2tgba "GFa & GFb" -d #+END_SRC #+RESULTS: dotex2 @@ -158,7 +159,7 @@ A Büchi automaton for the previous formula can be obtained with the =-B= option: #+NAME: dotex2ba -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :exports code ltl2tgba -B 'GFa & GFb' -d #+END_SRC #+RESULTS: dotex2ba @@ -200,12 +201,12 @@ can see this underlying TGBA if you pass the =--dot=t= option (the =t= requests the use of transition-based acceptance as it is done internally): -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :exports code ltl2tgba --dot=t -B 'GFa & GFb' #+END_SRC #+NAME: dotex2ba-t -#+BEGIN_SRC sh :results verbatim :exports none +#+BEGIN_SRC sh :exports none ltl2tgba --dot=.t -B 'GFa & GFb' #+END_SRC @@ -244,7 +245,7 @@ Büchi automata with state-based acceptance. Here is the same formula as above, for comparison. #+NAME: dotex2gba -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :exports code ltl2tgba -S 'GFa & GFb' -d #+END_SRC @@ -297,7 +298,7 @@ than the BA produced by =-B=. As already discussed on the page about [[file:oaut.org][common output options]], various options controls the output format of =ltl2tgba=: -#+BEGIN_SRC sh :results verbatim :exports results +#+BEGIN_SRC sh :exports results ltl2tgba --help | sed -n '/Output format:/,/^$/p' | sed '1d;$d' #+END_SRC #+RESULTS: @@ -346,7 +347,7 @@ Option =-8= can be used to improve the readability of the output if your system can display UTF-8 correctly. #+NAME: dotex2ba8 -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :exports code ltl2tgba -B8 "GFa & GFb" -d #+END_SRC #+RESULTS: dotex2ba8 @@ -386,7 +387,7 @@ Using the =--spin= or =-s= option, =ltl2tgba= will produce a Büchi automaton =ltl2tgba -s= is therefore a drop-in replacement for =spin -f=. -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltl2tgba -s 'GFa & GFb' #+END_SRC #+RESULTS: @@ -416,14 +417,14 @@ Since Spin 6 extended its syntax to support arbitrary atomic propositions, you may also need put the parser in =--lenient= mode to support these: -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltl2tgba -s --lenient '(a < b) U (process[2]@ok)' #+END_SRC #+RESULTS: : never { /* "a < b" U "process[2]@ok" */ : T0_init: : if -: :: ((process[2]@ok)) -> goto accept_all +: :: (process[2]@ok) -> goto accept_all : :: ((a < b) && (!(process[2]@ok))) -> goto T0_init : fi; : accept_all: @@ -437,13 +438,15 @@ set of options specifies the goal of the simplification routines: whenever possible, would you prefer a small automaton (=--small=) or a deterministic (=--deterministic=) automaton? -#+BEGIN_SRC sh :results verbatim :exports results +#+BEGIN_SRC sh :exports results ltl2tgba --help | sed -n '/Simplification goal:/,/^$/p' | sed '1d;$d' #+END_SRC #+RESULTS: : -a, --any no preference, do not bother making it small or : deterministic -: -D, --deterministic prefer deterministic automata +: -D, --deterministic prefer deterministic automata (combine with +: --generic to be sure to obtain a deterministic +: automaton) : --small prefer small automata (default) The =--any= option tells the translator that it should attempt to @@ -475,7 +478,7 @@ An example formula where the difference between =-D= and =--small= is flagrant is =Ga|Gb|Gc=: #+NAME: gagbgc1 -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :exports code ltl2tgba 'Ga|Gb|Gc' -d #+END_SRC #+RESULTS: gagbgc1 @@ -509,7 +512,7 @@ $txt [[file:gagbgc1.svg]] #+NAME: gagbgc2 -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :exports code ltl2tgba -D 'Ga|Gb|Gc' -d #+END_SRC #+RESULTS: gagbgc2 @@ -577,7 +580,7 @@ two ways to accept a run that repeats continuously the configuration $\bar ab$. #+NAME: ambig1 -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :exports code ltl2tgba -B 'GFa -> GFb' -d #+END_SRC #+RESULTS: ambig1 @@ -616,7 +619,7 @@ Here is an unambiguous automaton for the same formula, in which there is only one run that recognizes this example word: #+NAME: ambig2 -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :exports code ltl2tgba -B -U 'GFa -> GFb' -d #+END_SRC @@ -670,7 +673,7 @@ will be complete and unambiguous. A last parameter that can be used to tune the translation is the amount of pre- and post-processing performed. These two steps can be adjusted via a common set of switches: -#+BEGIN_SRC sh :results verbatim :exports results +#+BEGIN_SRC sh :exports results ltl2tgba --help | sed -n '/Simplification level:/,/^$/p' | sed '1d;$d' #+END_SRC #+RESULTS: @@ -740,7 +743,7 @@ expectations. deterministic TGBA exists. #+NAME: ltl2tgba-fga -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :exports code ltl2tgba "FGa" -D -d #+END_SRC @@ -754,7 +757,7 @@ ltl2tgba "FGa" -D -d But with =--generic=, =ltl2tgba= will output the following co-Büchi automaton: #+NAME: ltl2tgba-fga-D -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :exports code ltl2tgba "FGa" -G -D -d #+END_SRC @@ -770,7 +773,7 @@ If we translate =Fb|Gc= as a deterministic automaton with any acceptance condition, we get a weak and deterministic Büchi automaton: #+NAME: ltl2tgba-fbgc-D -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :exports code ltl2tgba "Fb|Gc" -G -D -d #+END_SRC @@ -786,7 +789,7 @@ Finally if we translate the conjunction of these two subformulas, a product of these two automata will be made, producing: #+NAME: ltl2tgba-fbgcfga-D -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :exports code ltl2tgba "(Fb|Gc)&FGa" -G -D -d #+END_SRC @@ -804,7 +807,7 @@ TGBA is non-deterministic, it will then be determinized into an automaton with parity acceptance: #+NAME: ltl2tgba-fbgcfga-nosplit-D -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :exports code ltl2tgba "(Fb|Gc)&FGa" -G -D -xltl-split=0 -d #+END_SRC #+BEGIN_SRC dot :file ltl2tgba-fbgcfga-nosplit-D.svg :var txt=ltl2tgba-fbgcfga-nosplit-D :exports results @@ -823,7 +826,7 @@ purpose. For instance the following deterministic automaton #+NAME: ltl2tgba-det1 -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :exports code ltl2tgba "F(a W FGb)" -G -D -d #+END_SRC @@ -837,7 +840,7 @@ ltl2tgba "F(a W FGb)" -G -D -d would be larger if SCC-based optimizations were disabled: #+NAME: ltl2tgba-det2 -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :exports code ltl2tgba "F(a W FGb)" -xdet-scc=0 -G -D -d #+END_SRC @@ -882,7 +885,7 @@ For instance, =FGa= gets translated into an automaton with =Rabin 1= acceptance (another name for =parity min odd 2=): #+NAME: ltl2tgba-dp1 -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :exports code ltl2tgba "FGa" -D -P -d #+END_SRC @@ -897,7 +900,7 @@ And =GFa & GFb= gets translated into a =Büchi= automaton (another name for =parity min even 1=): #+NAME: ltl2tgba-dp2 -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :exports code ltl2tgba "GFa & GFb" -D -P -d #+END_SRC @@ -912,7 +915,7 @@ If we really want to use the same style of parity acceptance for all outputs, we can specify it as an argument to the =--parity= option. For instance #+NAME: ltl2tgba-dp3 -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :exports code ltl2tgba "GFa & GFb" -D -P'min odd' -d #+END_SRC @@ -930,7 +933,7 @@ I.e., each transition (or state if state-based acceptance is requested) should belong to exactly one acceptance set. #+NAME: ltl2tgba-dp4 -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :exports code ltl2tgba "GFa & GFb" -D -p -d #+END_SRC @@ -942,7 +945,7 @@ ltl2tgba "GFa & GFb" -D -p -d [[file:ltl2tgba-dp4.svg]] #+NAME: ltl2tgba-dp5 -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :exports code ltl2tgba "GFa & GFb" -D -p'min odd' -d #+END_SRC @@ -957,7 +960,7 @@ Note that all these options can be combined with state-based acceptance if needed: #+NAME: ltl2tgba-dp6 -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :exports code ltl2tgba "GFa & GFb" -D -S -p'max even' -d #+END_SRC @@ -983,7 +986,7 @@ automata themselves. The =FORMAT= string should indicate which statistics should be output, and how they should be output using the following sequence of characters (other characters are output as-is): -#+BEGIN_SRC sh :results verbatim :exports results +#+BEGIN_SRC sh :exports results ltl2tgba --help | sed -n '/ sequences:/,/^$/p' | sed '1d;$d' #+END_SRC #+RESULTS: @@ -1042,7 +1045,7 @@ ltl2tgba --help | sed -n '/ sequences:/,/^$/p' | sed '1d;$d' For instance we can study the size of the automata generated for the right-nested =U= formulas as follows: -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh genltl --u-right=1..8 | ltl2tgba --stats '%s states and %e edges for "%f"' #+END_SRC #+RESULTS: @@ -1093,7 +1096,7 @@ compatible outgoing transition exist. deterministic monitor for the given formula. #+NAME: monitor1 -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :exports code ltl2tgba -M '(Xa & Fb) | Gc' -d #+END_SRC @@ -1128,7 +1131,7 @@ $txt [[file:monitor1.svg]] #+NAME: monitor2 -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :exports code ltl2tgba -MD '(Xa & Fb) | Gc' -d #+END_SRC @@ -1155,7 +1158,7 @@ if) a sink state had to be added. For instance, here is the "complete" version of the previous monitor. #+NAME: monitor3 -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :exports code ltl2tgba -C -M -D '(Xa & Fb) | Gc' -d #+END_SRC diff --git a/doc/org/ltl2tgta.org b/doc/org/ltl2tgta.org index 5cb1d345d..2387c20bf 100644 --- a/doc/org/ltl2tgta.org +++ b/doc/org/ltl2tgta.org @@ -3,6 +3,7 @@ #+DESCRIPTION: Spot command-line tool for translating LTL into Transition-based Generalized Testing Automata. #+INCLUDE: setup.org #+HTML_LINK_UP: tools.html +#+PROPERTY: header-args:sh :results verbatim :exports code This tool generates various form of Testing Automata, i.e., automata that observe the /changes/ of atomic propositions, not their values. @@ -18,39 +19,10 @@ Here is the output on =a U Gb= (we omit the call to =dot=, as shown while discussing [[file:ltl2tgba.org][=ltl2tgba=]]). #+NAME: augb-ta -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh ltl2tgta --ta --multiple-init 'a U Gb' #+END_SRC -#+RESULTS: augb-ta -#+begin_example -digraph G { - rankdir=LR - node [style="filled", fillcolor="#ffffa0"] - fontname="Lato" - node [fontname="Lato"] - edge [fontname="Lato"] - edge[arrowhead=vee, arrowsize=.7] - -1 [label="", style=invis, height=0] - -1 -> 1 [label="!a & b"] - -2 [label="", style=invis, height=0] - -2 -> 2 [label="a & !b"] - -3 [label="", style=invis, height=0] - -3 -> 3 [label="a & b"] - 1 [label="2\n!a & b",shape=box] - 1 -> 4 [label="{a}\n"] - 2 [label="1\na & !b"] - 2 -> 3 [label="{b}\n"] - 2 -> 1 [label="{a, b}\n"] - 3 [label="0\na & b",shape=box] - 3 -> 4 [label="{a}\n"] - 3 -> 1 [label="{a}\n"] - 3 -> 2 [label="{b}\n"] - 4 [label="3",peripheries=2,shape=box] - 4 -> 4 [label="{a}\n{0}"] -} -#+end_example - #+BEGIN_SRC dot :file augb-ta.svg :var txt=augb-ta :exports results $txt #+END_SRC @@ -78,31 +50,9 @@ Without the =--multiple-init= option, a fake initial state is added. This is the default since it often makes the result more readable. #+NAME: augb-ta2 -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh ltl2tgta --ta 'a U Gb' #+END_SRC -#+RESULTS: -#+begin_example -digraph G { - 0 [label="", style=invis, height=0] - 0 -> 1 - 1 [label=init] - 1 -> 2 [label="!a & b\n"] - 1 -> 3 [label="a & b\n"] - 1 -> 4 [label="a & !b\n"] - 2 [label="2",shape=box] - 2 -> 5 [label="{a}\n"] - 3 [label="3",shape=box] - 3 -> 5 [label="{a}\n"] - 3 -> 2 [label="{a}\n"] - 3 -> 4 [label="{b}\n"] - 4 [label="1"] - 4 -> 3 [label="{b}\n"] - 4 -> 2 [label="{a, b}\n"] - 5 [label="4",peripheries=2,shape=box] - 5 -> 5 [label="{a}\n{0}"] -} -#+end_example #+BEGIN_SRC dot :file augb-ta2.svg :var txt=augb-ta2 :exports results $txt @@ -117,37 +67,9 @@ Büchi accepting transitions are marked with the same ={0,1}= notation used in TGBA. #+NAME: gfagfb-gta -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh ltl2tgta --gta 'GFa & GFb' #+END_SRC -#+RESULTS: -#+begin_example -digraph G { - 0 [label="", style=invis, height=0] - 0 -> 1 - 1 [label=init] - 1 -> 2 [label="a & b\n"] - 1 -> 3 [label="!a & b\n"] - 1 -> 4 [label="a & !b\n"] - 1 -> 5 [label="!a & !b\n"] - 2 [label="1",shape=box] - 2 -> 3 [label="{a}\n{0,1}"] - 2 -> 4 [label="{b}\n{0,1}"] - 2 -> 5 [label="{a, b}\n{0,1}"] - 3 [label="3"] - 3 -> 2 [label="{a}\n{1}"] - 3 -> 4 [label="{a, b}\n{1}"] - 3 -> 5 [label="{b}\n{1}"] - 4 [label="2"] - 4 -> 2 [label="{b}\n{0}"] - 4 -> 3 [label="{a, b}\n{0}"] - 4 -> 5 [label="{a}\n{0}"] - 5 [label="4"] - 5 -> 2 [label="{a, b}\n"] - 5 -> 3 [label="{b}\n"] - 5 -> 4 [label="{a}\n"] -} -#+end_example #+BEGIN_SRC dot :file gfagfb-gta.svg :var txt=gfagfb-gta :exports results $txt @@ -167,41 +89,9 @@ made explicit with ={}= self-loops. Since these self-loop can be in acceptance sets, livelock acceptance states are no longer needed. #+NAME: gfagfb-tgta -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh ltl2tgta 'GFa & GFb' #+END_SRC -#+RESULTS: -#+begin_example -digraph G { - 0 [label="", style=invis, height=0] - 0 -> 1 - 1 [label=init] - 1 -> 2 [label="a & b\n"] - 1 -> 3 [label="!a & b\n"] - 1 -> 4 [label="a & !b\n"] - 1 -> 5 [label="!a & !b\n"] - 2 [label="3"] - 2 -> 3 [label="{a}\n{0,1}"] - 2 -> 4 [label="{b}\n{0,1}"] - 2 -> 5 [label="{a, b}\n{0,1}"] - 2 -> 2 [label="{}\n{0,1}"] - 3 [label="2"] - 3 -> 2 [label="{a}\n{1}"] - 3 -> 4 [label="{a, b}\n{1}"] - 3 -> 5 [label="{b}\n{1}"] - 3 -> 3 [label="{}\n"] - 4 [label="4"] - 4 -> 2 [label="{b}\n{0}"] - 4 -> 3 [label="{a, b}\n{0}"] - 4 -> 5 [label="{a}\n{0}"] - 4 -> 4 [label="{}\n"] - 5 [label="1"] - 5 -> 2 [label="{a, b}\n"] - 5 -> 3 [label="{b}\n"] - 5 -> 4 [label="{a}\n"] - 5 -> 5 [label="{}\n"] -} -#+end_example #+BEGIN_SRC dot :file gfagfb-tgta.svg :var txt=gfagfb-tgta :exports results $txt @@ -210,10 +100,12 @@ $txt [[file:gfagfb-tgta.svg]] -[fn:topnoc]: This new class of automaton, as well as the -implementation of the previous testing automata classes, is part of -Ala Eddine BEN SALEM's PhD work, and should appear in a future edition -of ToPNoC (LNCS 7400). +[fn:topnoc]: This new class of automata, as well as the implementation +of the previous testing automata classes, is part of Ala Eddine BEN +SALEM's PhD work, and is discussed in [[https://www.lrde.epita.fr/~adl/dl/adl/bensalem.12.topnoc.pdf][*Model checking using +generalized testing automata*]], /Ala Eddine Ben Salem/, /Alexandre +Duret-Lutz/, and /Fabrice Kordon/, in Transactions on Petri Nets and +Other Models of Concurrency (ToPNoC VI), LNCS 7400, p. 94--112, 2012. # LocalWords: ltl tgta num toc Automata automata GraphViz UTF Gb na diff --git a/doc/org/ltlcross.org b/doc/org/ltlcross.org index a5d920d71..6febcb1b6 100644 --- a/doc/org/ltlcross.org +++ b/doc/org/ltlcross.org @@ -3,6 +3,8 @@ #+DESCRIPTION: Spot command-line tool for cross-comparing the output of LTL translators. #+INCLUDE: setup.org #+HTML_LINK_UP: tools.html +#+PROPERTY: header-args:sh :results verbatim :exports both +#+PROPERTY: header-args:R :session :results output :exports both =ltlcross= is a tool for cross-comparing the output of LTL-to-automata translators. It is actually a Spot-based clone of [[http://www.tcs.hut.fi/Software/lbtt/][LBTT]], the @@ -58,7 +60,7 @@ and no =-f= or =-F= options are given. Each translator should be specified as a string that use some of the following character sequences: -#+BEGIN_SRC sh :results verbatim :exports results +#+BEGIN_SRC sh :exports results ltlcross --help | sed -n '/character sequences:/,/^$/p' | sed '1d;$d' #+END_SRC #+RESULTS: @@ -73,7 +75,7 @@ following character sequences: For instance here is how we could cross-compare the never claims output by =spin= and =ltl2tgba= for the formulas =GFa= and =X(a U b)=. -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :exports code ltlcross -f 'GFa' -f 'X(a U b)' 'ltl2tgba -s %s >%O' 'spin -f %s >%O' #+END_SRC #+RESULTS: @@ -83,7 +85,7 @@ by the formula in Spin's syntax, and =%O= will be replaced by a temporary file into which the output of the translator is redirected before it is read back by =ltlcross=. -#+BEGIN_SRC sh :results verbatim :exports results +#+BEGIN_SRC sh :exports results ltlcross -f 'GFa' -f 'X(a U b)' 'ltl2tgba -s %s >%O' 'spin -f %s >%O' 2>&1 #+END_SRC #+RESULTS: @@ -174,7 +176,7 @@ To simplify the use of some of the above tools, a set of predefined shorthands are available. Those can be listed with the =--list-shorthands= option. -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltlcross --list-shorthands #+END_SRC #+RESULTS: @@ -182,24 +184,28 @@ ltlcross --list-shorthands If a COMMANDFMT does not use any %-sequence, and starts with one of the following words, then the string on the right is appended. + delag %f>%O lbt <%L>%O ltl2ba -f %s>%O ltl2da %f>%O + ltl2dgra %f>%O ltl2dpa %f>%O + ltl2dra %f>%O ltl2ldba %f>%O ltl2dstar --output-format=hoa %[MW]L %O ltl2tgba -H %f>%O ltl3ba -f %s>%O ltl3dra -f %s>%O ltl3hoa -f %f>%O + ltl3tela -f %f>%O modella %[MWei^]L %O spin -f %s>%O Any {name} and directory component is skipped for the purpose of matching those prefixes. So for instance '{DRA} ~/mytools/ltl2dstar-0.5.2' -will changed into - '{DRA} ~/mytools/ltl2dstar-0.5.2 --output-format=hoa %[MR]L %O' +will be changed into + '{DRA} ~/mytools/ltl2dstar-0.5.2 --output-format=hoa %[MW]L %O' #+end_example What this implies is that running =ltlcross ltl2ba ltl3ba ...= is @@ -381,67 +387,45 @@ randltl -n 3 a b | ltlfilt --remove-wm | ltlcross --csv=results.csv --json=results.json \ 'ltl2tgba -s %f >%O' \ 'spin -f %s >%O' \ - 'lbt < %L >%O' --csv=results.csv 2>&1 + 'lbt < %L >%O' 2>&1 #+END_SRC -#+RESULTS: -#+begin_example --:1: 0 -Running [P0]: ltl2tgba -s '0' >'lcr-o0-HIoc9n' -Running [P1]: spin -f 'false' >'lcr-o1-69Gi3B' -Running [P2]: lbt < 'lcr-i0-cYhaYP' >'lcr-o2-CZe2S3' -Running [N0]: ltl2tgba -s '1' >'lcr-o0-9YEpOh' -Running [N1]: spin -f 'true' >'lcr-o1-exCCOv' -Running [N2]: lbt < 'lcr-i0-DMSnRJ' >'lcr-o2-E0H9TX' -Performing sanity checks and gathering statistics... - --:2: !((1) U (F(!(p0)))) -Running [P0]: ltl2tgba -s '!((1) U (F(!(p0))))' >'lcr-o0-ubhgZb' -Running [P1]: spin -f '!((true) U (<>(!(p0))))' >'lcr-o1-wBnwcq' -Running [P2]: lbt < 'lcr-i1-D3WcqE' >'lcr-o2-i3VTDS' -Running [N0]: ltl2tgba -s '(1) U (F(!(p0)))' >'lcr-o0-8F2eS6' -Running [N1]: spin -f '(true) U (<>(!(p0)))' >'lcr-o1-focrcl' -Running [N2]: lbt < 'lcr-i1-VgW9wz' >'lcr-o2-GbdTRN' -Performing sanity checks and gathering statistics... - --:3: (1) U ((G(p0)) | (F(p1))) -Running [P0]: ltl2tgba -s '(1) U ((G(p0)) | (F(p1)))' >'lcr-o0-jj8Ih2' -Running [P1]: spin -f '(true) U (([](p0)) || (<>(p1)))' >'lcr-o1-JarYMg' -Running [P2]: lbt < 'lcr-i2-yq4yiv' >'lcr-o2-Lw29NJ' -Running [N0]: ltl2tgba -s '!((1) U ((G(p0)) | (F(p1))))' >'lcr-o0-mHp6jY' -Running [N1]: spin -f '!((true) U (([](p0)) || (<>(p1))))' >'lcr-o1-pA7KVc' -Running [N2]: lbt < 'lcr-i2-ZxXHBr' >'lcr-o2-YadFhG' -Performing sanity checks and gathering statistics... - -No problem detected. -#+end_example After this execution, the file =results.csv= contains the following: -#+BEGIN_SRC sh :results verbatim :exports results -cat results.csv +#+BEGIN_SRC sh :results output raw :exports results +sed 's/"//g +s/|/\\vert{}/g +s/--/@@html:--@@/g +1a\ +|-| +s/^/| / +s/$/ |/ +s/,/|/g +' results.csv #+END_SRC + +#+ATTR_HTML: :class csv-table #+RESULTS: -#+begin_example -"formula","tool","exit_status","exit_code","time","states","edges","transitions","acc","scc","nondet_states","nondet_aut","complete_aut","product_states","product_transitions","product_scc" -"0","ltl2tgba -s %f >%O","ok",0,0.0299298,1,1,0,1,1,0,0,0,1,0,1 -"0","spin -f %s >%O","ok",0,0.00396246,2,2,1,1,2,0,0,0,1,0,1 -"0","lbt < %L >%O","ok",0,0.00262385,1,0,0,0,1,0,0,0,1,0,1 -"1","ltl2tgba -s %f >%O","ok",0,0.0261614,1,1,1,1,1,0,0,1,200,4199,1 -"1","spin -f %s >%O","ok",0,0.0137128,2,2,2,1,2,0,0,1,201,4220,2 -"1","lbt < %L >%O","ok",0,0.00792516,3,3,3,0,3,0,0,1,222,4653,23 -"!((1) U (F(!(p0))))","ltl2tgba -s %f >%O","ok",0,0.043858,1,1,1,1,1,0,0,0,200,2059,1 -"!((1) U (F(!(p0))))","spin -f %s >%O","ok",0,0.00202537,1,1,1,1,1,0,0,0,200,2059,1 -"!((1) U (F(!(p0))))","lbt < %L >%O","ok",0,0.00331618,2,2,2,0,2,0,0,0,201,2071,2 -"(1) U (F(!(p0)))","ltl2tgba -s %f >%O","ok",0,0.031689,2,3,4,1,2,0,0,1,400,8264,2 -"(1) U (F(!(p0)))","spin -f %s >%O","ok",0,0.0026263,2,3,5,1,2,1,1,1,400,10337,2 -"(1) U (F(!(p0)))","lbt < %L >%O","ok",0,0.00266354,7,13,22,2,7,4,1,1,1201,35191,604 -"(1) U ((G(p0)) | (F(p1)))","ltl2tgba -s %f >%O","ok",0,0.0287222,3,5,11,1,3,1,1,0,600,11358,3 -"(1) U ((G(p0)) | (F(p1)))","spin -f %s >%O","ok",0,0.00167423,4,8,24,1,4,2,1,0,800,24920,4 -"(1) U ((G(p0)) | (F(p1)))","lbt < %L >%O","ok",0,0.0016987,9,17,52,2,9,4,1,0,1601,41559,805 -"!((1) U ((G(p0)) | (F(p1))))","ltl2tgba -s %f >%O","ok",0,0.0308937,2,4,4,1,1,0,0,0,395,3964,1 -"!((1) U ((G(p0)) | (F(p1))))","spin -f %s >%O","ok",0,0.0230605,6,18,17,1,4,5,1,0,592,8891,1 -"!((1) U ((G(p0)) | (F(p1))))","lbt < %L >%O","ok",0,0.00280787,3,6,9,1,2,3,1,0,397,5957,2 -#+end_example +| formula | tool | exit_status | exit_code | time | states | edges | transitions | acc | scc | nondet_states | nondet_aut | complete_aut | product_states | product_transitions | product_scc | +|-------------------------------+--------------------+-------------+-----------+------------+--------+-------+-------------+-----+-----+---------------+------------+--------------+----------------+---------------------+-------------| +| 0 | ltl2tgba -s %f >%O | ok | 0 | 0.0269145 | 1 | 1 | 0 | 1 | 1 | 0 | 0 | 0 | 1 | 0 | 1 | +| 0 | spin -f %s >%O | ok | 0 | 0.00112819 | 2 | 2 | 1 | 1 | 2 | 0 | 0 | 0 | 1 | 0 | 1 | +| 0 | lbt < %L >%O | ok | 0 | 0.00228413 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 1 | +| 1 | ltl2tgba -s %f >%O | ok | 0 | 0.0269548 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | 200 | 4199 | 1 | +| 1 | spin -f %s >%O | ok | 0 | 0.00121962 | 2 | 2 | 2 | 1 | 2 | 0 | 0 | 1 | 201 | 4220 | 2 | +| 1 | lbt < %L >%O | ok | 0 | 0.00206923 | 3 | 3 | 3 | 0 | 3 | 0 | 0 | 1 | 222 | 4653 | 23 | +| !(F(!(p0))) | ltl2tgba -s %f >%O | ok | 0 | 0.0293213 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 200 | 2059 | 1 | +| !(F(!(p0))) | spin -f %s >%O | ok | 0 | 0.00114213 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 200 | 2059 | 1 | +| !(F(!(p0))) | lbt < %L >%O | ok | 0 | 0.00281165 | 2 | 2 | 2 | 0 | 2 | 0 | 0 | 0 | 201 | 2071 | 2 | +| F(!(p0)) | ltl2tgba -s %f >%O | ok | 0 | 0.0273697 | 2 | 3 | 4 | 1 | 2 | 0 | 0 | 1 | 400 | 8264 | 2 | +| F(!(p0)) | spin -f %s >%O | ok | 0 | 0.00110435 | 2 | 3 | 5 | 1 | 2 | 1 | 1 | 1 | 400 | 10337 | 2 | +| F(!(p0)) | lbt < %L >%O | ok | 0 | 0.00205025 | 4 | 6 | 10 | 1 | 4 | 2 | 1 | 1 | 601 | 14497 | 203 | +| F((G(p0)) \vert{} (F(p1))) | ltl2tgba -s %f >%O | ok | 0 | 0.0283784 | 3 | 5 | 11 | 1 | 3 | 1 | 1 | 0 | 600 | 11358 | 3 | +| F((G(p0)) \vert{} (F(p1))) | spin -f %s >%O | ok | 0 | 0.00144813 | 4 | 8 | 24 | 1 | 4 | 2 | 1 | 0 | 800 | 24920 | 4 | +| F((G(p0)) \vert{} (F(p1))) | lbt < %L >%O | ok | 0 | 0.00218541 | 9 | 17 | 52 | 2 | 9 | 4 | 1 | 0 | 1601 | 41559 | 805 | +| !(F((G(p0)) \vert{} (F(p1)))) | ltl2tgba -s %f >%O | ok | 0 | 0.026898 | 2 | 4 | 4 | 1 | 1 | 0 | 0 | 0 | 395 | 3964 | 1 | +| !(F((G(p0)) \vert{} (F(p1)))) | spin -f %s >%O | ok | 0 | 0.00365003 | 2 | 3 | 5 | 1 | 1 | 1 | 1 | 0 | 396 | 4964 | 1 | +| !(F((G(p0)) \vert{} (F(p1)))) | lbt < %L >%O | ok | 0 | 0.00184477 | 3 | 6 | 9 | 1 | 2 | 3 | 1 | 0 | 397 | 5957 | 2 | This file can be loaded in any spreadsheet or statistical application. @@ -453,11 +437,11 @@ If we had used the option =--json=results.json= instead of (or in addition to) =--cvs=results.csv=, the file =results.json= would have contained the following [[http://www.json.org/][JSON]] output. -#+BEGIN_SRC sh :results verbatim :exports results +#+BEGIN_SRC sh :exports results :wrap SRC json cat results.json #+END_SRC #+RESULTS: -#+begin_example +#+begin_SRC json { "tool": [ "ltl2tgba -s %f >%O", @@ -467,37 +451,37 @@ cat results.json "formula": [ "0", "1", - "!((1) U (F(!(p0))))", - "(1) U (F(!(p0)))", - "(1) U ((G(p0)) | (F(p1)))", - "!((1) U ((G(p0)) | (F(p1))))" + "!(F(!(p0)))", + "F(!(p0))", + "F((G(p0)) | (F(p1)))", + "!(F((G(p0)) | (F(p1))))" ], "fields": [ "formula","tool","exit_status","exit_code","time","states","edges","transitions","acc","scc","nondet_states","nondet_aut","complete_aut","product_states","product_transitions","product_scc" ], "inputs": [ 0, 1 ], "results": [ - [ 0,0,"ok",0,0.0299298,1,1,0,1,1,0,0,0,1,0,1 ], - [ 0,1,"ok",0,0.00396246,2,2,1,1,2,0,0,0,1,0,1 ], - [ 0,2,"ok",0,0.00262385,1,0,0,0,1,0,0,0,1,0,1 ], - [ 1,0,"ok",0,0.0261614,1,1,1,1,1,0,0,1,200,4199,1 ], - [ 1,1,"ok",0,0.0137128,2,2,2,1,2,0,0,1,201,4220,2 ], - [ 1,2,"ok",0,0.00792516,3,3,3,0,3,0,0,1,222,4653,23 ], - [ 2,0,"ok",0,0.043858,1,1,1,1,1,0,0,0,200,2059,1 ], - [ 2,1,"ok",0,0.00202537,1,1,1,1,1,0,0,0,200,2059,1 ], - [ 2,2,"ok",0,0.00331618,2,2,2,0,2,0,0,0,201,2071,2 ], - [ 3,0,"ok",0,0.031689,2,3,4,1,2,0,0,1,400,8264,2 ], - [ 3,1,"ok",0,0.0026263,2,3,5,1,2,1,1,1,400,10337,2 ], - [ 3,2,"ok",0,0.00266354,7,13,22,2,7,4,1,1,1201,35191,604 ], - [ 4,0,"ok",0,0.0287222,3,5,11,1,3,1,1,0,600,11358,3 ], - [ 4,1,"ok",0,0.00167423,4,8,24,1,4,2,1,0,800,24920,4 ], - [ 4,2,"ok",0,0.0016987,9,17,52,2,9,4,1,0,1601,41559,805 ], - [ 5,0,"ok",0,0.0308937,2,4,4,1,1,0,0,0,395,3964,1 ], - [ 5,1,"ok",0,0.0230605,6,18,17,1,4,5,1,0,592,8891,1 ], - [ 5,2,"ok",0,0.00280787,3,6,9,1,2,3,1,0,397,5957,2 ] + [ 0,0,"ok",0,0.0137672,1,1,0,1,1,0,0,0,1,0,1 ], + [ 0,1,"ok",0,0.000908285,2,2,1,1,2,0,0,0,1,0,1 ], + [ 0,2,"ok",0,0.00133153,1,0,0,0,1,0,0,0,1,0,1 ], + [ 1,0,"ok",0,0.0135283,1,1,1,1,1,0,0,1,200,4199,1 ], + [ 1,1,"ok",0,0.000828822,2,2,2,1,2,0,0,1,201,4220,2 ], + [ 1,2,"ok",0,0.00134064,3,3,3,0,3,0,0,1,222,4653,23 ], + [ 2,0,"ok",0,0.0140072,1,1,1,1,1,0,0,0,200,2059,1 ], + [ 2,1,"ok",0,0.00081293,1,1,1,1,1,0,0,0,200,2059,1 ], + [ 2,2,"ok",0,0.00134737,2,2,2,0,2,0,0,0,201,2071,2 ], + [ 3,0,"ok",0,0.0137064,2,3,4,1,2,0,0,1,400,8264,2 ], + [ 3,1,"ok",0,0.000911401,2,3,5,1,2,1,1,1,400,10337,2 ], + [ 3,2,"ok",0,0.00130378,4,6,10,1,4,2,1,1,601,14497,203 ], + [ 4,0,"ok",0,0.0144879,3,5,11,1,3,1,1,0,600,11358,3 ], + [ 4,1,"ok",0,0.00103421,4,8,24,1,4,2,1,0,800,24920,4 ], + [ 4,2,"ok",0,0.0013883,9,17,52,2,9,4,1,0,1601,41559,805 ], + [ 5,0,"ok",0,0.0142669,2,4,4,1,1,0,0,0,395,3964,1 ], + [ 5,1,"ok",0,0.00240013,2,3,5,1,1,1,1,0,396,4964,1 ], + [ 5,2,"ok",0,0.00134713,3,6,9,1,2,3,1,0,397,5957,2 ] ] } -#+end_example +#+end_SRC Here the =fields= table describes the columns of the =results= table. The =inputs= tables lists the columns that are considered as inputs @@ -535,8 +519,8 @@ for i in range(0, len(data["tool"])): #+RESULTS: : tool & count & time & states & edges & transitions & acc & scc & nondet_states & nondet_aut & complete_aut & product_states & product_transitions & product_scc \\ : ltl2tgba -s %f >%O & 6 & 0.0 & 1.7 & 2.5 & 3.5 & 1.0 & 1.5 & 0.2 & 0.2 & 0.3 & 299.3 & 4974.0 & 1.5 \\ -: spin -f %s >%O & 6 & 0.0 & 2.8 & 5.7 & 8.3 & 1.0 & 2.5 & 1.3 & 0.5 & 0.3 & 365.7 & 8404.5 & 1.8 \\ -: lbt < %L >%O & 6 & 0.0 & 4.2 & 6.8 & 14.7 & 0.8 & 4.0 & 1.8 & 0.5 & 0.3 & 603.8 & 14905.2 & 239.5 \\ +: spin -f %s >%O & 6 & 0.0 & 2.2 & 3.2 & 6.3 & 1.0 & 2.0 & 0.7 & 0.5 & 0.3 & 333.0 & 7750.0 & 1.8 \\ +: lbt < %L >%O & 6 & 0.0 & 3.7 & 5.7 & 12.7 & 0.7 & 3.5 & 1.5 & 0.5 & 0.3 & 503.8 & 11456.2 & 172.7 \\ The script =bench/ltl2tgba/sum.py= is a more evolved version of the above script that generates two kinds of LaTeX tables. @@ -589,43 +573,14 @@ sets. When building (degeneralized) Büchi automata, it will always be =1=, so its value is meaningful only when evaluating translations to generalized Büchi automata. =edges= counts the actual number of edges in the graph supporting the automaton; an edge (labeled by a Boolean -formula) might actually represent several transitions (each labeled by +formula) [[file:concepts.org::#trans-edge][might actually represent several transitions]] (each labeled by assignment of all atomic propositions). For instance in an automaton where the atomic proposition are $a$ and $b$, one edge labeled by $a\lor b$ actually represents three transitions $a b$, $a\bar b$, and $\bar a b$. -The following picture displays two automata for the LTL formula =a U -b=. They both have 2 states and 3 edges, however they differ in the -number of transitions (7 versus 8), because the initial self-loop is -more constrained in the first automaton. A smaller number of -transition is therefore an indication of a more constrained automaton. - -#+BEGIN_SRC dot :file edges.svg :exports results -digraph G { - 0 [label="", style=invis, height=0] - 0 -> 1 - 1 [label="A1"] - 1 -> 2 [label="b\n"] - 1 -> 1 [label="a & !b\n"] - 2 [label="B1", peripheries=2] - 2 -> 2 [label="1"] - - 3 [label="", style=invis, height=0] - 3 -> 4 - 4 [label="A2"] - 4 -> 5 [label="b\n"] - 4 -> 4 [label="a\n"] - 5 [label="B2", peripheries=2] - 5 -> 5 [label="1"] -} -#+END_SRC - -#+RESULTS: -[[file:edges.svg]] - - -=scc= counts the number of strongly-connected components in the automaton. +=scc= counts the number of strongly-connected components in the +automaton. If option =--strength= is passed to =ltlcross=, these SCCs are also partitioned on four sets based on their strengths: @@ -713,19 +668,38 @@ For instance in the following, =ltl2tgba= is run in two configurations, and the strings =ltl2tgba -s --small %f >%O= and =ltl2tgba -s --deter %f >%O= appear verbatim in the output: -#+BEGIN_SRC sh :results verbatim :exports both +#+NAME: ltlcross-unnamed +#+BEGIN_SRC sh :exports code ltlcross -f a -f Ga 'ltl2tgba -s --small %f >%O' 'ltl2tgba -s --deter %f >%O' --csv #+END_SRC + +#+BEGIN_SRC sh :results output raw :exports results :noweb yes +sed 's/"//g +s/|/\\vert{}/g +s/--/@@html:--@@/g +s/^/| / +s/$/ |/ +s/,/|/g +$d +1a\ +|-| +' <> +EOF +#+END_SRC + +#+ATTR_HTML: :class csv-table #+RESULTS: -: "formula","tool","exit_status","exit_code","time","states","edges","transitions","acc","scc","nondet_states","nondet_aut","complete_aut","product_states","product_transitions","product_scc" -: "a","ltl2tgba -s --small %f >%O","ok",0,0.0129968,2,2,3,1,2,0,0,0,201,4144,2 -: "a","ltl2tgba -s --deter %f >%O","ok",0,0.0116347,2,2,3,1,2,0,0,0,201,4144,2 -: "!(a)","ltl2tgba -s --small %f >%O","ok",0,0.0127019,2,2,3,1,2,0,0,0,201,4149,2 -: "!(a)","ltl2tgba -s --deter %f >%O","ok",0,0.0117374,2,2,3,1,2,0,0,0,201,4149,2 -: "G(a)","ltl2tgba -s --small %f >%O","ok",0,0.0126186,1,1,1,1,1,0,0,0,200,2059,1 -: "G(a)","ltl2tgba -s --deter %f >%O","ok",0,0.011645,1,1,1,1,1,0,0,0,200,2059,1 -: "!(G(a))","ltl2tgba -s --small %f >%O","ok",0,0.0129519,2,3,4,1,2,0,0,1,400,8264,2 -: "!(G(a))","ltl2tgba -s --deter %f >%O","ok",0,0.0129941,2,3,4,1,2,0,0,1,400,8264,2 +| formula | tool | exit_status | exit_code | time | states | edges | transitions | acc | scc | nondet_states | nondet_aut | complete_aut | product_states | product_transitions | product_scc | +|---------+-------------------------------------+-------------+-----------+-----------+--------+-------+-------------+-----+-----+---------------+------------+--------------+----------------+---------------------+-------------| +| a | ltl2tgba -s @@html:--@@small %f >%O | ok | 0 | 0.045425 | 2 | 2 | 3 | 1 | 2 | 0 | 0 | 0 | 201 | 4144 | 2 | +| a | ltl2tgba -s @@html:--@@deter %f >%O | ok | 0 | 0.0452103 | 2 | 2 | 3 | 1 | 2 | 0 | 0 | 0 | 201 | 4144 | 2 | +| !(a) | ltl2tgba -s @@html:--@@small %f >%O | ok | 0 | 0.0475807 | 2 | 2 | 3 | 1 | 2 | 0 | 0 | 0 | 201 | 4149 | 2 | +| !(a) | ltl2tgba -s @@html:--@@deter %f >%O | ok | 0 | 0.0441754 | 2 | 2 | 3 | 1 | 2 | 0 | 0 | 0 | 201 | 4149 | 2 | +| G(a) | ltl2tgba -s @@html:--@@small %f >%O | ok | 0 | 0.0453961 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 200 | 2059 | 1 | +| G(a) | ltl2tgba -s @@html:--@@deter %f >%O | ok | 0 | 0.0467509 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 200 | 2059 | 1 | +| !(G(a)) | ltl2tgba -s @@html:--@@small %f >%O | ok | 0 | 0.0459274 | 2 | 3 | 4 | 1 | 2 | 0 | 0 | 1 | 400 | 8264 | 2 | +| !(G(a)) | ltl2tgba -s @@html:--@@deter %f >%O | ok | 0 | 0.04534 | 2 | 3 | 4 | 1 | 2 | 0 | 0 | 1 | 400 | 8264 | 2 | To present these results graphically, or even when analyzing these data, it might be convenient to give each configured tool a shorter @@ -733,37 +707,50 @@ name. =ltlcross= supports the specification of such short names by looking whether the command specification for a translator has the form "={short name}actual command=". -For instance: -#+BEGIN_SRC sh :results verbatim :exports both +For instance, after +#+BEGIN_SRC sh :exports code genltl --and-f=1..5 | ltlcross '{small} ltl2tgba -s --small %f >%O' \ '{deter} ltl2tgba -s --deter %f >%O' --csv=ltlcross.csv -cat ltlcross.csv #+END_SRC + +The file =ltlcross.csv= now contains: +#+BEGIN_SRC sh :results output raw :exports results +sed 's/"//g +s/|/\\vert{}/g +s/--/@@html:--@@/g +s/^/| / +s/$/ |/ +s/,/|/g +$d +1a\ +|-| +' ltlcross.csv +#+END_SRC + +#+ATTR_HTML: :class csv-table #+RESULTS: -#+begin_example -"formula","tool","exit_status","exit_code","time","states","edges","transitions","acc","scc","nondet_states","nondet_aut","complete_aut","product_states","product_transitions","product_scc" -"F(p1)","small","ok",0,0.0138108,2,3,4,1,2,0,0,1,400,8272,3 -"F(p1)","deter","ok",0,0.0142178,2,3,4,1,2,0,0,1,400,8272,3 -"!(F(p1))","small","ok",0,0.013972,1,1,1,1,1,0,0,0,200,2055,2 -"!(F(p1))","deter","ok",0,0.0139471,1,1,1,1,1,0,0,0,200,2055,2 -"(F(p1)) & (F(p2))","small","ok",0,0.0136648,4,9,16,1,4,0,0,1,798,16533,5 -"(F(p1)) & (F(p2))","deter","ok",0,0.0140229,4,9,16,1,4,0,0,1,798,16533,5 -"!((F(p1)) & (F(p2)))","small","ok",0,0.0144659,3,5,7,1,3,0,0,0,598,7367,4 -"!((F(p1)) & (F(p2)))","deter","ok",0,0.0143098,3,5,7,1,3,0,0,0,598,7367,4 -"(F(p1)) & (F(p2)) & (F(p3))","small","ok",0,0.0142109,8,27,64,1,8,0,0,1,1587,33068,34 -"(F(p1)) & (F(p2)) & (F(p3))","deter","ok",0,0.0149064,8,27,64,1,8,0,0,1,1587,33068,34 -"!((F(p1)) & (F(p2)) & (F(p3)))","small","ok",0,0.0159551,4,6,24,1,4,1,1,0,601,6171,4 -"!((F(p1)) & (F(p2)) & (F(p3)))","deter","ok",0,0.0143288,7,19,37,1,7,0,0,0,1387,18792,33 -"(F(p1)) & (F(p2)) & (F(p3)) & (F(p4))","small","ok",0,0.0152539,16,81,256,1,16,0,0,1,2727,57786,74 -"(F(p1)) & (F(p2)) & (F(p3)) & (F(p4))","deter","ok",0,0.0155381,16,81,256,1,16,0,0,1,2727,57786,74 -"!((F(p1)) & (F(p2)) & (F(p3)) & (F(p4)))","small","ok",0,0.015231,5,8,64,1,5,1,1,0,801,8468,5 -"!((F(p1)) & (F(p2)) & (F(p3)) & (F(p4)))","deter","ok",0,0.0157937,15,65,175,1,15,0,0,0,2527,37226,73 -"(F(p1)) & (F(p2)) & (F(p3)) & (F(p4)) & (F(p5))","small","ok",0,0.017919,32,243,1024,1,32,0,0,1,5330,114068,350 -"(F(p1)) & (F(p2)) & (F(p3)) & (F(p4)) & (F(p5))","deter","ok",0,0.0167644,32,243,1024,1,32,0,0,1,5330,114068,350 -"!((F(p1)) & (F(p2)) & (F(p3)) & (F(p4)) & (F(p5)))","small","ok",0,0.0187427,6,10,160,1,6,1,1,0,1000,10707,6 -"!((F(p1)) & (F(p2)) & (F(p3)) & (F(p4)) & (F(p5)))","deter","ok",0,0.0183562,31,211,781,1,31,0,0,0,5130,82897,349 -#+end_example +| formula | tool | exit_status | exit_code | time | states | edges | transitions | acc | scc | nondet_states | nondet_aut | complete_aut | product_states | product_transitions | product_scc | +|----------------------------------------------------+-------+-------------+-----------+-----------+--------+-------+-------------+-----+-----+---------------+------------+--------------+----------------+---------------------+-------------| +| F(p1) | small | ok | 0 | 0.0143077 | 2 | 3 | 4 | 1 | 2 | 0 | 0 | 1 | 400 | 8272 | 3 | +| F(p1) | deter | ok | 0 | 0.0143547 | 2 | 3 | 4 | 1 | 2 | 0 | 0 | 1 | 400 | 8272 | 3 | +| !(F(p1)) | small | ok | 0 | 0.0146721 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 200 | 2055 | 2 | +| !(F(p1)) | deter | ok | 0 | 0.0145825 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 200 | 2055 | 2 | +| (F(p1)) & (F(p2)) | small | ok | 0 | 0.0147275 | 4 | 9 | 16 | 1 | 4 | 0 | 0 | 1 | 798 | 16533 | 5 | +| (F(p1)) & (F(p2)) | deter | ok | 0 | 0.0144936 | 4 | 9 | 16 | 1 | 4 | 0 | 0 | 1 | 798 | 16533 | 5 | +| !((F(p1)) & (F(p2))) | small | ok | 0 | 0.0147704 | 3 | 5 | 7 | 1 | 3 | 0 | 0 | 0 | 598 | 7367 | 4 | +| !((F(p1)) & (F(p2))) | deter | ok | 0 | 0.0146198 | 3 | 5 | 7 | 1 | 3 | 0 | 0 | 0 | 598 | 7367 | 4 | +| (F(p1)) & (F(p2)) & (F(p3)) | small | ok | 0 | 0.0153116 | 8 | 27 | 64 | 1 | 8 | 0 | 0 | 1 | 1587 | 33068 | 34 | +| (F(p1)) & (F(p2)) & (F(p3)) | deter | ok | 0 | 0.0156095 | 8 | 27 | 64 | 1 | 8 | 0 | 0 | 1 | 1587 | 33068 | 34 | +| !((F(p1)) & (F(p2)) & (F(p3))) | small | ok | 0 | 0.015041 | 4 | 6 | 24 | 1 | 4 | 1 | 1 | 0 | 601 | 6171 | 4 | +| !((F(p1)) & (F(p2)) & (F(p3))) | deter | ok | 0 | 0.0151199 | 7 | 19 | 37 | 1 | 7 | 0 | 0 | 0 | 1387 | 18792 | 33 | +| (F(p1)) & (F(p2)) & (F(p3)) & (F(p4)) | small | ok | 0 | 0.0166691 | 16 | 81 | 256 | 1 | 16 | 0 | 0 | 1 | 2727 | 57786 | 74 | +| (F(p1)) & (F(p2)) & (F(p3)) & (F(p4)) | deter | ok | 0 | 0.0161634 | 16 | 81 | 256 | 1 | 16 | 0 | 0 | 1 | 2727 | 57786 | 74 | +| !((F(p1)) & (F(p2)) & (F(p3)) & (F(p4))) | small | ok | 0 | 0.0167047 | 5 | 8 | 64 | 1 | 5 | 1 | 1 | 0 | 801 | 8468 | 5 | +| !((F(p1)) & (F(p2)) & (F(p3)) & (F(p4))) | deter | ok | 0 | 0.0160785 | 15 | 65 | 175 | 1 | 15 | 0 | 0 | 0 | 2527 | 37226 | 73 | +| (F(p1)) & (F(p2)) & (F(p3)) & (F(p4)) & (F(p5)) | small | ok | 0 | 0.018485 | 32 | 243 | 1024 | 1 | 32 | 0 | 0 | 1 | 5330 | 114068 | 350 | +| (F(p1)) & (F(p2)) & (F(p3)) & (F(p4)) & (F(p5)) | deter | ok | 0 | 0.0209914 | 32 | 243 | 1024 | 1 | 32 | 0 | 0 | 1 | 5330 | 114068 | 350 | +| !((F(p1)) & (F(p2)) & (F(p3)) & (F(p4)) & (F(p5))) | small | ok | 0 | 0.0196063 | 6 | 10 | 160 | 1 | 6 | 1 | 1 | 0 | 1000 | 10707 | 6 | In this last example, we saved the CSV output to =ltlcross.csv= so we can play with it in the next section. @@ -773,19 +760,21 @@ can play with it in the next section. The produced CSV should be directly readable by R's CSV input functions like =read.csv()=, =readr::read_csv()=, or =data.table::fread()=. -#+BEGIN_SRC R :session :results output :exports both +#+BEGIN_SRC R library(data.table) dt <- fread('ltlcross.csv') str(dt) #+END_SRC #+RESULTS: #+begin_example +data.table 1.12.0 Latest news: r-datatable.com + Classes ‘data.table’ and 'data.frame': 20 obs. of 16 variables: $ formula : chr "F(p1)" "F(p1)" "!(F(p1))" "!(F(p1))" ... $ tool : chr "small" "deter" "small" "deter" ... $ exit_status : chr "ok" "ok" "ok" "ok" ... $ exit_code : int 0 0 0 0 0 0 0 0 0 0 ... - $ time : num 0.0133 0.0133 0.0139 0.0128 0.0144 ... + $ time : num 0.0284 0.0283 0.0283 0.0282 0.029 ... $ states : int 2 2 1 1 4 4 3 3 8 8 ... $ edges : int 3 3 1 1 9 9 5 5 27 27 ... $ transitions : int 4 4 1 1 16 16 7 7 64 64 ... @@ -808,21 +797,22 @@ A common transformation is to group the results of all tools on the same line: using exactly one line per formula. This is easily achieved using =dcast()= from the =data.table= library. -#+BEGIN_SRC R :session :results output :exports both +#+BEGIN_SRC R dt2 <- dcast(dt, formula ~ tool, value.var=names(dt)[-(1:2)], sep=".") str(dt2) #+END_SRC #+RESULTS: #+begin_example + Classes ‘data.table’ and 'data.frame': 10 obs. of 29 variables: $ formula : chr "!((F(p1)) & (F(p2)) & (F(p3)) & (F(p4)) & (F(p5)))" "!((F(p1)) & (F(p2)) & (F(p3)) & (F(p4)))" "!((F(p1)) & (F(p2)) & (F(p3)))" "!((F(p1)) & (F(p2)))" ... $ exit_status.deter : chr "ok" "ok" "ok" "ok" ... $ exit_status.small : chr "ok" "ok" "ok" "ok" ... $ exit_code.deter : int 0 0 0 0 0 0 0 0 0 0 $ exit_code.small : int 0 0 0 0 0 0 0 0 0 0 - $ time.deter : num 0.0174 0.0149 0.0141 0.0136 0.0128 ... - $ time.small : num 0.0171 0.0155 0.0152 0.0146 0.0139 ... + $ time.deter : num 0.0172 0.0212 0.02 0.0191 0.0282 ... + $ time.small : num 0.0172 0.0221 0.0203 0.0195 0.0283 ... $ states.deter : int 31 15 7 3 1 4 8 16 32 2 $ states.small : int 6 5 4 3 1 4 8 16 32 2 $ edges.deter : int 211 65 19 5 1 9 27 81 243 3 @@ -855,7 +845,7 @@ compare the number of states produced by the two configurations of =ltl2tgba= for each formula, we just need to plot column =dt2$state.small= against =dt2$state.deter=. -#+BEGIN_SRC R :session :results output graphics :width 5 :height 5 :file ltlcross-r.svg :exports both +#+BEGIN_SRC R :results output graphics :width 5 :height 5 :file ltlcross-r.svg library(ggplot2) ggplot(dt2, aes(x=states.small, y=states.deter)) + geom_abline(colour='white') + geom_point() @@ -868,10 +858,10 @@ ggplot(dt2, aes(x=states.small, y=states.deter)) + We should probably print the formulas for the cases where the two sizes differ. -#+BEGIN_SRC R :session :results output graphics :width 5 :height 5 :file ltlcross-r2.svg :exports both +#+BEGIN_SRC R :results output graphics :width 5 :height 5 :file ltlcross-r2.svg ggplot(dt2, aes(x=states.small, y=states.deter)) + geom_abline(colour='white') + geom_point() + - geom_text(data=subset(df2, states.small != states.deter), + geom_text(data=subset(dt2, states.small != states.deter), aes(label=formula), hjust=0, nudge_x=.5) #+END_SRC @@ -942,52 +932,47 @@ If =--save-bogus=OTHERFILENAME= is provided, every bogus formula found during the process will be saved in =OTHERFILENAME=. Example: -#+BEGIN_SRC sh :exports code :results verbatim +#+BEGIN_SRC sh :prologue "exec 2>&1" :epilogue true ltlcross -f '(G!b & (!c | F!a)) | (c & Ga & Fb)' "modella %L %O" \ --save-bogus=bogus \ --grind=bogus-grind #+END_SRC -#+BEGIN_SRC sh :exports results :results verbatim -ltlcross -f '(G!b & (!c | F!a)) | (c & Ga & Fb)' "modella %L %O" \ - --save-bogus=bogus --grind=bogus-grind 2>&1 -true -#+END_SRC #+RESULTS: #+begin_example | & G ! p0 | ! p1 F ! p2 & & p1 G p2 F p0 -Running [P0]: modella 'lcr-i0-FUPmeY' 'lcr-o0-F3bZRp' -Running [N0]: modella 'lcr-i0-ebjQwR' 'lcr-o0-20eIbj' +Running [P0]: modella 'lcr-i0-Nc8B1P' 'lcr-o0-CDjvYF' +Running [N0]: modella 'lcr-i0-Io4LVv' 'lcr-o0-C482Sl' Performing sanity checks and gathering statistics... error: P0*N0 is nonempty; both automata accept the infinite word: cycle{!p0 & !p1} Trying to find a bogus mutation of (G!b & (!c | F!a)) | (c & Ga & Fb)... Mutation 1/22: & & p0 G p1 F p2 -Running [P0]: modella 'lcr-i1-zXEyXK' 'lcr-o0-RsypJc' -Running [N0]: modella 'lcr-i1-Ux7xvE' 'lcr-o0-x19Gh6' +Running [P0]: modella 'lcr-i1-EmhjSb' 'lcr-o0-q1GzR1' +Running [N0]: modella 'lcr-i1-mwR1QR' 'lcr-o0-gEcuQH' Performing sanity checks and gathering statistics... Mutation 2/22: & G ! p0 | ! p1 F ! p2 -Running [P0]: modella 'lcr-i2-syS74x' 'lcr-o0-wPRySZ' -Running [N0]: modella 'lcr-i2-x9DdGr' 'lcr-o0-fgHStT' +Running [P0]: modella 'lcr-i2-4UoNQx' 'lcr-o0-W9W6Qn' +Running [N0]: modella 'lcr-i2-h5IDRd' 'lcr-o0-VDFaS3' Performing sanity checks and gathering statistics... Mutation 3/22: | G ! p0 & & p1 G p2 F p0 -Running [P0]: modella 'lcr-i3-rVOAil' 'lcr-o0-jU2i7M' -Running [N0]: modella 'lcr-i3-KATfWe' 'lcr-o0-2UOcLG' +Running [P0]: modella 'lcr-i3-bkvvTT' 'lcr-o0-wMAQUJ' +Running [N0]: modella 'lcr-i3-qoYoWz' 'lcr-o0-ILwXXp' Performing sanity checks and gathering statistics... error: P0*N0 is nonempty; both automata accept the infinite word: cycle{!p0 & !p1} Trying to find a bogus mutation of G!b | (c & Ga & Fb)... Mutation 1/16: t -Running [P0]: modella 'lcr-i4-OJk2B8' 'lcr-o0-VVCSsA' -Running [N0]: modella 'lcr-i4-nKwTj2' 'lcr-o0-npMUau' +Running [P0]: modella 'lcr-i4-avS30f' 'lcr-o0-MYCa45' +Running [N0]: modella 'lcr-i4-vJss7V' 'lcr-o0-ItCKaM' Performing sanity checks and gathering statistics... Mutation 2/16: G ! p0 -Running [P0]: modella 'lcr-i5-Waoe2V' 'lcr-o0-9wsyTn' -Running [N0]: modella 'lcr-i5-M0R2KP' 'lcr-o0-uhmxCh' +Running [P0]: modella 'lcr-i5-TG7leC' 'lcr-o0-N6UXhs' +Running [N0]: modella 'lcr-i5-KwJJli' 'lcr-o0-kbRvp8' Performing sanity checks and gathering statistics... Mutation 3/16: & & p0 G p1 F p2 @@ -995,8 +980,8 @@ warning: This formula or its negation has already been checked. Use --allow-dups if it should not be ignored. Mutation 4/16: | G ! p0 & p1 F p0 -Running [P0]: modella 'lcr-i6-OtIGuJ' 'lcr-o0-qBEQmb' -Running [N0]: modella 'lcr-i6-MGbcfD' 'lcr-o0-t93x74' +Running [P0]: modella 'lcr-i6-otaRtY' 'lcr-o0-bRLcyO' +Running [N0]: modella 'lcr-i6-3DMJCE' 'lcr-o0-v04gHu' Performing sanity checks and gathering statistics... error: P0*N0 is nonempty; both automata accept the infinite word: cycle{!p0 & !p1} @@ -1011,38 +996,38 @@ warning: This formula or its negation has already been checked. Use --allow-dups if it should not be ignored. Mutation 3/10: & p0 F p1 -Running [P0]: modella 'lcr-i7-4oa00w' 'lcr-o0-3IEsUY' -Running [N0]: modella 'lcr-i7-vyy5Nq' 'lcr-o0-nXOIHS' +Running [P0]: modella 'lcr-i7-gKcHMk' 'lcr-o0-UPD7Ra' +Running [N0]: modella 'lcr-i7-4HUKX0' 'lcr-o0-Dpno3Q' Performing sanity checks and gathering statistics... Mutation 4/10: | p0 G ! p1 -Running [P0]: modella 'lcr-i8-Kt48Bk' 'lcr-o0-xeIzwM' -Running [N0]: modella 'lcr-i8-ye5are' 'lcr-o0-3QMMlG' +Running [P0]: modella 'lcr-i8-H6GH9G' 'lcr-o0-xyO1fx' +Running [N0]: modella 'lcr-i8-w3vxmn' 'lcr-o0-wgw3sd' Performing sanity checks and gathering statistics... Mutation 5/10: | G ! p0 F p0 -Running [P0]: modella 'lcr-i9-Bpmah8' 'lcr-o0-38lycA' -Running [N0]: modella 'lcr-i9-cQJ771' 'lcr-o0-yUcH3t' +Running [P0]: modella 'lcr-i9-vt8eA3' 'lcr-o0-982qHT' +Running [N0]: modella 'lcr-i9-qrbNOJ' 'lcr-o0-ceD9Vz' Performing sanity checks and gathering statistics... Mutation 6/10: | ! p0 & p1 F p0 -Running [P0]: modella 'lcr-i10-mYtDZV' 'lcr-o0-nCdAVn' -Running [N0]: modella 'lcr-i10-d1fIRP' 'lcr-o0-oAsQNh' +Running [P0]: modella 'lcr-i10-6upQ3p' 'lcr-o0-EStxbg' +Running [N0]: modella 'lcr-i10-7nUoj6' 'lcr-o0-e4DgrW' Performing sanity checks and gathering statistics... Mutation 7/10: | & p1 F p0 G p0 -Running [P0]: modella 'lcr-i11-petsKJ' 'lcr-o0-Z3U4Gb' -Running [N0]: modella 'lcr-i11-bmFSDD' 'lcr-o0-P1DGA5' +Running [P0]: modella 'lcr-i11-ohXyzM' 'lcr-o0-bozRHC' +Running [N0]: modella 'lcr-i11-6wYkQs' 'lcr-o0-TCxOYi' Performing sanity checks and gathering statistics... Mutation 8/10: | & p0 p1 G ! p0 -Running [P0]: modella 'lcr-i12-eUjByx' 'lcr-o0-DZAwwZ' -Running [N0]: modella 'lcr-i12-v3JCur' 'lcr-o0-IzWIsT' +Running [P0]: modella 'lcr-i12-51Vd88' 'lcr-o0-uWKDhZ' +Running [N0]: modella 'lcr-i12-0OkfrP' 'lcr-o0-aEdRAF' Performing sanity checks and gathering statistics... Mutation 9/10: | G ! p0 & p0 F p0 -Running [P0]: modella 'lcr-i13-Sb2Arl' 'lcr-o0-kBwtqN' -Running [N0]: modella 'lcr-i13-Tctwpf' 'lcr-o0-hvIzoH' +Running [P0]: modella 'lcr-i13-vy57Kv' 'lcr-o0-lcfpVl' +Running [N0]: modella 'lcr-i13-D7SQ5b' 'lcr-o0-k8Hig2' Performing sanity checks and gathering statistics... error: P0*N0 is nonempty; both automata accept the infinite word: cycle{!p0} @@ -1057,13 +1042,13 @@ warning: This formula or its negation has already been checked. Use --allow-dups if it should not be ignored. Mutation 3/7: & p0 F p0 -Running [P0]: modella 'lcr-i14-iDAoo9' 'lcr-o0-6vSdoB' -Running [N0]: modella 'lcr-i14-WMIdo3' 'lcr-o0-NxEdov' +Running [P0]: modella 'lcr-i14-AvSorS' 'lcr-o0-AZkvCI' +Running [N0]: modella 'lcr-i14-Hd7LNy' 'lcr-o0-pM82Yo' Performing sanity checks and gathering statistics... Mutation 4/7: | p0 G ! p0 -Running [P0]: modella 'lcr-i15-lS5FoX' 'lcr-o0-XFX8op' -Running [N0]: modella 'lcr-i15-8IdNpR' 'lcr-o0-0Bxrqj' +Running [P0]: modella 'lcr-i15-tygKaf' 'lcr-o0-YHFrm5' +Running [N0]: modella 'lcr-i15-GL9iyV' 'lcr-o0-riOaKL' Performing sanity checks and gathering statistics... Mutation 5/7: | G ! p0 F p0 @@ -1071,13 +1056,13 @@ warning: This formula or its negation has already been checked. Use --allow-dups if it should not be ignored. Mutation 6/7: | ! p0 & p0 F p0 -Running [P0]: modella 'lcr-i16-7boQrL' 'lcr-o0-wsIftd' -Running [N0]: modella 'lcr-i16-tk8OuF' 'lcr-o0-9wQow7' +Running [P0]: modella 'lcr-i16-M0RHWB' 'lcr-o0-iVlf9r' +Running [N0]: modella 'lcr-i16-WD4Xli' 'lcr-o0-Ez6Gy8' Performing sanity checks and gathering statistics... Mutation 7/7: | G p0 & p0 F p0 -Running [P0]: modella 'lcr-i17-wnlkyz' 'lcr-o0-MAjgA1' -Running [N0]: modella 'lcr-i17-qFLnCt' 'lcr-o0-45gvEV' +Running [P0]: modella 'lcr-i17-F1BLLY' 'lcr-o0-Z9nQYO' +Running [N0]: modella 'lcr-i17-efo5bF' 'lcr-o0-fFzkpv' Performing sanity checks and gathering statistics... Smallest bogus mutation found for (G!b & (!c | F!a)) | (c & Ga & Fb) is G!c | (c & Fc). @@ -1086,7 +1071,7 @@ error: some error was detected during the above runs. Check file bogus for problematic formulas. #+end_example -#+BEGIN_SRC sh :exports both :results verbatim +#+BEGIN_SRC sh cat bogus #+END_SRC @@ -1096,7 +1081,7 @@ cat bogus : G!b | (c & Fb) : G!c | (c & Fc) -#+BEGIN_SRC sh :exports both :results verbatim +#+BEGIN_SRC sh cat bogus-grind #+END_SRC @@ -1112,15 +1097,6 @@ When checks are enabled, the negated formulas are intermixed with the positives ones in the results. Therefore the =--no-check= option can be used to gather statistics about a specific set of formulas. - -# LocalWords: ltlcross num toc LTL Büchi LBTT Testbench PSL SRC sed -# LocalWords: automata LBT LBTT's ltl tgba GFa lck iDGV sA FYp BYY -# LocalWords: ClVQg wyErP UNE dQ coM tH eHPoQy goto ba lbt modella -# LocalWords: lbtt csv json randltl ltlfilt wm eGEYaZ nYpFBX fGdZQ -# LocalWords: CPs kXiZZS ILLzR wU CcMCaQ IOckzW tsT RZ TJXmT jb XRO -# LocalWords: nxqfd hS vNItGg acc scc nondetstates nondeterministic -# LocalWords: cvs LaTeX datacols len ith otimes ltlcheck eval setq -# LocalWords: setenv concat getenv ** =--verbose= :PROPERTIES: :CUSTOM_ID: verbose @@ -1134,21 +1110,17 @@ and =ltl3ba -H1= on the formula =FGa=. Note that =ltl2tgba= will produce transition-based generalized Büchi automata, while =ltl3ba -H1= produces co-Büchi alternating automata. -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :prologue "export SPOT_HOA_TOLERANT=1; exec 2>&1" ltlcross -f 'FGa' ltl2tgba 'ltl3ba -H1' --determinize --verbose #+END_SRC -#+BEGIN_SRC sh :results verbatim :exports results -SPOT_HOA_TOLERANT=1 ltlcross -f 'FGa' ltl2tgba 'ltl3ba -H1' --determinize --verbose 2>&1 -#+END_SRC - #+RESULTS: #+begin_example F(G(a)) -Running [P0]: ltl2tgba -H 'F(G(a))'>'lcr-o0-opbyhq' -Running [P1]: ltl3ba -H1 -f '<>([](a))'>'lcr-o1-aP47sS' -Running [N0]: ltl2tgba -H '!(F(G(a)))'>'lcr-o0-UV1eFk' -Running [N1]: ltl3ba -H1 -f '!(<>([](a)))'>'lcr-o1-bFSrTM' +Running [P0]: ltl2tgba -H 'F(G(a))'>'lcr-o0-cNwEjy' +Running [P1]: ltl3ba -H1 -f '<>([](a))'>'lcr-o1-WQo28q' +Running [N0]: ltl2tgba -H '!(F(G(a)))'>'lcr-o0-KT96Zj' +Running [N1]: ltl3ba -H1 -f '!(<>([](a)))'>'lcr-o1-WE1RXc' info: collected automata: info: P0 (2 st.,3 ed.,1 sets) info: N0 (1 st.,2 ed.,1 sets) deterministic complete @@ -1214,21 +1186,17 @@ that the automaton =N0= is really the complement of =P0=. Similarly Note that if we had not used the =--determinize= option, the procedure would look slightly more complex: -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :prologue "export SPOT_HOA_TOLERANT=1; exec 2>&1" ltlcross -f 'FGa' ltl2tgba 'ltl3ba -H1' --verbose #+END_SRC -#+BEGIN_SRC sh :results verbatim :exports results -SPOT_HOA_TOLERANT=1 ltlcross -f 'FGa' ltl2tgba 'ltl3ba -H1' --verbose 2>&1 -#+END_SRC - #+RESULTS: #+begin_example F(G(a)) -Running [P0]: ltl2tgba -H 'F(G(a))'>'lcr-o0-cq9s5c' -Running [P1]: ltl3ba -H1 -f '<>([](a))'>'lcr-o1-Fb0iii' -Running [N0]: ltl2tgba -H '!(F(G(a)))'>'lcr-o0-X5dGvn' -Running [N1]: ltl3ba -H1 -f '!(<>([](a)))'>'lcr-o1-tLO5Ks' +Running [P0]: ltl2tgba -H 'F(G(a))'>'lcr-o0-Ot1KDa' +Running [P1]: ltl3ba -H1 -f '<>([](a))'>'lcr-o1-Kvzdfm' +Running [N0]: ltl2tgba -H '!(F(G(a)))'>'lcr-o0-X2dURx' +Running [N1]: ltl3ba -H1 -f '!(<>([](a)))'>'lcr-o1-wuLpzJ' info: collected automata: info: P0 (2 st.,3 ed.,1 sets) info: N0 (1 st.,2 ed.,1 sets) deterministic complete @@ -1288,21 +1256,17 @@ implementation that should not be checked, and we just want to check the output of =ltl2tgba= against this reference. See how the number of tests performed has been reduced. -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :prologue "export SPOT_HOA_TOLERANT=1; exec 2>&1" ltlcross -f 'FGa' ltl2tgba --reference 'ltl3ba -H1' --verbose #+END_SRC -#+BEGIN_SRC sh :results verbatim :exports results -SPOT_HOA_TOLERANT=1 ltlcross -f 'FGa' ltl2tgba --reference 'ltl3ba -H1' --verbose 2>&1 -#+END_SRC - #+RESULTS: #+begin_example F(G(a)) -Running [P0]: ltl3ba -H1 -f '<>([](a))'>'lcr-o0-UanRv9' -Running [P1]: ltl2tgba -H 'F(G(a))'>'lcr-o1-43jbVn' -Running [N0]: ltl3ba -H1 -f '!(<>([](a)))'>'lcr-o0-TUeymC' -Running [N1]: ltl2tgba -H '!(F(G(a)))'>'lcr-o1-5PYsOQ' +Running [P0]: ltl3ba -H1 -f '<>([](a))'>'lcr-o0-hsnlkV' +Running [P1]: ltl2tgba -H 'F(G(a))'>'lcr-o1-R0jOmP' +Running [N0]: ltl3ba -H1 -f '!(<>([](a)))'>'lcr-o0-7GwxvJ' +Running [N1]: ltl2tgba -H '!(F(G(a)))'>'lcr-o1-5sgPFD' info: collected automata: info: P0 (2 st.,3 ed.,1 sets) info: N0 (3 st.,5 ed.,1 sets) univ-edges complete @@ -1339,3 +1303,16 @@ info: consistency_check (P1,N1), state-space #0/1 No problem detected. #+end_example + +#+BEGIN_SRC sh :results silent :exports results +rm -f results.csv results.json ltlcross.csv bogus-grind bogus +#+END_SRC + +# LocalWords: ltlcross num toc LTL Büchi LBTT Testbench PSL SRC sed +# LocalWords: automata LBT LBTT's ltl tgba GFa lck iDGV sA FYp BYY +# LocalWords: ClVQg wyErP UNE dQ coM tH eHPoQy goto ba lbt modella +# LocalWords: lbtt csv json randltl ltlfilt wm eGEYaZ nYpFBX fGdZQ +# LocalWords: CPs kXiZZS ILLzR wU CcMCaQ IOckzW tsT RZ TJXmT jb XRO +# LocalWords: nxqfd hS vNItGg acc scc nondetstates nondeterministic +# LocalWords: cvs LaTeX datacols len ith otimes ltlcheck eval setq +# LocalWords: setenv concat getenv diff --git a/doc/org/ltldo.org b/doc/org/ltldo.org index bdb54b65e..785c3b5b5 100644 --- a/doc/org/ltldo.org +++ b/doc/org/ltldo.org @@ -3,6 +3,7 @@ #+DESCRIPTION: Spot's wrapper for third-party LTL translators #+INCLUDE: setup.org #+HTML_LINK_UP: tools.html +#+PROPERTY: header-args:sh :results verbatim :exports both This tool is a wrapper for tools that read LTL/PSL formulas and (optionally) output automata. @@ -26,7 +27,7 @@ Büchi automaton produced by =ltl3ba=. Here is the input file: -#+BEGIN_SRC sh :results silent :exports both +#+BEGIN_SRC sh :results silent cat >sample.ltl <((a && ![]b) || (!a && []b)),4,10 Using =ltldo= the above command can be reduced to this: -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltldo 'ltl3ba -f %s>%O' -F sample.ltl --stats='%f,%s,%t' #+END_SRC #+RESULTS: @@ -106,7 +107,7 @@ In fact, as we will discuss below, =ltl3ba= is a tool that =ltldo= already knows about, so there is a shorter way to run the above command: -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :exports code ltldo ltl3ba -F sample.ltl --stats='%f,%s,%t' #+END_SRC #+RESULTS: @@ -129,8 +130,8 @@ Here is another example, where we use Spin to produce two automata in the [[http://adl.github.io/hoaf/][HOA format]]. Spin has no support for HOA, but =ltldo= simply converts the never claim produced by =spin= into this format. -#+BEGIN_SRC sh :results verbatim :exports both :wrap SRC hoa -ltldo -f a -f GFa 'spin -f %s>%O' +#+BEGIN_SRC sh :wrap SRC hoa +ltldo 'spin -f %s>%O' -f a -f GFa #+END_SRC #+RESULTS: @@ -177,7 +178,7 @@ simplified to just this: The syntax for specifying how a tool should be called is the same as in [[file:ltlcross.org][=ltlcross=]]. Namely, the following sequences are available. -#+BEGIN_SRC sh :results verbatim :exports results +#+BEGIN_SRC sh :exports results ltldo --help | sed -n '/character sequences:/,/^$/p' | sed '1d;$d' #+END_SRC @@ -195,7 +196,7 @@ filename using one of the sequence for that last line. For instance we could simply run a formula though =echo= to compare different output syntaxes: -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltldo -f 'p0 U p1' -f 'GFp0' 'echo %f, %s, %l, %w' #+END_SRC #+RESULTS: @@ -211,7 +212,7 @@ executed on each formula in the same order. A typical use-case is to compare statistics of different tools: -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltldo -F sample.ltl 'spin -f %s>%O' 'ltl3ba -f %s>%O' --stats=%T,%f,%s,%e #+END_SRC @@ -248,7 +249,7 @@ In the following example, we moved the formula used on its own line using the trick that the command =echo %f= will not be subject to =--stats= (since it does not declare any output automaton). -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltldo -F sample.ltl --stats=%T,%s,%e \ 'echo "#" %f' '{spin}spin -f %s>%O' '{ltl3ba}ltl3ba -f %s>%O' #+END_SRC @@ -299,7 +300,7 @@ There is a list of existing tools for which =ltldo= (and =ltlcross=) have built-in specifications. This list can be printed using the =--list-shorthands= option: -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltldo --list-shorthands #+END_SRC #+RESULTS: @@ -327,22 +328,18 @@ will changed into '{DRA} ~/mytools/ltl2dstar-0.5.2 --output-format=hoa %[MR]L %O' #+end_example -Therefore you can type just +Therefore you can type the following to obtain a Dot output (as +requested with =-d=) for the neverclaim produced by =ltl2ba -f a=. -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :prologue export SPOT_DOTEXTRA= SPOT_DOTDEFAULT= ltldo ltl2ba -f a -d #+END_SRC - -to obtain a Dot output (as requested with =-d=) for the neverclaim -produced by =ltl2ba -f a=. - -#+BEGIN_SRC sh :results verbatim :exports results -SPOT_DOTEXTRA= ltldo ltl2ba -f a --dot= -#+END_SRC #+RESULTS: #+begin_example -digraph G { +digraph "" { rankdir=LR + label="\n[Büchi]" + labelloc="t" node [shape="circle"] I [label="", style=invis, width=0] I -> 0 @@ -356,14 +353,13 @@ digraph G { The =ltl2ba= argument passed to =ltldo= was interpreted as if you had typed ={ltl2ba}ltl2ba -f %s>%O=. -The shorthand is only used if it is the first word of an command +The shorthand is only used if it is the first word of a command string that does not use any =%= character. This makes it possible to add options: -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltldo ltl3ba 'ltl3ba -H2' -f GFa --stats='%T, %s states, %e edges' #+END_SRC - #+RESULTS: : ltl3ba, 2 states, 4 edges : ltl3ba -H2, 1 states, 2 edges @@ -373,15 +369,10 @@ ltldo ltl3ba 'ltl3ba -H2' -f GFa --stats='%T, %s states, %e edges' If you have ever tried to use =spin=, =ltl2ba=, or =ltl3ba=, to translate a formula such as =[]!Error=, you have noticed that it does not work: -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :prologue "exec 2>&1" :epilogue true spin -f '[]!Error' #+END_SRC #+RESULTS: - -#+BEGIN_SRC sh :results verbatim :exports results -spin -f '[]!Error' 2>&1 || exit 0 -#+END_SRC -#+RESULTS: : tl_spin: expected predicate, saw 'E' : tl_spin: []!Error : -------------^ @@ -391,14 +382,14 @@ only atomic propositions starting with a lowercase letter. Running the same command through =ltldo= will work: -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltldo spin -f '[]!Error' -s #+END_SRC #+RESULTS: : never { : accept_init: : if -: :: ((!(Error))) -> goto accept_init +: :: (!(Error)) -> goto accept_init : fi; : } @@ -428,7 +419,7 @@ an LTL formula). In the following example, you can see that the automaton uses the atomic proposition =Error=, but its name contains a reference to =p0=. -#+BEGIN_SRC sh :results verbatim :exports both :wrap SRC hoa +#+BEGIN_SRC sh :wrap SRC hoa ltldo 'ltl3ba -H' -f '[]!Error' #+END_SRC #+RESULTS: @@ -451,7 +442,7 @@ State: 0 "accept_init" {0} If this is a problem, you can always force a new name with the =--name= option: -#+BEGIN_SRC sh :results verbatim :exports both :wrap SRC hoa +#+BEGIN_SRC sh :wrap SRC hoa ltldo 'ltl3ba -H' -f '[]!Error' --name='BA for %f' #+END_SRC @@ -480,7 +471,7 @@ State: 0 "accept_init" {0} Here is a formula on which different translators produce Büchi automata of different sizes (states and edges): -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltldo ltl2ba ltl3ba 'ltl2tgba -s' -f 'F(a & Xa | FGa)' \ --stats='%T: %s st. (%n non-det.), %e ed.' #+END_SRC @@ -494,7 +485,7 @@ Instead of outputting the result of the translation of each formula by each translator, =ltldo= can also be configured to output the smallest automaton obtained for each formula: -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltldo ltl2ba ltl3ba 'ltl2tgba -s' -f 'F(a & Xa | FGa)' --smallest #+END_SRC @@ -530,7 +521,7 @@ edges. If we desire the automaton that has the fewest states, and in case of equality the smallest number of non-deterministic states, we can use the following command instead. -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltldo ltl2ba ltl3ba 'ltl2tgba -s' -f 'F(a & Xa | FGa)' --smallest=%s,%n #+END_SRC @@ -563,7 +554,7 @@ from Dwyer et al. (FMSP'98), and print which translator among =ltl2ba=, =ltl3ba=, and =ltl2tgba -s= would produce the smallest automaton. -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh genltl --dac=10..20 --format=%F:%L,%f | ltldo -F-/2 ltl2ba ltl3ba 'ltl2tgba -s' --smallest --stats='%<,%T' #+END_SRC @@ -589,7 +580,7 @@ or =ltl2tgba -s= are also producing automata of equal size. To understand the above pipeline, remove the =ltldo= invocation. The [[file:genltl.org][=genltl=]] command outputs this: -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh genltl --dac=10..20 --format=%F:%L,%f #+END_SRC #+RESULTS: diff --git a/doc/org/ltlfilt.org b/doc/org/ltlfilt.org index d1b92a41c..e574334ba 100644 --- a/doc/org/ltlfilt.org +++ b/doc/org/ltlfilt.org @@ -3,6 +3,7 @@ #+DESCRIPTION: Spot command-line tool for filtering, tranforming, and converting LTL formulas. #+INCLUDE: setup.org #+HTML_LINK_UP: tools.html +#+PROPERTY: header-args:sh :results verbatim :exports both This tool is a filter for LTL formulas. (It will also work with PSL formulas.) It can be used to perform a number of tasks. Essentially: @@ -23,7 +24,7 @@ For instance the following will convert two LTL formulas expressed using infix notation (with different names supported for the same operators) and convert it into LBT's syntax. -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltlfilt -l -f 'p1 U (p2 & GFp3)' -f 'X<>[]p4' #+END_SRC #+RESULTS: @@ -33,7 +34,7 @@ ltlfilt -l -f 'p1 U (p2 & GFp3)' -f 'X<>[]p4' Conversely, here is how to rewrite formulas expressed using the LBT's Polish notation. Let's take the following four formulas taken from examples distributed with =scheck=: -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh cat >scheck.ltl< b)= would become =GF(p0)= as well. For instance here are some LTL formulas extracted from an [[http://www.fi.muni.cz/~xrehak/publications/verificationresults.ps.gz][industrial project]]: -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltlfilt --nnf -u --relabel-bool < F !hfe_req) G (lup_sr_valid -> F lup_sr_clean ) @@ -230,7 +231,7 @@ An option that can be used in combination with =--relabel= or between old and new names to be printed as a set of =#define= statements. -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltlfilt -f '(a & !b) & GF(a & !b) & FG(!c)' --relabel-bool=pnn --define --spin #+END_SRC @@ -245,7 +246,7 @@ For instance the following sequence show how to use =ltl3ba= to create a neverclaim for an LTL formula containing atomic propositions that =ltl3ba= cannot parse: -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltlfilt -f '"proc@loc1" U "proc@loc2"' --relabel=pnn --define=ltlex.def --spin | ltl3ba -F - >ltlex.never cat ltlex.def ltlex.never @@ -268,7 +269,7 @@ accept_all: As a side note, the tool [[file:ltldo.org][=ltldo=]] might be a simpler answer to this syntactic problem: -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltldo ltl3ba -f '"proc@loc1" U "proc@loc2"' --spin #+END_SRC #+RESULTS: @@ -292,7 +293,7 @@ separate page]]. =ltlfilt= supports many ways to filter formulas: -#+BEGIN_SRC sh :results verbatim :exports results +#+BEGIN_SRC sh :exports results ltlfilt --help | sed -n '/Filtering options.*:/,/^$/p' | sed '1d;$d' #+END_SRC #+RESULTS: @@ -332,7 +333,7 @@ Most of the above options should be self-explanatory. For instance the following command will extract all formulas from =scheck.ltl= which do not represent guarantee properties. -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltlfilt --lbt-input -F scheck.ltl -v --guarantee #+END_SRC #+RESULTS: @@ -342,7 +343,7 @@ Combining =ltlfilt= with [[file:randltl.org][=randltl=]] makes it easier to gene formulas that respect certain constraints. For instance let us generate 10 formulas that are equivalent to =a U b=: -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh randltl -n -1 a b | ltlfilt --equivalent-to 'a U b' -n 10 #+END_SRC #+RESULTS: @@ -375,7 +376,7 @@ syntactically. We can generate some starting again with =randltl=, then ignoring all syntactic safety formulas, and keeping only the safety formulas in the remaining list. -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh randltl -r -n -1 a b | ltlfilt -v --syntactic-safety | ltlfilt --safety -n 10 #+END_SRC #+RESULTS: @@ -397,7 +398,7 @@ Ga | (!b U !a) about a single formula. For instance is =a U (b U a)= equivalent to =b U a=? -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltlfilt -f 'a U (b U a)' --equivalent-to 'b U a' #+END_SRC #+RESULTS: @@ -410,7 +411,7 @@ status to 1, were the two formulas not equivalent. Is the formula =F(a & X(!a & Gb))= stutter-invariant? -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltlfilt -f 'F(a & X(!a & Gb))' --stutter-invariant #+END_SRC #+RESULTS: @@ -420,7 +421,7 @@ Yes it is. And since it is stutter-invariant, there exist some equivalent formulas that do not use =X= operator. The =--remove-x= option gives one: -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltlfilt -f 'F(a & X(!a & Gb))' --remove-x #+END_SRC #+RESULTS: @@ -429,7 +430,7 @@ ltlfilt -f 'F(a & X(!a & Gb))' --remove-x We could even verify that the resulting horrible formula is equivalent to the original one: -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltlfilt -f 'F(a & X(!a & Gb))' --remove-x | ltlfilt --equivalent-to 'F(a & X(!a & Gb))' #+END_SRC #+RESULTS: @@ -447,7 +448,7 @@ the formula generated randomly can be reduced by trivial simplifications such as =!!f= being rewritten to =f=, yielding formulas of smaller sizes). -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh randltl -n -1 --tree-size=8 a b | ltlfilt --size=5 -n 10 #+END_SRC @@ -473,7 +474,7 @@ formulas: the complexity of the Boolean subformulas has little influence on the overall translation. Here are 10 random formula with Boolean-size 5: -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh randltl -n -1 --tree-size=12 a b | ltlfilt --bsize=5 -n 10 #+END_SRC @@ -495,7 +496,7 @@ GF(1 U b) The =--format= option can be used the alter the way formulas are output. The list of supported =%=-escape sequences are recalled in the =--help= output: -#+BEGIN_SRC sh :results verbatim :exports results +#+BEGIN_SRC sh :exports results ltlfilt --help | sed -n '/ sequences:/,/^$/p' | sed '1d;$d' #+END_SRC #+RESULTS: @@ -544,7 +545,7 @@ you could print only the line numbers containing formulas matching some criterion. In the following, we print only the numbers of the lines of =scheck.ltl= that contain guarantee formulas: -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltlfilt --lbt-input -F scheck.ltl --guarantee --format=%L #+END_SRC #+RESULTS: @@ -555,7 +556,7 @@ ltlfilt --lbt-input -F scheck.ltl --guarantee --format=%L We could also prefix each formula by its size, in order to sort the file by formula size: -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltlfilt --lbt-input scheck.ltl --format='%s,%f' | sort -n #+END_SRC @@ -575,7 +576,7 @@ makes it very easy to partition a list of formulas in different files. For instance here is how to split =scheck.ltl= according to formula sizes. -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltlfilt --lbt-input scheck.ltl --output='scheck-%s.ltl' wc -l scheck*.ltl #+END_SRC @@ -587,7 +588,7 @@ wc -l scheck*.ltl : 4 scheck.ltl : 8 total -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh rm -f ltlex.def ltlex.never scheck.ltl #+END_SRC diff --git a/doc/org/ltlgrind.org b/doc/org/ltlgrind.org index 6fbb30976..152ea210e 100644 --- a/doc/org/ltlgrind.org +++ b/doc/org/ltlgrind.org @@ -3,17 +3,21 @@ #+DESCRIPTION: Spot command-line tool for mutating LTL formulas. #+INCLUDE: setup.org #+HTML_LINK_UP: tools.html +#+PROPERTY: header-args:sh :results verbatim :exports both -This tool lists formulas that are similar to but simpler than a given -formula by applying simple mutations to it, like removing operands or +:results scalar: Is the same as :results verbatim. + +:results table: Interprets the results as an Org This tool lists +formulas that are similar to but simpler than a given formula by +applying simple mutations to it, like removing operands or operators. This is meant to be used with ltlcross to simplify a formula that caused a problem before trying to debug it (see also =ltlcross --grind=FILENAME=). -Here is a list of the different kind of mutations that can be applied: +Here is a list of the different kinds of mutations that can be applied: -#+BEGIN_SRC sh :results verbatim :exports results -ltlgrind --help | sed -n '/Transformation rules:/,/^$/p' | sed '1d;$d' +#+BEGIN_SRC sh :exports results +ltlgrind --help | sed -n '/Mutation rules.*:/,/^$/p' | sed '1d;$d' #+END_SRC #+RESULTS: @@ -28,7 +32,7 @@ ltlgrind --help | sed -n '/Transformation rules:/,/^$/p' | sed '1d;$d' --rewrite-ops rewrite operators that have a semantically simpler form: a U b becomes a W b, etc. --simplify-bounds on a bounded unary operator, decrement one of the - bounds, or set min to 0 or max to unbounded. + bounds, or set min to 0 or max to unbounded --split-ops when an operator can be expressed as a conjunction/disjunction using simpler operators, each term of the conjunction/disjunction is a @@ -40,7 +44,7 @@ ltlgrind --help | sed -n '/Transformation rules:/,/^$/p' | sed '1d;$d' By default, all rules are applied. But if one or more rules are specified, only those will be applied. -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltlgrind -f 'a U G(b <-> c)' --split-ops --rewrite-ops --remove-ops #+END_SRC diff --git a/doc/org/ltlsynt.org b/doc/org/ltlsynt.org index 1f5f641b8..825d6d2f4 100644 --- a/doc/org/ltlsynt.org +++ b/doc/org/ltlsynt.org @@ -3,6 +3,7 @@ #+DESCRIPTION: Spot command-line tool for synthesizing AIGER circuits from LTL/PSL formulas. #+INCLUDE: setup.org #+HTML_LINK_UP: tools.html +#+PROPERTY: header-args:sh :results verbatim :exports both * Basic usage @@ -23,7 +24,7 @@ N}$ satisfies \phi. The following example illustrates the synthesis of a controller acting as an =AND= gate. We have two inputs =a= and =b= and one output =c=, and we want =c= to always be the =AND= of the two inputs: -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltlsynt --ins=a,b --outs=c -f 'G (a & b <=> c)' #+END_SRC @@ -59,14 +60,12 @@ The following example illustrates the case of an unrealizable specification. As =a= is an input proposition, there is no way to guarantee that it will eventually hold. -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh :epilogue true ltlsynt --ins=a --outs=b -f 'F a' #+END_SRC #+RESULTS: -#+begin_example -UNREALIZABLE -#+end_example +: UNREALIZABLE By default, the controller is output in HOA format, but it can be output as an @@ -89,7 +88,7 @@ TLSF specification to an LTL formula. The following four steps show you how a TLSF specification called spec.tlsf can be synthesized using =syfco= and =ltlsynt=: -#+BEGIN_SRC sh +#+BEGIN_SRC sh :export code LTL=$(syfco FILE -f ltlxba -m fully) IN=$(syfco FILE -f ltlxba -m fully) OUT=$(syfco FILE -f ltlxba -m fully) @@ -108,4 +107,3 @@ You can also ask =ltlsynt= to print to obtained parity game into [[https://github.com/tcsprojects/pgsolver][PGSolver]] format, with the flag =--print-pg=. Note that this flag deactivates the resolution of the parity game, which is to be deferred to one of the solvers from PGSolver. - diff --git a/doc/org/oaut.org b/doc/org/oaut.org index 846ac0064..9088df31d 100644 --- a/doc/org/oaut.org +++ b/doc/org/oaut.org @@ -3,6 +3,7 @@ #+DESCRIPTION: Options for input and output of ω-automata in Spot's command-line tools #+INCLUDE: setup.org #+HTML_LINK_UP: tools.html +#+PROPERTY: header-args:sh :results verbatim :exports both Spot supports different output syntaxes for automata. This page documents the options, common to all tools where it makes sense, that @@ -12,7 +13,7 @@ are used to specify how to output of automata. All tools that can output automata implement the following options: -#+BEGIN_SRC sh :results verbatim :exports results +#+BEGIN_SRC sh :exports results ltl2tgba --help | sed -n '/Output format:/,/^$/p' | sed '1d;$d' #+END_SRC #+RESULTS: @@ -86,7 +87,7 @@ printer. Here is an example where [[file:ltl2tgba.org][=ltl2tgba=]] is used to construct two automata: one for =a U b= and one for =(Ga -> Gb) W c=. -#+BEGIN_SRC sh :results verbatim :exports both :wrap SRC hoa +#+BEGIN_SRC sh :wrap SRC hoa ltl2tgba 'a U b' '(Ga -> Gb) W c' #+END_SRC #+RESULTS: @@ -140,7 +141,7 @@ The above output contains two automata, named after the formulas they represent. Here is a picture of these two automata: #+NAME: hoafex -#+BEGIN_SRC sh :results verbatim :exports none +#+BEGIN_SRC sh :exports none ltl2tgba --dot=.cn '(Ga -> Gb) W c' 'a U b' | dot | gvpack | perl -pe 's/\\\n//g;s/\\/\\\\/g;s/graph G/graph cluster/g' #+END_SRC @@ -317,7 +318,7 @@ to use state-based acceptance whenever possible. Option =t= forces transition-based acceptance. For instance compare this output to the previous one: -#+BEGIN_SRC sh :results verbatim :exports both :wrap SRC hoa +#+BEGIN_SRC sh :wrap SRC hoa ltl2tgba -Ht 'a U b' #+END_SRC #+RESULTS: @@ -343,7 +344,7 @@ State: 1 Option =m= uses mixed acceptance, i.e, some states might use state-based acceptance while other will not: -#+BEGIN_SRC sh :results verbatim :exports both :wrap SRC hoa +#+BEGIN_SRC sh :wrap SRC hoa ltl2tgba -Hm '(Ga -> Gb) W c' #+END_SRC #+RESULTS: @@ -383,7 +384,7 @@ the result should be used with line-based tools or embedded into a CSV file... Here is an example using both transition-based acceptance, and single-line output: -#+BEGIN_SRC sh :results verbatim :exports both :wrap SRC hoa +#+BEGIN_SRC sh :wrap SRC hoa ltl2tgba -Htl 'a U b' '(Ga -> Gb) W c' #+END_SRC #+RESULTS: @@ -398,7 +399,7 @@ be requested explicitly using =-H1=. The main advantage of version 1.1, as far as Spot is concerned, is that some of negated properties can be transmitted. For instance, compare -#+BEGIN_SRC sh :results verbatim :exports both :wrap SRC hoa +#+BEGIN_SRC sh :wrap SRC hoa ltl2tgba -f GFa -f FGa -H1 --check | grep -E '^(HOA|properties|name):' #+END_SRC @@ -416,7 +417,7 @@ properties: weak versus -#+BEGIN_SRC sh :results verbatim :exports both :wrap SRC hoa +#+BEGIN_SRC sh :wrap SRC hoa ltl2tgba -f GFa -f FGa -H1.1 --check | grep -E '^(HOA|properties|name):' #+END_SRC @@ -444,7 +445,7 @@ represented in the first version. The [[http://www.tcs.hut.fi/Software/lbtt/doc/html/Format-for-automata.html][LBTT]] output has two flavors: state-based (which is used to output Büchi automata or monitors) or transition-based (for TGBA). -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltl2tgba --ba --lbtt 'p0 U p1' #+END_SRC #+RESULTS: @@ -460,7 +461,7 @@ ltl2tgba --ba --lbtt 'p0 U p1' If you want to request transition-based output even for Büchi automata, use =--lbtt=t=. -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltl2tgba --ba --lbtt=t 'p0 U p1' #+END_SRC @@ -481,7 +482,7 @@ case other atomic propositions are used, Spot output them in double quotes. This other extension of the format is also supported by [[http://www.ltl2dstar.de/][ltl2dstar]]. -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltl2tgba --ba --lbtt 'a U b' #+END_SRC @@ -500,7 +501,7 @@ ltl2tgba --ba --lbtt 'a U b' Spin [[http://spinroot.com/spin/Man/never.html][never claims]] can be requested using =-s= or =--spin=. They can only represent Büchi automata, so these options imply =--ba=. -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltl2tgba -s 'a U b' #+END_SRC @@ -519,7 +520,7 @@ Recent versions of Spin (starting with Spin 6.2.4) output never claims in a slightly different style that can be requested using either =-s6= or =--spin=6=: -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltl2tgba -s6 'a U b' #+END_SRC @@ -543,38 +544,35 @@ of Promela syntax.) The =-d= or =--dot= option causes automata to be output in GraphViz's format. -#+BEGIN_SRC sh :results verbatim :exports code +#+NAME: oaut-dot1 +#+BEGIN_SRC sh :prologue export SPOT_DOTEXTRA= SPOT_DOTDEFAULT= ltl2tgba '(Ga -> Gb) W c' -d #+END_SRC - -#+NAME: oaut-dot1 -#+BEGIN_SRC sh :results verbatim :exports results -SPOT_DOTEXTRA= ltl2tgba '(Ga -> Gb) W c' --dot= -#+END_SRC - #+RESULTS: oaut-dot1 #+begin_example -digraph G { +digraph "(Gb | F!a) W c" { rankdir=LR + label="Inf(0)\n[Büchi]" + labelloc="t" node [shape="circle"] I [label="", style=invis, width=0] - I -> 1 + I -> 0 0 [label="0"] - 0 -> 0 [label="b\n{0}"] + 0 -> 0 [label="!a & !c\n{0}"] + 0 -> 1 [label="c"] + 0 -> 2 [label="a & b & !c"] + 0 -> 3 [label="a & !c"] 1 [label="1"] - 1 -> 0 [label="a & b & !c"] - 1 -> 1 [label="!a & !c\n{0}"] - 1 -> 2 [label="a & !c"] - 1 -> 3 [label="c"] + 1 -> 1 [label="1\n{0}"] 2 [label="2"] - 2 -> 1 [label="!a & !c\n{0}"] - 2 -> 2 [label="a & !c"] - 2 -> 3 [label="!a & c"] - 2 -> 4 [label="a & c"] + 2 -> 2 [label="b\n{0}"] 3 [label="3"] - 3 -> 3 [label="1\n{0}"] + 3 -> 0 [label="!a & !c\n{0}"] + 3 -> 1 [label="!a & c"] + 3 -> 3 [label="a & !c"] + 3 -> 4 [label="a & c"] 4 [label="4"] - 4 -> 3 [label="!a"] + 4 -> 1 [label="!a"] 4 -> 4 [label="a"] } #+end_example @@ -609,62 +607,13 @@ option =f(FONT)= is used to select a fontname: it is often necessary when =b= is used to ensure the characters ⓿, ❶, etc. are all selected from the same font. -#+BEGIN_SRC sh :results verbatim :exports code +#+NAME: oaut-dot2 +#+BEGIN_SRC sh :prologue export SPOT_DOTEXTRA= ltl2tgba --dot=vcsna '(Ga -> Gb) W c' #+END_SRC -#+RESULTS: -#+begin_example -digraph G { - label="(Gb | F!a) W c\nInf(0)\n[Büchi]" - labelloc="t" - node [shape="circle"] - edge[arrowhead=vee, arrowsize=.7] - I [label="", style=invis, height=0] - I -> 0 - subgraph cluster_0 { - color=green - label="" - 1 [label="1"] - } - subgraph cluster_1 { - color=green - label="" - 2 [label="2"] - } - subgraph cluster_2 { - color=red - label="" - 4 [label="4"] - } - subgraph cluster_3 { - color=green - label="" - 0 [label="0"] - 3 [label="3"] - } - 0 -> 0 [label="!a & !c\n{0}"] - 0 -> 1 [label="c"] - 0 -> 2 [label="a & b & !c"] - 0 -> 3 [label="a & !c"] - 1 -> 1 [label="1\n{0}"] - 2 -> 2 [label="b\n{0}"] - 3 -> 0 [label="!a & !c\n{0}"] - 3 -> 1 [label="!a & c"] - 3 -> 3 [label="a & !c"] - 3 -> 4 [label="a & c"] - 4 -> 1 [label="!a"] - 4 -> 4 [label="a"] -} -#+end_example - -#+NAME: oaut-dot2 -#+BEGIN_SRC sh :results verbatim :exports none -SPOT_DOTEXTRA= ltl2tgba --dot=vcsna '(Ga -> Gb) W c' -#+END_SRC - #+RESULTS: oaut-dot2 #+begin_example -digraph G { +digraph "(Gb | F!a) W c" { label="(Gb | F!a) W c\nInf(0)\n[Büchi]" labelloc="t" node [shape="circle"] @@ -728,7 +677,7 @@ The strongly connected components are displayed using the following colors: Here is an example involving all colors: #+NAME: oaut-dot3 -#+BEGIN_SRC sh :results verbatim :exports none +#+BEGIN_SRC sh :exports none SPOT_DOTEXTRA= autfilt --dot=cas < size.csv Rscript -e "summary(read.csv('size.csv', header=FALSE, col.names='edges'))" #+END_SRC @@ -1031,19 +1002,19 @@ edges should be $20.8\times100=2080$. Two of the statistics are related to time: =%r= displays wall-clock time, while =%R= displays CPU-time. -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh genltl --or-gf=1..8 | ltl2tgba --high --stats='%f,%r,%R' #+END_SRC #+RESULTS: -: GFp1,0.000502296,0 -: GF(p1 | p2),0.000796475,0 -: GF(p1 | p2 | p3),0.00215579,0 -: GF(p1 | p2 | p3 | p4),0.00441474,0 -: GF(p1 | p2 | p3 | p4 | p5),0.00980961,0.01 -: GF(p1 | p2 | p3 | p4 | p5 | p6),0.0255462,0.03 -: GF(p1 | p2 | p3 | p4 | p5 | p6 | p7),0.121033,0.12 -: GF(p1 | p2 | p3 | p4 | p5 | p6 | p7 | p8),0.624101,0.62 +: GFp1,0.00100355,0 +: GF(p1 | p2),0.00137515,0 +: GF(p1 | p2 | p3),0.00331282,0.01 +: GF(p1 | p2 | p3 | p4),0.00526782,0 +: GF(p1 | p2 | p3 | p4 | p5),0.00895499,0.01 +: GF(p1 | p2 | p3 | p4 | p5 | p6),0.0223277,0.02 +: GF(p1 | p2 | p3 | p4 | p5 | p6 | p7),0.0936452,0.09 +: GF(p1 | p2 | p3 | p4 | p5 | p6 | p7 | p8),0.480063,0.48 Note that =%r= is implemented using the most precise clock available and usually has nano-second precision, while =%R= uses the =times()= @@ -1070,29 +1041,28 @@ Here is an example where we use =ltldo= to benchmark the (default) each option the overall wall-clock time, CPU-time spent in =ltldo=, and CPU-time spent in =ltl2tgba=: -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh genltl --or-gf=1..8 | ltldo '{high}ltl2tgba' '{low}ltl2tgba --low' --stats='%T,%f,%r,%[p]R,%[c]R' #+END_SRC - #+RESULTS: #+begin_example -high,GFp1,0.0495443,0,0.02 -low,GFp1,0.0427718,0,0.03 -high,GFp1 | GFp2,0.0449237,0,0.03 -low,GFp1 | GFp2,0.0429886,0,0.03 -high,GFp1 | GFp2 | GFp3,0.0477704,0.01,0.03 -low,GFp1 | GFp2 | GFp3,0.0294271,0,0.01 -high,GFp1 | GFp2 | GFp3 | GFp4,0.0250874,0,0.02 -low,GFp1 | GFp2 | GFp3 | GFp4,0.0203729,0,0.01 -high,GFp1 | GFp2 | GFp3 | GFp4 | GFp5,0.0318887,0,0.03 -low,GFp1 | GFp2 | GFp3 | GFp4 | GFp5,0.0207457,0,0.01 -high,GFp1 | GFp2 | GFp3 | GFp4 | GFp5 | GFp6,0.0612968,0,0.05 -low,GFp1 | GFp2 | GFp3 | GFp4 | GFp5 | GFp6,0.0145482,0,0.01 -high,GFp1 | GFp2 | GFp3 | GFp4 | GFp5 | GFp6 | GFp7,0.130631,0,0.12 -low,GFp1 | GFp2 | GFp3 | GFp4 | GFp5 | GFp6 | GFp7,0.0151502,0,0.01 -high,GFp1 | GFp2 | GFp3 | GFp4 | GFp5 | GFp6 | GFp7 | GFp8,0.595865,0,0.59 -low,GFp1 | GFp2 | GFp3 | GFp4 | GFp5 | GFp6 | GFp7 | GFp8,0.0160234,0,0.01 +high,GFp1,0.0409265,0,0.05 +low,GFp1,0.0199356,0,0.02 +high,GFp1 | GFp2,0.0145994,0,0.02 +low,GFp1 | GFp2,0.0143211,0,0.01 +high,GFp1 | GFp2 | GFp3,0.0155654,0,0.03 +low,GFp1 | GFp2 | GFp3,0.014428,0,0.01 +high,GFp1 | GFp2 | GFp3 | GFp4,0.0173471,0,0.02 +low,GFp1 | GFp2 | GFp3 | GFp4,0.0143645,0,0.02 +high,GFp1 | GFp2 | GFp3 | GFp4 | GFp5,0.0214066,0,0.03 +low,GFp1 | GFp2 | GFp3 | GFp4 | GFp5,0.0147305,0,0 +high,GFp1 | GFp2 | GFp3 | GFp4 | GFp5 | GFp6,0.0386194,0,0.05 +low,GFp1 | GFp2 | GFp3 | GFp4 | GFp5 | GFp6,0.0140456,0,0.02 +high,GFp1 | GFp2 | GFp3 | GFp4 | GFp5 | GFp6 | GFp7,0.108726,0,0.1 +low,GFp1 | GFp2 | GFp3 | GFp4 | GFp5 | GFp6 | GFp7,0.0137925,0,0.02 +high,GFp1 | GFp2 | GFp3 | GFp4 | GFp5 | GFp6 | GFp7 | GFp8,0.49704,0,0.5 +low,GFp1 | GFp2 | GFp3 | GFp4 | GFp5 | GFp6 | GFp7 | GFp8,0.0218286,0,0.03 #+end_example * Naming automata @@ -1106,17 +1076,18 @@ tools have no default name. This name can be changed using the =--stats=. #+NAME: oaut-name -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :exports code ltl2tgba --name='TGBA for %f' --dot=n 'a U b' #+END_SRC #+RESULTS: oaut-name #+begin_example -digraph G { +digraph "TGBA for a U b" { rankdir=LR - label="TGBA for a U b" + label="TGBA for a U b\n[Büchi]" labelloc="t" - node[style=filled, fillcolor="#ffffa0"] edge[arrowhead=vee, arrowsize=.7] + node [shape="circle"] + node[fontsize=12] fontsize=12 stylesheet="spot.css" edge[arrowhead=vee, arrowsize=.7, fontsize=12] I [label="", style=invis, width=0] I -> 1 0 [label="0", peripheries=2] @@ -1150,7 +1121,7 @@ retaining only the names (i.e. formulas) of the automata with 3 states, and finally restricting the output to the first 5 matches using =autfilt -n5=. -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh randltl -n -1 a b | ltl2tgba | autfilt --states=3 --stats='!(%M)' | @@ -1172,13 +1143,13 @@ capable of [[file:csv.org][reading from a CSV file]] (=-F-/2= instructs =ltl2tgb read the standard input as if it was a CSV file, and to process its second column): -#+BEGIN_SRC sh :results verbatim :exports both -randltl -n -1 a b | # generate a stream of random LTL formulas -ltl2tgba -F- --stats='%s,!(%f)' | # for each formula output "states,negated formula" -grep '^3,' | # keep only formulas with 3 states -ltl2tgba -F-/2 --stats='%s,%f' | # for each negated formula output "states,formula" -grep '^3,' | # keep only negated formulas with 3 states -head -n5 | cut -d, -f2 # return the five first formulas +#+BEGIN_SRC sh +randltl -n -1 a b | # generate a stream of random LTL formulas +ltl2tgba -F- --stats='%s,!(%f)' | # for each formula output "states,negated formula" +grep '^3,' | # keep only formulas with 3 states +ltl2tgba -F-/2 --stats='%s,%f' | # for each negated formula output "states,formula" +grep '^3,' | # keep only negated formulas with 3 states +head -n5 | cut -d, -f2 # return the five first formulas #+END_SRC #+RESULTS: @@ -1192,13 +1163,6 @@ Note that the =-F-= argument in the first call to =ltl2tgba= is superfluous as the tool default to reading from its standard input. But we put it there for symmetry with the second call. -# LocalWords: num toc html syntaxes ltl tgba sed utf UTF lbtt SCCs -# LocalWords: GraphViz's hoaf HOA LBTT's neverclaim ba SPOT's Gb cn -# LocalWords: GraphViz autfilt acc Buchi hoafex gvpack perl pe bb -# LocalWords: labelloc rankdir subgraph lp pos invis gv png cmdline -# LocalWords: Tpng txt Hs Hm CSV Htl LBT dstar init goto fi Tpdf XF -# LocalWords: oaut vcsn randaut nondeterministic filename csv hoa -# LocalWords: varphi lnot GFb FG * Naming output By default, all output is sent to standard output, so you can either @@ -1212,7 +1176,7 @@ For instance =%d= is replaced by 0 or 1 depending on whether the automaton is deterministic. We can generate 20 random automata, and output them in two files depending on their determinism: -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh randaut -n 20 -Q2 -e1 1 -o out-det%d.hoa autfilt -c out-det0.hoa # Count of non-deterministic automata autfilt -c out-det1.hoa # Count of deterministic automata @@ -1229,7 +1193,7 @@ untouched. For instance if we run the above commands again, but forcing [[file:randaut.org][=randaut=]] to output 20 *deterministic* automata, it may look like we produced more than 20 automata: -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh randaut -D -n 20 -Q2 -e1 1 -o out-det%d.hoa autfilt -c out-det0.hoa # Count of non-deterministic automata autfilt -c out-det1.hoa # Count of deterministic automata @@ -1245,10 +1209,20 @@ previous execution, while =out-det1.hoa= has been overwritten. In the case where you want to append to a file instead of overwriting it, prefix the output filename with =>>= as in -: randaut -D -n 20 -Q2 1 -o '>>out-det%d.hoa' +#+BEGIN_SRC sh :exports code +randaut -D -n 20 -Q2 1 -o '>>out-det%d.hoa' +#+END_SRC (You need the quotes so that the shell does not interpret =>>=.) #+BEGIN_SRC sh :results silent :exports results rm -f out-det0.hoa out-det1.hoa #+END_SRC + +# LocalWords: num toc html syntaxes ltl tgba sed utf UTF lbtt SCCs +# LocalWords: GraphViz's hoaf HOA LBTT's neverclaim ba SPOT's Gb cn +# LocalWords: GraphViz autfilt acc Buchi hoafex gvpack perl pe bb +# LocalWords: labelloc rankdir subgraph lp pos invis gv png cmdline +# LocalWords: Tpng txt Hs Hm CSV Htl LBT dstar init goto fi Tpdf XF +# LocalWords: oaut vcsn randaut nondeterministic filename csv hoa +# LocalWords: varphi lnot GFb FG diff --git a/doc/org/randaut.org b/doc/org/randaut.org index 4e182b817..ae9e1d359 100644 --- a/doc/org/randaut.org +++ b/doc/org/randaut.org @@ -3,6 +3,7 @@ #+DESCRIPTION: Spot command-line tool for generating random ω-automata. #+INCLUDE: setup.org #+HTML_LINK_UP: tools.html +#+PROPERTY: header-args:sh :results verbatim :exports code The =randaut= tool generates random (connected) automata. @@ -11,64 +12,9 @@ acceptance sets, and using a set of atomic propositions you have to supply. #+NAME: randaut1 -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh randaut a b --dot #+END_SRC -#+RESULTS: randaut1 -#+begin_example -digraph G { - rankdir=LR - node [shape="circle"] - fontname="Lato" - node [fontname="Lato"] - edge [fontname="Lato"] - node[style=filled, fillcolor="#ffffa0"] edge[arrowhead=vee, arrowsize=.7] - I [label="", style=invis, width=0] - I -> 0 - 0 [label=<0>] - 0 -> 8 [label=] - 0 -> 3 [label=] - 0 -> 4 [label=] - 1 [label=<1>] - 1 -> 7 [label=] - 1 -> 0 [label=] - 1 -> 6 [label=] - 2 [label=<2>] - 2 -> 4 [label=] - 2 -> 0 [label=] - 2 -> 5 [label=] - 2 -> 9 [label=] - 3 [label=<3>] - 3 -> 2 [label=] - 3 -> 9 [label=] - 3 -> 3 [label=] - 4 [label=<4>] - 4 -> 0 [label=] - 4 -> 7 [label=] - 5 [label=<5>] - 5 -> 3 [label=] - 5 -> 1 [label=] - 5 -> 7 [label=] - 5 -> 9 [label=] - 5 -> 5 [label=] - 6 [label=<6>] - 6 -> 8 [label=] - 6 -> 5 [label=] - 6 -> 2 [label=] - 7 [label=<7>] - 7 -> 8 [label=] - 7 -> 9 [label=] - 7 -> 0 [label=] - 7 -> 1 [label=] - 7 -> 4 [label=] - 8 [label=<8>] - 8 -> 1 [label=] - 8 -> 3 [label=] - 9 [label=<9>] - 9 -> 1 [label=] - 9 -> 3 [label=] -} -#+end_example #+BEGIN_SRC dot :file randaut1.svg :var txt=randaut1 :exports results $txt @@ -95,30 +41,10 @@ In particular =-e0= will cause all states to have 1 successors, and =-e1= will cause all states to be interconnected. #+NAME: randaut2 -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh randaut -Q3 -e0 2 --dot #+END_SRC -#+RESULTS: randaut2 -#+begin_example -digraph G { - rankdir=LR - node [shape="circle"] - fontname="Lato" - node [fontname="Lato"] - edge [fontname="Lato"] - node[style=filled, fillcolor="#ffffa0"] edge[arrowhead=vee, arrowsize=.7] - I [label="", style=invis, width=0] - I -> 0 - 0 [label=<0>] - 0 -> 2 [label=] - 1 [label=<1>] - 1 -> 1 [label=] - 2 [label=<2>] - 2 -> 1 [label=] -} -#+end_example - #+BEGIN_SRC dot :file randaut2.svg :var txt=randaut2 :exports results $txt #+END_SRC @@ -126,36 +52,10 @@ $txt [[file:randaut2.svg]] #+NAME: randaut3 -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh randaut -Q3 -e1 2 --dot #+END_SRC -#+RESULTS: randaut3 -#+begin_example -digraph G { - rankdir=LR - node [shape="circle"] - fontname="Lato" - node [fontname="Lato"] - edge [fontname="Lato"] - node[style=filled, fillcolor="#ffffa0"] edge[arrowhead=vee, arrowsize=.7] - I [label="", style=invis, width=0] - I -> 0 - 0 [label=<0>] - 0 -> 2 [label=] - 0 -> 0 [label=] - 0 -> 1 [label=] - 1 [label=<1>] - 1 -> 1 [label=] - 1 -> 2 [label=] - 1 -> 0 [label=] - 2 [label=<2>] - 2 -> 1 [label=] - 2 -> 0 [label=] - 2 -> 2 [label=] -} -#+end_example - #+BEGIN_SRC dot :file randaut3.svg :var txt=randaut3 :exports results $txt #+END_SRC @@ -170,7 +70,7 @@ The generation of the acceptance sets abn is controlled with the following four - =-A ACCEPTANCE= (or =--acceptance=ACCEPTANCE=) controls both the acceptance condition, and the number of associated acceptance sets. The =ACCEPTANCE= argument is documented in =--help= as follows: -#+BEGIN_SRC sh :results verbatim :exports results +#+BEGIN_SRC sh :exports results randaut --help | sed -n '/^ \(ACCEPTANCE\|RANGE\)/,/^$/p' #+END_SRC @@ -221,34 +121,10 @@ ans =-s= (or =--spin=) implies =-B=. #+NAME: randaut4 -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh randaut -Q3 -e0.5 -A3 -a0.5 2 --dot #+END_SRC -#+RESULTS: randaut4 -#+begin_example -digraph G { - rankdir=LR - node [shape="circle"] - fontname="Lato" - node [fontname="Lato"] - edge [fontname="Lato"] - node[style=filled, fillcolor="#ffffa0"] edge[arrowhead=vee, arrowsize=.7] - I [label="", style=invis, width=0] - I -> 0 - 0 [label="0"] - 0 -> 1 [label=] - 0 -> 0 [label=>] - 1 [label="1"] - 1 -> 1 [label=>] - 1 -> 2 [label=>] - 2 [label="2"] - 2 -> 1 [label=>] - 2 -> 0 [label=>] - 2 -> 2 [label=>] -} -#+end_example - #+BEGIN_SRC dot :file randaut4.svg :var txt=randaut4 :exports results $txt #+END_SRC @@ -257,7 +133,7 @@ $txt #+NAME: randaut5 -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh randaut -Q3 -e0.4 -B -a0.7 2 --dot #+END_SRC @@ -292,46 +168,10 @@ $txt [[file:randaut5.svg]] #+NAME: randaut5b -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh randaut -Q6 -e0.4 -S -a.2 -A 'Streett 1..3' 2 --dot #+END_SRC -#+RESULTS: randaut5b -#+begin_example -digraph G { - rankdir=LR - label=<(Fin() | Inf()) & (Fin() | Inf())> - 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=] - 0 -> 1 [label=] - 0 -> 3 [label=] - 1 [label=<1>] - 1 -> 5 [label=] - 2 [label=<2
>] - 2 -> 1 [label=] - 2 -> 2 [label=] - 2 -> 4 [label=] - 3 [label=<3>] - 3 -> 2 [label=] - 3 -> 3 [label=] - 4 [label=<4>] - 4 -> 0 [label=] - 4 -> 5 [label=] - 5 [label=<5
>] - 5 -> 1 [label=] - 5 -> 2 [label=] - 5 -> 3 [label=] -} -#+end_example - #+BEGIN_SRC dot :file randaut5b.svg :var txt=randaut5b :exports results $txt #+END_SRC @@ -345,61 +185,10 @@ specify a precise parity acceptance such as =parity min even 3=, or give =randaut= some freedom, as in this example. #+NAME: randaut5c -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh randaut -Q10 -S --colored -A 'parity rand rand 3..4' 2 --dot #+END_SRC -#+RESULTS: randaut5c -#+begin_example -digraph G { - rankdir=LR - label=⓿) | (Fin() & (Inf() | Fin()))> - 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=] - 0 -> 8 [label=] - 0 -> 0 [label=] - 0 -> 6 [label=] - 1 [label=<1
>] - 1 -> 5 [label=] - 1 -> 9 [label=] - 2 [label=<2
>] - 2 -> 4 [label=] - 2 -> 5 [label=] - 3 [label=<3
>] - 3 -> 6 [label=] - 3 -> 1 [label=] - 4 [label=<4
>] - 4 -> 6 [label=] - 4 -> 1 [label=] - 5 [label=<5
>] - 5 -> 0 [label=] - 5 -> 8 [label=] - 5 -> 7 [label=] - 6 [label=<6
>] - 6 -> 2 [label=] - 6 -> 3 [label=] - 7 [label=<7
>] - 7 -> 3 [label=] - 7 -> 1 [label=] - 8 [label=<8
>] - 8 -> 3 [label=] - 8 -> 4 [label=] - 8 -> 2 [label=] - 8 -> 0 [label=] - 9 [label=<9
>] - 9 -> 0 [label=] - 9 -> 6 [label=] -} -#+end_example - #+BEGIN_SRC dot :file randaut5c.svg :var txt=randaut5c :exports results $txt #+END_SRC @@ -421,34 +210,10 @@ sum of all these formulas is $\top$. The resulting automaton is therefore deterministic and complete. #+NAME: randaut6 -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh randaut -D -Q3 -e0.6 -A2 -a0.5 2 --dot #+END_SRC -#+RESULTS: randaut6 -#+begin_example -digraph G { - rankdir=LR - node [shape="circle"] - fontname="Lato" - node [fontname="Lato"] - edge [fontname="Lato"] - node[style=filled, fillcolor="#ffffa0"] edge[arrowhead=vee, arrowsize=.7] - I [label="", style=invis, width=0] - I -> 0 - 0 [label="0"] - 0 -> 1 [label=] - 0 -> 2 [label=] - 1 [label="1"] - 1 -> 2 [label=>] - 1 -> 0 [label=>] - 2 [label="2"] - 2 -> 2 [label=>] - 2 -> 0 [label=>] - 2 -> 1 [label=>] -} -#+end_example - #+BEGIN_SRC dot :file randaut6.svg :var txt=randaut6 :exports results $txt #+END_SRC @@ -476,19 +241,24 @@ following generates 20 automatas, but store them in different files according to the acceptance condition. The format =%g= represent the formula for the acceptance condition and would not make a nice filename, but =%[s]g= is a short name for that acceptance condition -(its is replaced by "other" if Spot does not know better). +(its is replaced by "other" if Spot does not know better). We use +=-Hl= to output one automaton per line, so that =wc -l= will count +automata. -#+BEGIN_SRC sh :results verbatim :exports both -randaut -n20 -Q10 -A 'random 3' 2 -o 'randaut-%[s]g.hoa' +#+BEGIN_SRC sh :exports both +randaut -n20 -Q10 -A 'random 3' 2 -Hl -o 'randaut-%[s]g.hoa' wc -l randaut-*.hoa #+END_SRC #+RESULTS: -: 222 randaut-Rabin-like.hoa -: 380 randaut-Streett-like.hoa -: 100 randaut-generalized-Buchi.hoa -: 249 randaut-other.hoa -: 951 total +: 1 randaut-Fin-less.hoa +: 4 randaut-Rabin-like.hoa +: 7 randaut-Streett-like.hoa +: 2 randaut-generalized-Buchi.hoa +: 1 randaut-generalized-Rabin.hoa +: 1 randaut-generalized-Streett.hoa +: 4 randaut-other.hoa +: 20 total #+BEGIN_SRC sh :results silent :exports results rm -f rautaut-*.hoa @@ -515,7 +285,7 @@ options discussed [[file:oaut.org::#default-dot][on another page]], while '=s=' displayed.) #+NAME: randaut7 -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh randaut -n -1 --colored -A'parity min odd 4' a b | autfilt --sccs=5 --trivial-sccs=1 --rejecting-sccs=1 \ --inherently-weak-sccs=2 --weak-sccs=1 -n 1 --dot=.s diff --git a/doc/org/randltl.org b/doc/org/randltl.org index 3c0c1c4b8..d37dd7876 100644 --- a/doc/org/randltl.org +++ b/doc/org/randltl.org @@ -3,6 +3,7 @@ #+DESCRIPTION: Spot command-line tool for generating random LTL formulas. #+INCLUDE: setup.org #+HTML_LINK_UP: tools.html +#+PROPERTY: header-args:sh :results verbatim :exports both This tool generates random formulas. By default, it will generate one random LTL formula using atomic propositions supplied on the @@ -12,44 +13,55 @@ formulas instead, but let us first focus on LTL generation. For instance to obtain fave random LTL formula over the propositions =a=, =b=, or =c=, use: -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh randltl -n5 a b c #+END_SRC #+RESULTS: -: 1 -: !(!((a U Gb) U b) U GFa) -: GF((b R !a) U (Xc M 1)) -: (b <-> Xc) xor Fb -: FXb R (a R (1 U b)) +: 0 +: 0 R b +: F(XG(F!b M Fb) W (b R a)) +: F(a R !c) +: G(a | Fb) W (FGb R !b) Note that the result does not always use all atomic propositions. If you do not care about how the atomic propositions are named, you can give a nonnegative number instead: -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh randltl -n5 3 #+END_SRC #+RESULTS: -: 1 -: !(!((p0 U Gp1) U p1) U GFp0) -: GF((p1 R !p0) U (Xp2 M 1)) -: (p1 <-> Xp2) xor Fp1 -: FXp1 R (p0 R (1 U p1)) +: 0 +: 0 R p1 +: F(XG(F!p1 M Fp1) W (p1 R p0)) +: F(p0 R !p2) +: G(p0 | Fp1) W (FGp1 R !p1) The syntax of the formula output can be changed using the [[file:ioltl.org][common output options]]: -#+BEGIN_SRC sh :results verbatim :exports results +#+BEGIN_SRC sh :exports results randltl --help | sed -n '/Output options:/,/^$/p' | sed '1d;$d' #+END_SRC #+RESULTS: -: -8, --utf8 output using UTF-8 characters -: -l, --lbt output in LBT's syntax -: -p, --full-parentheses output fully-parenthesized formulas -: -s, --spin output in Spin's syntax -: --spot output in Spot's syntax (default) -: --wring output in Wring's syntax +#+begin_example + -0, --zero-terminated-output separate output formulas with \0 instead of \n + (for use with xargs -0) + -8, --utf8 output using UTF-8 characters + --format=FORMAT, --stats=FORMAT + specify how each line should be output (default: + "%f") + -l, --lbt output in LBT's syntax + --latex output using LaTeX macros + -o, --output=FORMAT send output to a file named FORMAT instead of + standard output. The first formula sent to a file + truncates it unless FORMAT starts with '>>'. + -p, --full-parentheses output fully-parenthesized formulas + -s, --spin output in Spin's syntax + --spot output in Spot's syntax (default) + --wring output in Wring's syntax +#+end_example When you select Spin's or Wring's syntax, operators =W= and =M= are automatically rewritten using =U= and =R= (written =V= for Spin). @@ -57,7 +69,7 @@ When you select LBT's syntax, you should name you atomic propositions like =p0=, =p1=, etc... (Atomic proposition named differently will be output by Spot in double-quotes, but this is not supported by LBT.) -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh randltl -l 12 randltl -8 12 randltl -s 12 @@ -65,10 +77,10 @@ randltl --wring 12 #+END_SRC #+RESULTS: -: V ! X ^ G p4 M p10 F ! p11 V G p3 p5 -: ¬○(□p4⊕(p10 M ◇¬p11)) R (□p3 R p5) -: !X(([]p4 && !(<>!p11 U (p10 && <>!p11))) || (![]p4 && (<>!p11 U (p10 && <>!p11)))) V ([]p3 V p5) -: (!(X((G(p4=1)) ^ ((F(p11=0)) U ((p10=1) * (F(p11=0))))))) R ((G(p3=1)) R (p5=1)) +: V f W V G p5 p7 p10 +: 0 R ((□p5 R p7) W p10) +: false V (p10 V (p10 || ([]p5 V p7))) +: (FALSE) R ((p10=1) R ((p10=1) + ((G(p5=1)) R (p7=1)))) As you might guess from the above result, for a given set of atomic propositions (and on the same computer) the generated formula will @@ -78,18 +90,18 @@ can be changed using the =--seed= option. For instance the following three commands: #+NAME: result-seed -#+BEGIN_SRC sh :results verbatim :exports both -randltl a b c -randltl --seed=123 a b c -randltl --seed=0 a b c +#+BEGIN_SRC sh +randltl a b c d +randltl --seed=4 a b c d +randltl --seed=0 a b c d #+END_SRC Will give three formulas in which the first and last are identical: #+RESULTS: result-seed -: 1 -: b W 0 -: 1 +: Xb R ((Gb R c) W d) +: Gd +: Xb R ((Gb R c) W d) When generating random formulas, we usually want large quantity of them. Rather than running =randltl= several times with different @@ -119,15 +131,15 @@ Initially, the random generator selects a tree size for the formula. The default size is =15=, but it can be changed using the =--tree-size= option. For instance in the following, for each formula the tree size will be chosen randomly in the range =22..30=. -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh randltl -n 5 a b c --tree-size=22..30 #+END_SRC #+RESULTS: -: (((b xor c) xor (a U (Gc M c))) | (!b xor (a M b))) W (b & Fc) +: c R (!Fa M Xc) +: !(FGc <-> (c <-> Ga)) -> ((Ga W Fa) M F(c W a)) +: G(((a xor Fc) W (G(a | b) R (b <-> !b))) <-> (b M 1)) : 0 -: !((c xor Gb) -> !Fb) xor !(Gc M 1) : 1 -: (a | ((c | G(!a W (!a W b))) W (b & (c M b)))) <-> (b R c) The tree size is just the number of nodes in the syntax tree of the formula during its construction. However because Spot automatically @@ -145,15 +157,15 @@ Stronger simplifications may be requested using the =-r= option, that implements many rewritings that helps Spot translators algorithms (so beware that using =-r= reduces the randomness of the output). -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh randltl -n 5 a b c --tree-size=22..30 -r #+END_SRC #+RESULTS: -: 1 +: c R (G!a M Xc) +: Fa | (FGc & ((c & Ga) | (!c & F!a))) | (GF!c & ((c & F!a) | (!c & Ga))) +: G((Fb & G((a & G!c) | (!a & Fc))) | (G!b & F((a & Fc) | (!a & G!c)))) : 0 -: ((G!b | (!c & F!b) | (c & Gb)) & GF!c) | (Fb & ((!c & Gb) | (c & F!b)) & FGc) -: (b R c) | (!a & ((!c & F(a & !b)) M (!c W !b))) -: XGa +: 1 The generator build the syntax tree recursively from its root, by considering all operators that could be used for a given tree size (for @@ -163,7 +175,7 @@ being selected is this priority over the sum of the priorities of all considered operators. The default priorities for each operator can be seen with =--dump-priorities=: -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh randltl a b c --dump-priorities #+END_SRC #+RESULTS: @@ -199,15 +211,15 @@ disable some of the operators by giving them a null priority. The following example disables 6 operators, and augments the priority of =U= to 3 to favor its occurrence. -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh randltl -n 5 a b c --ltl-priorities 'xor=0,implies=0,equiv=0,W=0,M=0,X=0,U=3' #+END_SRC #+RESULTS: -: 1 -: 1 U b : 0 -: F!((b U !a) U Gc) -: !b U G(b R c) +: b +: 1 +: !F(1 U ((a U c) U b)) +: 1 U G!b When using =-r= to simplify generated formulas, beware that these rewritings may use operators that you disabled during the initial @@ -221,27 +233,27 @@ is generated for a subset of the atomic propositions and "ANDed" to the random formula. The =--tree-size= option has no influence on the weak-fairness formula appended. -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh randltl -n 5 a b c --weak-fairness #+END_SRC #+RESULTS: -: GFb -: ((b | XXa) M Ga) & GFa & GFc -: GFb & GFc & !(!((a U Gb) U b) U GFa) -: GFb & GFa & GFc & F(!X!b U (!c M 1)) -: GFb & GFa & GFc & Xc +: 0 +: (!Fb | F!Fc) & GFa & GFb & GFc +: GFa & GFb & GFc & F(a xor b) +: (a | b) & GFa & GFb & GFc & (Ga -> Gc) +: GFa & GFb & GFc & (GXb U (Fc U (Fc | (a R b)))) Boolean formulas may be output with the =-B= option: -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh randltl -B -n 5 a b c #+END_SRC #+RESULTS: -: !b -: b & !b -: b -: !c xor (!a xor b) -: !a -> (!c <-> (b xor !(a xor !b))) +: !(b -> !c) +: c xor (b | c) +: !(a & (a xor b)) +: 0 +: !b -> c In that case, priorities should be set with =--boolean-priorities=. @@ -251,21 +263,21 @@ random PSL formula may produce many LTL formulas that do not use any PSL operator (this is even more so the case when simplifications are enabled with =-r=). -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh randltl -P -n 5 a b c #+END_SRC #+RESULTS: -: 1 -: a R c -: F({[*0] | {{[*0] | a[*]}}[*]}[]-> 0) -: (a | ((a U c) M a)) M 1 : 0 +: b +: !(a W b) +: 1 +: (a U !b) <-> (!a -> Gb) As shown with the =--dump-priorities= output below, tweaking the priorities used to generated PSL formulas requires three different options: -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh randltl -P a b c --dump-priorities #+END_SRC #+RESULTS: @@ -295,6 +307,8 @@ eword 1 boolform 1 star 1 star_b 1 +fstar 1 +fstar_b 1 and 1 andNLM 1 or 1 diff --git a/doc/org/satmin.org b/doc/org/satmin.org index 53a536653..e316b81c6 100644 --- a/doc/org/satmin.org +++ b/doc/org/satmin.org @@ -3,6 +3,7 @@ #+DESCRIPTION: Spot command-line tools for minimizing ω-automata #+INCLUDE: setup.org #+HTML_LINK_UP: tools.html +#+PROPERTY: header-args:sh :results verbatim :exports both #+NAME: version #+BEGIN_SRC sh :exports none @@ -50,7 +51,7 @@ Let us first state a few facts about this minimization procedure. * How to change the SAT solver used -By default Spot uses PicoSAT call_version()[:results raw]), this SAT-solver +By default Spot uses PicoSAT call_version()[:results raw], this SAT-solver is built into the Spot library, so that no temporary files are used to store the problem. @@ -59,7 +60,7 @@ SAT solver used by Spot. This variable should describe a shell command to run the SAT-solver on an input file called =%I= so that a model satisfying the formula will be written in =%O=. For instance to use [[http://www.labri.fr/perso/lsimon/glucose/][Glucose 3.0]], instead of the builtin version of PicoSAT, define -#+BEGIN_SRC sh +#+BEGIN_SRC sh :exports code export SPOT_SATSOLVER='glucose -verb=0 -model %I >%O' #+END_SRC We assume the SAT solver follows the input/output conventions of the @@ -80,14 +81,14 @@ automaton. However =-D= is not a guarantee to obtain a deterministic automaton, even if one exists. For instance, =-D= fails to produce a -deterministic automaton for =GF(a <-> XXb)=. Instead we get a 9-state +deterministic automaton for =a U X(b | GF!b)=. Instead we get a 4-state non-deterministic automaton. -#+BEGIN_SRC sh :results verbatim :exports both -ltl2tgba -D 'GF(a <-> XXb)' --stats='states=%s, det=%d' +#+BEGIN_SRC sh +ltl2tgba -D 'a U X(b | GF!b)' --stats='states=%s, det=%d' #+END_SRC #+RESULTS: -: states=9, det=0 +: states=4, det=0 Option =-x tba-det= enables an additional determinization procedure, that would otherwise not be used by =-D= @@ -98,60 +99,27 @@ acceptance conditions, it will be degeneralized first. On our example, =-x tba-det= successfully produces a deterministic TBA, but a non-minimal one: -#+BEGIN_SRC sh :results verbatim :exports both -ltl2tgba -D -x tba-det 'GF(a <-> XXb)' --stats='states=%s, det=%d' +#+BEGIN_SRC sh +ltl2tgba -D -x tba-det 'a U X(b | GF!b)' --stats='states=%s, det=%d' #+END_SRC #+RESULTS: -: states=7, det=1 +: states=9, det=1 Option =-x sat-minimize= will turn-on SAT-based minimization. It also implies =-x tba-det=, so there is no need to supply both options. -#+BEGIN_SRC sh :results verbatim :exports both -ltl2tgba -D -x sat-minimize 'GF(a <-> XXb)' --stats='states=%s, det=%d' +#+BEGIN_SRC sh +ltl2tgba -D -x sat-minimize 'a U X(b | GF!b)' --stats='states=%s, det=%d' #+END_SRC #+RESULTS: -: states=4, det=1 +: states=5, det=1 We can draw it: #+NAME: gfaexxb3 -#+BEGIN_SRC sh :results verbatim :exports code -ltl2tgba -D -x sat-minimize 'GF(a <-> XXb)' -d +#+BEGIN_SRC sh :exports code +ltl2tgba -D -x sat-minimize 'a U X(b | GF!b)' -d #+END_SRC -#+RESULTS: gfaexxb3 -#+begin_example -digraph G { - rankdir=LR - node [shape="circle"] - fontname="Lato" - node [fontname="Lato"] - edge [fontname="Lato"] - node[style=filled, fillcolor="#ffffa0"] edge[arrowhead=vee, arrowsize=.7] - I [label="", style=invis, width=0] - I -> 0 - 0 [label="0"] - 0 -> 1 [label=>] - 0 -> 2 [label=] - 0 -> 3 [label=
] - 0 -> 3 [label=>] - 1 [label="1"] - 1 -> 0 [label=] - 1 -> 0 [label=>] - 1 -> 1 [label=] - 1 -> 1 [label=>] - 2 [label="2"] - 2 -> 0 [label=] - 2 -> 1 [label=>] - 2 -> 1 [label=] - 2 -> 3 [label=>] - 3 [label="3"] - 3 -> 2 [label=>] - 3 -> 2 [label=] - 3 -> 3 [label=>] - 3 -> 3 [label=] -} -#+end_example #+BEGIN_SRC dot :file gfaexxb3.svg :var txt=gfaexxb3 :exports results $txt @@ -166,46 +134,8 @@ result will of course be slightly bigger. #+NAME: gfaexxb4 #+BEGIN_SRC sh :results verbatim :exports code -ltl2tgba -BD -x sat-minimize 'GF(a <-> XXb)' -d +ltl2tgba -BD -x sat-minimize 'a U X(b | GF!b)' -d #+END_SRC -#+RESULTS: gfaexxb4 -#+begin_example -digraph G { - rankdir=LR - node [shape="circle"] - fontname="Lato" - node [fontname="Lato"] - edge [fontname="Lato"] - node[style=filled, fillcolor="#ffffa0"] edge[arrowhead=vee, arrowsize=.7] - I [label="", style=invis, width=0] - I -> 0 - 0 [label="0"] - 0 -> 0 [label=] - 0 -> 1 [label=] - 0 -> 2 [label=] - 1 [label="1", peripheries=2] - 1 -> 4 [label=] - 1 -> 5 [label=] - 2 [label="2"] - 2 -> 1 [label=] - 2 -> 4 [label=] - 2 -> 5 [label=] - 3 [label="3", peripheries=2] - 3 -> 0 [label=] - 3 -> 1 [label=] - 3 -> 2 [label=] - 4 [label="4"] - 4 -> 0 [label=] - 4 -> 1 [label=] - 4 -> 2 [label=] - 4 -> 3 [label=] - 5 [label="5"] - 5 -> 1 [label=] - 5 -> 3 [label=] - 5 -> 4 [label=] - 5 -> 5 [label=] -} -#+end_example #+BEGIN_SRC dot :file gfaexxb4.svg :var txt=gfaexxb4 :exports results $txt @@ -214,10 +144,11 @@ $txt [[file:gfaexxb4.svg]] -There are cases where =ltl2tgba='s =tba-det= algorithm fails to produce a deterministic automaton. -In that case, SAT-based minimization is simply skipped. For instance: +There are cases where =ltl2tgba='s =tba-det= algorithm fails to +produce a deterministic automaton. In that case, SAT-based +minimization is simply skipped. For instance: -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltl2tgba -D -x sat-minimize 'G(F(!b & (X!a M (F!a & F!b))) U !b)' --stats='states=%s, det=%d' #+END_SRC #+RESULTS: @@ -234,7 +165,7 @@ The first is purely syntactic. If a formula belongs to the class of without being syntactic recurrences.) [[file:ltlfilt.org][=ltlfilt=]] can be instructed to print only formulas that are syntactic recurrences: -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltlfilt --syntactic-recurrence -f 'G(F(!b & (X!a M (F!a & F!b))) U !b)' #+END_SRC #+RESULTS: @@ -247,7 +178,7 @@ converting a deterministic Rabin automaton using [[file:dstar2tgba.org][=dstar2t output is guaranteed to be deterministic if and only if the input DRA expresses a recurrence property. -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltlfilt --remove-wm -f 'G(F(!b & (X!a M (F!a & F!b))) U !b)' -l | ltl2dstar --ltl2nba=spin:ltl2tgba@-Ds - - | dstar2tgba -D --stats='input(states=%S) output(states=%s, acc-sets=%a, det=%d)' @@ -274,7 +205,7 @@ As far as SAT-based minimization goes, =dstar2tgba= will take the same options as =ltl2tgba=. For instance we can see that the smallest DTBA has call_size(arg="%s -x sat-minimize")[:results raw] states: -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltlfilt --remove-wm -f 'G(F(!b & (X!a M (F!a & F!b))) U !b)' -l | ltl2dstar --ltl2nba=spin:ltl2tgba@-Ds - - | dstar2tgba -D -x sat-minimize --stats='input(states=%S) output(states=%s, acc-sets=%a, det=%d)' @@ -284,8 +215,9 @@ dstar2tgba -D -x sat-minimize --stats='input(states=%S) output(states=%s, acc-se * More acceptance sets -The formula "=G(F(!b & (X!a M (F!a & F!b))) U !b)=" can in fact be minimized into an -even smaller automaton if we use multiple acceptance sets. +The formula "=G(F(!b & (X!a M (F!a & F!b))) U !b)=" can in fact be +minimized into an even smaller automaton if we use multiple acceptance +sets. Unfortunately because =dstar2tgba= does not know the formula being translated, and it always convert a DRA into a DBA (with a single @@ -294,7 +226,7 @@ more acceptance sets could be useful to further minimize it. This number of acceptance sets can however be specified on the command-line with option =-x sat-acc=M=. For instance: -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltlfilt --remove-wm -f 'G(F(!b & (X!a M (F!a & F!b))) U !b)' -l | ltl2dstar --ltl2nba=spin:ltl2tgba@-Ds - - | dstar2tgba -D -x sat-minimize,sat-acc=2 --stats='input(states=%S) output(states=%s, acc-sets=%a, det=%d)' @@ -408,51 +340,16 @@ acceptance. For our example, let us first generate a deterministic Rabin automaton with [[http://www.ltl2dstar.de/][=ltl2dstar=]]. -#+BEGIN_SRC sh :results silent :exports both +#+BEGIN_SRC sh :results silent ltlfilt -f 'FGa | FGb' -l | ltl2dstar --ltl2nba=spin:ltl2tgba@-Ds --output-format=hoa - - > output.hoa #+END_SRC Let's draw it: #+NAME: autfiltsm1 -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :exports code autfilt output.hoa --dot #+END_SRC -#+RESULTS: autfiltsm1 -#+begin_example -digraph G { - rankdir=LR - label=<(Fin(⓿) & Inf(❶)) | (Fin(❷) & Inf(❸))> - 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=] - 0 -> 1 [label=
] - 0 -> 2 [label=] - 0 -> 3 [label=] - 1 [label=<1
❶❷>] - 1 -> 0 [label=] - 1 -> 1 [label=
] - 1 -> 2 [label=] - 1 -> 3 [label=] - 2 [label=<2
⓿❸>] - 2 -> 0 [label=] - 2 -> 1 [label=
] - 2 -> 2 [label=] - 2 -> 3 [label=] - 3 [label=<3
❶❸>] - 3 -> 0 [label=] - 3 -> 1 [label=
] - 3 -> 2 [label=] - 3 -> 3 [label=] -} -#+end_example #+BEGIN_SRC dot :file autfiltsm1.svg :var txt=autfiltsm1 :exports results $txt @@ -466,7 +363,7 @@ transition-based version (the output may change depending on the SAT solver used): #+NAME: autfiltsm2 -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :exports code autfilt --sat-minimize output.hoa --dot #+END_SRC @@ -479,7 +376,7 @@ $txt We can also attempt to build a state-based version with #+NAME: autfiltsm3 -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :exports code autfilt -S --sat-minimize output.hoa --dot #+END_SRC @@ -500,32 +397,10 @@ You can however force a specific acceptance to be used as output. Let's try with generalized co-Büchi for instance: #+NAME: autfiltsm4 -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :exports code autfilt -S --sat-minimize='acc="generalized-co-Buchi 2"' output.hoa --dot #+END_SRC -#+RESULTS: autfiltsm4 -#+begin_example -digraph G { - rankdir=LR - label=⓿)|Fin()> - 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=
] - 0 -> 1 [label=] - 1 [label=<1
>] - 1 -> 0 [label=] - 1 -> 1 [label=] -} -#+end_example - #+BEGIN_SRC dot :file autfiltsm4.svg :var txt=autfiltsm4 :exports results $txt #+END_SRC @@ -539,7 +414,7 @@ give an acceptance formula in the [[http://adl.github.io/hoaf/#acceptance][HOA s attempt to create a co-Büchi automaton with #+NAME: autfiltsm5 -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :exports code autfilt -S --sat-minimize='acc="Fin(0)"' output.hoa --dot #+END_SRC #+RESULTS: autfiltsm5 @@ -571,32 +446,11 @@ Here is an example demonstrating the case where the input automaton is smaller than the output. Let's take this small TGBA as input: #+NAME: autfiltsm6 -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :exports code ltl2tgba 'GFa & GFb' >output2.hoa autfilt output2.hoa --dot #+END_SRC -#+RESULTS: autfiltsm6 -#+begin_example -digraph G { - rankdir=LR - label=⓿)&Inf()> - 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=
>] - 0 -> 0 [label=] - 0 -> 0 [label=>] - 0 -> 0 [label=>] -} -#+end_example - #+BEGIN_SRC dot :file autfiltsm6.svg :var txt=autfiltsm6 :exports results $txt #+END_SRC @@ -607,10 +461,10 @@ $txt If we attempt to minimize it into a transition-based Büchi automaton, with fewer states, it will fail, output no result, and return with a -non-zero exit code (because no automata where output). +non-zero exit code (because no automata were output). #+NAME: autfiltsm7 -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh autfilt --sat-minimize='acc="Buchi"' output2.hoa echo $? #+END_SRC @@ -620,7 +474,7 @@ echo $? However if we allow more states, it will work: #+NAME: autfiltsm8 -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :exports code autfilt --sat-minimize='acc="Buchi",max-states=3' output2.hoa --dot #+END_SRC @@ -692,7 +546,7 @@ Compare the following, where parity acceptance is used, but the automaton is not colored: #+NAME: autfiltsm9 -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :exports code autfilt -S --sat-minimize='acc="parity max even 3"' output2.hoa --dot #+END_SRC @@ -707,7 +561,7 @@ $txt belong to exactly one acceptance set: #+NAME: autfiltsm10 -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :exports code autfilt -S --sat-minimize='acc="parity max even 3",colored' output2.hoa --dot #+END_SRC @@ -724,22 +578,31 @@ If the environment variable =SPOT_SATLOG= is set to the name of a file, the minimization function will append statistics about each of its iterations in this file. -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh rm -f stats.csv export SPOT_SATLOG=stats.csv ltlfilt -f 'Ga R (F!b & (c U b))' -l | ltl2dstar --ltl2nba=spin:ltl2tgba@-Ds - - | dstar2tgba -D -x sat-minimize,sat-acc=2 --stats='input(states=%S) output(states=%s, acc-sets=%a, det=%d)' -echo ==== stats.csv ==== -cat stats.csv #+END_SRC #+RESULTS: : input(states=11) output(states=5, acc-sets=2, det=1) -: ==== stats.csv ==== -: input.states,target.states,reachable.states,edges,transitions,variables,clauses,enc.user,enc.sys,sat.user,sat.sys,automaton -: 10,5,,,,13600,1543042,59,3,187,0, -: 10,7,7,33,56,26656,4247441,162,7,775,0,"HOA: v1 States: 7 Start: 0 AP: 3 ""a"" ""b"" ""c"" acc-name: generalized-Buchi 2 Acceptance: 2 Inf(0)&Inf(1) properties: trans-labels explicit-labels trans-acc complete deterministic --BODY-- State: 0 [!0&!1&2] 0 {1} [!0&1] 0 {0} [!0&!1&!2] 1 {0} [0&!1&!2] 1 [0&!1&2] 2 {1} [0&1&!2] 4 [0&1&2] 4 {0} State: 1 [0&!1] 1 {0} [!0&!1&!2 | 0&1] 1 [!0&1 | !0&2] 3 {0} State: 2 [!0&!1&2] 0 {1} [!0&1] 0 {0 1} [!0&!1&!2] 1 [0&!1&2] 2 [0&!1&!2] 3 {1} [0&1] 5 {0 1} State: 3 [!1&!2] 3 [1 | 2] 3 {0} State: 4 [!0&!1&2] 0 {0 1} [!0&1] 0 {0} [!0&!1&!2] 1 [0&1] 4 {0} [0&!1&2] 5 {0} [0&!1&!2] 6 State: 5 [!0&1 | !0&2] 0 {0 1} [!0&!1&!2] 1 [0&1 | 0&2] 5 {0 1} [0&!1&!2] 6 {0} State: 6 [!0&!1&!2] 1 [!0&1&!2] 1 {0 1} [!0&1&2] 1 {1} [!0&!1&2] 3 {0 1} [0] 6 {0 1} --END--" -: 7,6,6,26,48,10512,1376507,50,0,269,0,"HOA: v1 States: 6 Start: 0 AP: 3 ""a"" ""b"" ""c"" acc-name: generalized-Buchi 2 Acceptance: 2 Inf(0)&Inf(1) properties: trans-labels explicit-labels trans-acc complete deterministic --BODY-- State: 0 [!0&!1&2] 0 {1} [!0&1] 0 {0} [!0&!1&!2] 1 [0&!1&!2] 1 {0 1} [0&!1&2] 2 {1} [0&1] 3 {0} State: 1 [t] 1 State: 2 [!0&!1&2] 0 {1} [!0&1] 0 {0} [!1&!2] 1 [0&!1&2] 2 {1} [0&1] 4 {1} State: 3 [!0&!1&2] 0 {1} [!0&1] 0 [!0&!1&!2] 1 [0&1] 3 [0&!1&2] 4 {1} [0&!1&!2] 5 {1} State: 4 [!0&!1&2 | !0&1&!2] 0 {0 1} [!0&1&2] 0 {0} [!0&!1&!2] 1 [0&1 | 0&2] 4 {0 1} [0&!1&!2] 5 State: 5 [!0&!1&!2] 1 [!0&1 | !0&2] 1 {0 1} [0] 5 {0 1} --END--" + +Here is the contents of the =stats.csv= file: +#+begin_src sh :exports results :results output raw +sed '1a\ +|-| +s/^/|/ +s/$/|/ +s/,/|/g +s/"HOA:.*--END--"/HOA:.../' stats.csv +#+end_src +#+RESULTS: +| input.states | target.states | reachable.states | edges | transitions | variables | clauses | enc.user | enc.sys | sat.user | sat.sys | automaton | +|--------------+---------------+------------------+-------+-------------+-----------+---------+----------+---------+----------+---------+-----------| +| 8 | 4 | | | | 5120 | 446320 | 22 | 1 | 17 | 0 | | +| 8 | 6 | 6 | 29 | 48 | 11520 | 1515749 | 50 | 4 | 234 | 0 | HOA:... | +| 8 | 5 | | | | 8000 | 874992 | 29 | 0 | 67 | 0 | | The generated CSV file use the following columns: - =input.states=: the number of states of the reference automaton at this step @@ -759,14 +622,17 @@ file follows RFC4180 in escaping double-quote by doubling them. In the above example, the DRA produced by =ltl2dstar= had 11 states. In the first line of the =stats.csv= file, you can see the -minimization function had a 10-state input, which means that -=dstar2tgba= first reduced the 11-state (complete) DRA into a 10-state -(complete) DBA before calling the SAT-based minimization. This first -line shows the SAT-based minimization for a (complete) 5-state DTGBA -and failing to find one. Then on the next line it looks for a 7-state -solution, finds one. Finally, it finds a (complete) 6-state solution, -now using the 7-state version as reference automaton to further -simplify the problem. +minimization function had a 8-state input, which means that +=dstar2tgba= first reduced the 11-state (complete) DRA into a 8-state +(complete) DBA before calling the SAT-based minimization (the fact +that the input was reduced to a *DBA* is not very obvious from this +trace), This first line shows the SAT-based minimization for a +(complete) 5-state DTGBA and failing to find one. Then on the next +line it looks for a 6-state solution, finds one. Finally, it looks +for a 5-state solution, and cannot find one. The reason the 5-state +attempt uses the 8-state automaton as input rather than the 6-state +automaton is because the 8-state automaton uses 1 acceptance states +(it's a DBA) while the 6-state automaton uses 2. The final output is reported with 5 states, because by default we output trim automata. If the =--complete= option had been given, the diff --git a/doc/org/setup.org b/doc/org/setup.org index d6ba75962..3334f92b9 100644 --- a/doc/org/setup.org +++ b/doc/org/setup.org @@ -1,4 +1,4 @@ -#+OPTIONS: H:2 num:nil toc:t html-postamble:nil +#+OPTIONS: H:2 num:nil toc:t html-postamble:nil ^:nil #+EMAIL: spot@lrde.epita.fr #+HTML_LINK_HOME: index.html #+MACRO: SPOTVERSION 2.7.2 diff --git a/doc/org/tools.org b/doc/org/tools.org index f44f45be9..5227f1b4e 100644 --- a/doc/org/tools.org +++ b/doc/org/tools.org @@ -3,6 +3,7 @@ #+DESCRIPTION: List of all the command-line tools installed by Spot {{{SPOTVERSION}}} #+INCLUDE: setup.org #+HTML_LINK_UP: index.html +#+PROPERTY: header-args:sh :results verbatim :exports both This document introduces command-line tools that are installed with the Spot library. We give some examples to highlight possible @@ -17,7 +18,7 @@ commands issued to the shell are formatted like this with a cyan line on the left: #+NAME: helloworld -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh echo Hello World #+END_SRC @@ -97,6 +98,11 @@ lead to some academic publication, please consider citing Spot. Our Additionally, the man pages of these tools also contains additional references about the algorithms or data sources used. +If you did some benchmark comparison against Spot, or if you built a +tool above features provided by Spot, please make it clear what +version of Spot you are using. Spot is improved regularly, and +results might be different with another version. + # LocalWords: num toc helloworld SRC LTL PSL randltl ltlfilt genltl # LocalWords: scalable ltl tgba Büchi automata tgta ltlcross eval # LocalWords: setenv concat getenv setq diff --git a/doc/org/tut01.org b/doc/org/tut01.org index 71c6dc307..523bc4b19 100644 --- a/doc/org/tut01.org +++ b/doc/org/tut01.org @@ -3,6 +3,9 @@ #+DESCRIPTION: Code example for parsing and printing formulas in Spot #+INCLUDE: setup.org #+HTML_LINK_UP: tut.html +#+PROPERTY: header-args:sh :results verbatim :exports both +#+PROPERTY: header-args:python :results output :exports both +#+PROPERTY: header-args:C+++ :results verbatim :exports both Our first task is to read formulas and print them in another syntax. @@ -15,7 +18,7 @@ of LBT, you should use [[file:ioltl.org][=--lbt-input=]]. The output syntax is using different options such as (=--spin=, =--lbt=, =--latex=, etc.). Full parentheses can also be requested using =-p=. -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltlfilt -f '[]<>p0 || <>[]p1' formula='& & G p0 p1 p2' ltlfilt --lbt-input -f "$formula" --latex @@ -39,7 +42,7 @@ other syntaxes.) Here are the same operations in Python -#+BEGIN_SRC python :results output :exports both +#+BEGIN_SRC python import spot print(spot.formula('[]<>p0 || <>[]p1')) f = spot.formula('& & G p0 p1 p2') @@ -70,7 +73,7 @@ above in the python bindings. Here parse errors would be returned as exceptions. #+NAME: 1stex -#+BEGIN_SRC C++ :results verbatim :exports both +#+BEGIN_SRC C++ #include #include #include @@ -113,7 +116,7 @@ parser. Additionally, this give you control over how to print errors. Here is how to call the infix parser explicitly: -#+BEGIN_SRC C++ :results verbatim :exports both +#+BEGIN_SRC C++ #include #include #include @@ -157,7 +160,7 @@ about the extra parenthesis, but it will still return a formula that is equivalent to =a U b=. You could decide to continue with the "fixed" formula if you wish. Here is an example: -#+BEGIN_SRC C++ :results verbatim :exports both +#+BEGIN_SRC C++ #include #include #include @@ -197,7 +200,7 @@ really cannot recover anything. The only difference here is the call to =parse_prefix_ltl()= instead of =parse_infix_psl()=. -#+BEGIN_SRC C++ :results verbatim :exports both +#+BEGIN_SRC C++ #include #include #include @@ -241,7 +244,7 @@ down the line. For instance, let's see what happens if a PSL formulas is passed to =print_spin_ltl=: -#+BEGIN_SRC C++ :results verbatim :exports both +#+BEGIN_SRC C++ #include #include #include @@ -270,7 +273,7 @@ If that is unwanted, here are two possible solutions. The first is to simply diagnose non-LTL formulas. -#+BEGIN_SRC C++ :results verbatim :exports code +#+BEGIN_SRC C++ :exports code #include #include #include @@ -299,7 +302,7 @@ equivalent LTL formula. This does not always work, so you need to be prepared to reject the formula anyway. In our example, we are lucky (maybe because it was carefully chosen...): -#+BEGIN_SRC C++ :results verbatim :exports both +#+BEGIN_SRC C++ #include #include #include @@ -342,7 +345,7 @@ syntax for atomic propositions supported by any tool. The usual workaround in Spot is to double-quote any arbitrary atomic proposition: -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh echo compare ltlfilt -f '"a > 4" U "b < 5"' echo and @@ -363,7 +366,7 @@ it has an option for that. This is called /lenient parsing/: when the parser finds a parenthetical block it does not understand, it simply assume that this block represents an atomic proposition. -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltlfilt --lenient -f '(a > 4) U (b < 5)' #+END_SRC @@ -373,7 +376,7 @@ ltlfilt --lenient -f '(a > 4) U (b < 5)' Lenient parsing is risky, because any parenthesized sub-formula that is a syntax-error will be treated as an atomic proposition: -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltlfilt --lenient -f '(a U ) U c' #+END_SRC @@ -388,7 +391,7 @@ Formulas have a custom format specification language that allows you to easily change the way a formula should be output when using the =format()= method of strings. -#+BEGIN_SRC python :results output :exports both +#+BEGIN_SRC python import spot formula = spot.formula('a U b U "$strange[0]=name"') print("""\ @@ -418,7 +421,7 @@ produced from the formula. The complete list of specifier that apply to formulas can always be printed with =help(spot.formula.__format__)=: -#+BEGIN_SRC python :results output :exports results +#+BEGIN_SRC python :exports results import spot help(spot.formula.__format__) #+END_SRC diff --git a/doc/org/tut02.org b/doc/org/tut02.org index cbba341ec..fd4c5ceb3 100644 --- a/doc/org/tut02.org +++ b/doc/org/tut02.org @@ -3,6 +3,9 @@ #+DESCRIPTION: Code example for relabeling formulas in Spot #+INCLUDE: setup.org #+HTML_LINK_UP: tut.html +#+PROPERTY: header-args:sh :results verbatim :exports both +#+PROPERTY: header-args:python :results output :exports both +#+PROPERTY: header-args:C+++ :results verbatim :exports both The task is to read an LTL formula, relabel all (possibly double-quoted) atomic propositions, and provide =#define= statements @@ -10,7 +13,7 @@ for each of these renamings, writing everything in Spin's syntax. * Shell -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltlfilt -ps --relabel=pnn --define -f '"Proc@Here" U ("var > 10" | "var < 4")' #+END_SRC @@ -26,7 +29,7 @@ translator) using a formula with complex atomic propositions it cannot parse. Then you can pass the rewritten formula to =ltl2ba=, and prepend all those =#define= to its output. For instance: -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltlfilt -ps --relabel=pnn --define=tmp.defs -f '"Proc@Here" U ("var > 10" | "var < 4")' >tmp.ltl cat tmp.defs; ltl2ba -F tmp.ltl rm tmp.defs tmp.ltl @@ -38,7 +41,7 @@ rm tmp.defs tmp.ltl #define p1 (var < 4) #define p2 (var > 10) never { /* (p0) U ((p1) || (p2)) - */ + ,*/ T0_init: if :: (p0) -> goto T0_init @@ -51,8 +54,8 @@ accept_all: Aside: another way to work around syntax limitations of tools is to use [[file:ltldo.org][=ltldo=]]. On the above example, =ltldo ltl2ba -f '"Proc@Here" U -("var > 10" | "var < 4")' -s= would produce a never clam with the -correct atomic proposition, even though =ltl2ba= cannot parse them. +("var > 10" | "var < 4")' -s= would produce a never claim with the +correct atomic propositions, even though =ltl2ba= cannot parse them. * Python @@ -60,13 +63,13 @@ The =spot.relabel= function takes an optional third parameter that should be a =relabeling_map=. If supplied, this map is filled with pairs of atomic propositions of the form (new-name, old-name). -#+BEGIN_SRC python :results output :exports both +#+BEGIN_SRC python import spot m = spot.relabeling_map() g = spot.relabel('"Proc@Here" U ("var > 10" | "var < 4")', spot.Pnn, m) for newname, oldname in m.items(): - print("#define {} ({})".format(newname.to_str(), oldname.to_str('spin', True))) -print(g.to_str('spin', True)) + print("#define {} ({})".format(newname.to_str(), oldname.to_str('spin', True))) + print(g.to_str('spin', True)) #+END_SRC #+RESULTS: @@ -79,7 +82,7 @@ print(g.to_str('spin', True)) The =spot::relabeling_map= is just implemented as a =std::map=. -#+BEGIN_SRC C++ :results verbatim :exports both +#+BEGIN_SRC C++ #include #include #include @@ -124,7 +127,7 @@ The =spot::relabeling_map= is just implemented as a =std::map=. Instead of relabeling each atomic proposition, you could decide to relabel each Boolean sub-expression: -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltlfilt -ps --relabel-bool=pnn --define -f '"Proc@Here" U ("var > 10" | "var < 4")' #+END_SRC @@ -140,7 +143,7 @@ ltlfilt -ps --relabel-bool=pnn --define -f '"Proc@Here" U ("var > 10" | "var < 4 because that would hide the fact that both =p0= and =p1= check for =a=. Instead we get this: -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltlfilt -ps --relabel-bool=pnn --define -f 'a U (a & b)' #+END_SRC diff --git a/doc/org/tut03.org b/doc/org/tut03.org index 156254d00..1362e5c61 100644 --- a/doc/org/tut03.org +++ b/doc/org/tut03.org @@ -3,6 +3,8 @@ #+DESCRIPTION: Code example for constructing and transforming formulas in Spot #+INCLUDE: setup.org #+HTML_LINK_UP: tut.html +#+PROPERTY: header-args:python :results output :exports both +#+PROPERTY: header-args:C+++ :results verbatim :exports both This page explains how to build formulas and how to iterate over their syntax trees. @@ -29,7 +31,7 @@ as in =formula::And({arg1, arg2, arg3})=. Here is the list of supported operators: -#+BEGIN_SRC C++ +#+BEGIN_SRC C++ :exports code // atomic proposition formula::ap(string) // constants @@ -88,7 +90,7 @@ Building a formula using these operators is quite straightforward. The second part of the following example shows how to print some detail of the top-level operator in the formula. -#+BEGIN_SRC C++ :results verbatim :exports both +#+BEGIN_SRC C++ #include #include #include @@ -136,7 +138,7 @@ detail of the top-level operator in the formula. The Python equivalent is similar: -#+BEGIN_SRC python :results output :exports both +#+BEGIN_SRC python import spot # Build FGa -> (GFb & GFc) @@ -199,7 +201,7 @@ that tells whether a formula contains a =F= or =G= operator) to save time time by not exploring further. #+NAME: gcount_cpp -#+BEGIN_SRC C++ :results verbatim :exports both +#+BEGIN_SRC C++ #include #include #include @@ -247,7 +249,7 @@ Here is a demonstration of how to exchange all =F= and =G= operators in a formula: #+NAME: xchg_fg_cpp -#+BEGIN_SRC C++ :results verbatim :exports both +#+BEGIN_SRC C++ #include #include #include @@ -275,7 +277,7 @@ in a formula: } #+END_SRC -#+RESULTS: +#+RESULTS: xchg_fg_cpp : before: FGa -> (GFb & GF(b & c & d)) : after: GFa -> (FGb & FG(b & c & d)) @@ -292,7 +294,7 @@ For instance instead of having a lambda capturing the [[gcount_cpp][=gcount= variable in the first example]], we could pass a reference to this variable: -#+BEGIN_SRC C++ :results verbatim :exports both +#+BEGIN_SRC C++ #include #include #include @@ -327,7 +329,7 @@ the case of =map=. Let's write a variant of our [[xchg_fg_cpp][=xchg_fg()= exam that counts the number of exchanges performed. First, we do it without lambda: -#+BEGIN_SRC C++ :results verbatim :exports both +#+BEGIN_SRC C++ #include #include #include @@ -372,7 +374,7 @@ capture itself. A solution is to use =std::function= but that has a large penalty cost. We can work around that by assuming that that address will be passed as an argument (=self=) to the lambda: -#+BEGIN_SRC C++ :results verbatim :exports both +#+BEGIN_SRC C++ #include #include #include @@ -416,7 +418,7 @@ The Python version of the above two examples uses a very similar syntax. Python only supports a very limited form of lambda expressions, so we have to write a standard function instead: -#+BEGIN_SRC python :results output :exports both +#+BEGIN_SRC python import spot gcount = 0 @@ -450,7 +452,7 @@ b & c & d Here is the =F= and =G= exchange: -#+BEGIN_SRC python :results output :exports both +#+BEGIN_SRC python import spot def xchg_fg(i): diff --git a/doc/org/tut04.org b/doc/org/tut04.org index b61ee05f0..9dc199138 100644 --- a/doc/org/tut04.org +++ b/doc/org/tut04.org @@ -3,6 +3,9 @@ #+DESCRIPTION: Code example for testing the equivalence of two LTL or PSL formulas #+INCLUDE: setup.org #+HTML_LINK_UP: tut.html +#+PROPERTY: header-args:sh :results verbatim :exports both +#+PROPERTY: header-args:python :results output :exports both +#+PROPERTY: header-args:C+++ :results verbatim :exports both This page shows how to test whether two LTL/PSL formulas are equivalent, i.e., if they denote the same languages. @@ -13,7 +16,7 @@ Using a =ltlfilt= you can use =--equivalent-to=f= to filter a list of LTL formula and retain only those equivalent to =f=. So this gives an easy way to test the equivalence of two formulas: -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltlfilt -f '(a U b) U a' --equivalent-to 'b U a' #+END_SRC #+RESULTS: @@ -23,7 +26,7 @@ Since the input formula was output, it means it is equivalent to =b U a=. You may want to add =-c= to count the number of formula output if you prefer a 1/0 answer: -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltlfilt -c -f '(a U b) U a' --equivalent-to 'b U a' #+END_SRC #+RESULTS: @@ -55,7 +58,7 @@ and $A_g\otimes A_{\lnot f}$ are empty. We could also write this check by doing [[file:tut10.org][the translation]] and emptiness check ourselves. For instance: -#+BEGIN_SRC python :results output :exports both +#+BEGIN_SRC python import spot def implies(f, g): @@ -76,7 +79,7 @@ print("Equivalent" if equiv(f, g) else "Not equivalent") This can also be done via a =language_containment_checker= object: -#+BEGIN_SRC python :results output :exports both +#+BEGIN_SRC python import spot f = spot.formula("(a U b) U a") g = spot.formula("b U a") @@ -97,7 +100,7 @@ Here are possible C++ implementations using either =are_equivalent()= or the =language_containment_checker=. Note that the =are_equivalent()= function also work with automata. -#+BEGIN_SRC C++ :results verbatim :exports both +#+BEGIN_SRC C++ #include #include #include @@ -113,18 +116,18 @@ int main() #+RESULTS: : Equivalent -#+BEGIN_SRC C++ :results verbatim :exports both - #include - #include - #include +#+BEGIN_SRC C++ +#include +#include +#include - int main() - { - spot::formula f = spot::parse_formula("(a U b) U a"); - spot::formula g = spot::parse_formula("b U a"); - spot::language_containment_checker c; - std::cout << (c.equal(f, g) ? "Equivalent\n" : "Not equivalent\n"); - } +int main() +{ + spot::formula f = spot::parse_formula("(a U b) U a"); + spot::formula g = spot::parse_formula("b U a"); + spot::language_containment_checker c; + std::cout << (c.equal(f, g) ? "Equivalent\n" : "Not equivalent\n"); +} #+END_SRC #+RESULTS: diff --git a/doc/org/tut10.org b/doc/org/tut10.org index 93adbddc9..ecfec2330 100644 --- a/doc/org/tut10.org +++ b/doc/org/tut10.org @@ -3,12 +3,15 @@ #+DESCRIPTION: Code example for translating formulas in Spot #+INCLUDE: setup.org #+HTML_LINK_UP: tut.html +#+PROPERTY: header-args:sh :results verbatim :exports both +#+PROPERTY: header-args:python :results output :exports both +#+PROPERTY: header-args:C+++ :results verbatim :exports both Here is how to translate an LTL (or PSL) formula into a never claim. * Shell -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltl2tgba --spin 'GFa -> GFb' #+END_SRC @@ -17,23 +20,23 @@ ltl2tgba --spin 'GFa -> GFb' never { /* F(GFb | G!a) */ T0_init: if - :: ((!(a))) -> goto accept_S0 - :: ((true)) -> goto T0_init - :: ((b)) -> goto accept_S2 + :: (true) -> goto T0_init + :: (b) -> goto accept_S1 + :: (!(a)) -> goto accept_S2 fi; -accept_S0: +accept_S1: if - :: ((!(a))) -> goto accept_S0 + :: (b) -> goto accept_S1 + :: (!(b)) -> goto T0_S3 fi; accept_S2: if - :: ((b)) -> goto accept_S2 - :: ((!(b))) -> goto T0_S3 + :: (!(a)) -> goto accept_S2 fi; T0_S3: if - :: ((b)) -> goto accept_S2 - :: ((!(b))) -> goto T0_S3 + :: (b) -> goto accept_S1 + :: (!(b)) -> goto T0_S3 fi; } #+end_example @@ -47,7 +50,7 @@ method that can output in one of the supported syntaxes. So the translation is actually a one-liner in Python: -#+BEGIN_SRC python :results output :exports both +#+BEGIN_SRC python import spot print(spot.formula('GFa -> GFb').translate('BA').to_str('spin')) #+END_SRC @@ -57,23 +60,23 @@ print(spot.formula('GFa -> GFb').translate('BA').to_str('spin')) never { T0_init: if - :: ((!(a))) -> goto accept_S0 - :: ((true)) -> goto T0_init - :: ((b)) -> goto accept_S2 + :: (true) -> goto T0_init + :: (b) -> goto accept_S1 + :: (!(a)) -> goto accept_S2 fi; -accept_S0: +accept_S1: if - :: ((!(a))) -> goto accept_S0 + :: (b) -> goto accept_S1 + :: (!(b)) -> goto T0_S3 fi; accept_S2: if - :: ((b)) -> goto accept_S2 - :: ((!(b))) -> goto T0_S3 + :: (!(a)) -> goto accept_S2 fi; T0_S3: if - :: ((b)) -> goto accept_S2 - :: ((!(b))) -> goto T0_S3 + :: (b) -> goto accept_S1 + :: (!(b)) -> goto T0_S3 fi; } @@ -83,7 +86,7 @@ The above line can actually be made a bit shorter, because =translate()= can also be used as a function (as opposed to a method) that takes a formula (possibly as a string) as first argument: -#+BEGIN_SRC python :results output :exports both +#+BEGIN_SRC python import spot print(spot.translate('GFa -> GFb', 'BA').to_str('spin')) #+END_SRC @@ -93,23 +96,23 @@ print(spot.translate('GFa -> GFb', 'BA').to_str('spin')) never { T0_init: if - :: ((!(a))) -> goto accept_S0 - :: ((true)) -> goto T0_init - :: ((b)) -> goto accept_S2 + :: (true) -> goto T0_init + :: (b) -> goto accept_S1 + :: (!(a)) -> goto accept_S2 fi; -accept_S0: +accept_S1: if - :: ((!(a))) -> goto accept_S0 + :: (b) -> goto accept_S1 + :: (!(b)) -> goto T0_S3 fi; accept_S2: if - :: ((b)) -> goto accept_S2 - :: ((!(b))) -> goto T0_S3 + :: (!(a)) -> goto accept_S2 fi; T0_S3: if - :: ((b)) -> goto accept_S2 - :: ((!(b))) -> goto T0_S3 + :: (b) -> goto accept_S1 + :: (!(b)) -> goto T0_S3 fi; } @@ -127,7 +130,7 @@ various preferences (like small or deterministic) or characteristic (complete, unambiguous) for the resulting automaton. Finally, the output as a never claim is done via the =print_never_claim= function. -#+BEGIN_SRC C++ :results verbatim :exports both +#+BEGIN_SRC C++ #include #include #include @@ -151,22 +154,22 @@ output as a never claim is done via the =print_never_claim= function. never { T0_init: if - :: (p1) -> goto accept_S0 :: (true) -> goto T0_init - :: (p0) -> goto accept_S2 + :: (p0) -> goto accept_S1 + :: (p1) -> goto accept_S2 fi; -accept_S0: +accept_S1: if - :: (p1) -> goto accept_S0 + :: (p0) -> goto accept_S1 + :: (!(p0)) -> goto T0_S3 fi; accept_S2: if - :: (p0) -> goto accept_S2 - :: (!(p0)) -> goto T0_S3 + :: (p1) -> goto accept_S2 fi; T0_S3: if - :: (p0) -> goto accept_S2 + :: (p0) -> goto accept_S1 :: (!(p0)) -> goto T0_S3 fi; } @@ -176,7 +179,7 @@ T0_S3: The Python version of =translate()= is documented as follows: -#+BEGIN_SRC python :results output :exports both +#+BEGIN_SRC python :exports results import spot help(spot.translate) #+END_SRC @@ -185,22 +188,30 @@ help(spot.translate) #+begin_example Help on function translate in module spot: -translate(formula, *args) +translate(formula, *args, dict= *' at 0x7f1f9541c090> >, xargs=None) Translate a formula into an automaton. - Keep in mind that pref expresses just a preference that may not be - satisfied. + Keep in mind that 'Deterministic' expresses just a preference that + may not be satisfied. The optional arguments should be strings among the following: - - at most one in 'TGBA', 'BA', or 'Monitor' - (type of automaton to build) + - at most one in 'TGBA', 'BA', or 'Monitor', 'generic', + 'parity', 'parity min odd', 'parity min even', + 'parity max odd', 'parity max even' (type of automaton to + build), 'coBuchi' - at most one in 'Small', 'Deterministic', 'Any' (preferred characteristics of the produced automaton) - at most one in 'Low', 'Medium', 'High' (optimization level) - - any combination of 'Complete', 'Unambiguous', and - 'StateBasedAcceptance' (or 'SBAcc' for short) + - any combination of 'Complete', 'Unambiguous', + 'StateBasedAcceptance' (or 'SBAcc' for short), and + 'Colored' (only for parity acceptance) - The default correspond to 'tgba', 'small' and 'high'. + The default corresponds to 'tgba', 'small' and 'high'. + + Additional options can be supplied using a `spot.option_map`, or a + string (that will be converted to `spot.option_map`), as the `xargs` + argument. This is similar to the `-x` option of command-line tools; + so check out the spot-x(7) man page for details. #+end_example diff --git a/doc/org/tut11.org b/doc/org/tut11.org index 23f69c09e..ee2a8a9e4 100644 --- a/doc/org/tut11.org +++ b/doc/org/tut11.org @@ -3,6 +3,9 @@ #+DESCRIPTION: Code example for using Spot to translating formulas in monitors #+INCLUDE: setup.org #+HTML_LINK_UP: tut.html +#+PROPERTY: header-args:sh :results verbatim :exports both +#+PROPERTY: header-args:python :results output :exports both +#+PROPERTY: header-args:C+++ :results verbatim :exports both A monitor is a special type of automaton that is supposed to /monitor/ a running system and move accordingly. A monitor detects an error @@ -13,7 +16,7 @@ For instance here is a monitor that checks that *yellow* never occurs immediately after *red*. #+NAME: tut11a -#+BEGIN_SRC sh :results verbatim :exports none +#+BEGIN_SRC sh :exports none ltl2tgba -D -M '!F(red & Xyellow)' -d #+END_SRC @@ -39,7 +42,7 @@ that case a violation should be reported. To build the above deterministic monitor using [[file:ltl2tgba.org][=ltl2tgba=]], we simply pass option =-M= (for monitor) and =-D= (for deterministic). -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltl2tgba -D -M '!F(red & X(yellow))' #+END_SRC @@ -69,7 +72,7 @@ The code is very similar to [[file:tut10.org][our previous example of building a claim]] except that we explicitly require a deterministic monitor and output in the [[file:hoa.org][HOA format]]. -#+BEGIN_SRC python :results output :exports both +#+BEGIN_SRC python import spot print(spot.translate('!F(red & X(yellow))', 'monitor', 'det').to_str('HOA')) #+END_SRC @@ -97,7 +100,7 @@ State: 1 The code very similar to [[file:tut10.org][the never claim example]]. -#+BEGIN_SRC C++ :results verbatim :exports both +#+BEGIN_SRC C++ #include #include #include @@ -154,7 +157,7 @@ In the [[file:hierarchy.org][hierarchy of temporal properties]], the properties monitorable correspond to the class of [[file:hierarchy.org::#safety][safety properties]]. You can check that an LTL formula is a safety by using: -#+BEGIN_SRC sh :results verbatim :exports both +#+BEGIN_SRC sh ltlfilt --count --safety -f '!F(red & X(yellow))' #+END_SRC @@ -173,22 +176,16 @@ red light will be on until the green light is on, we would use the following formula: =G(press -> red U green)=. Unfortunately it is not a safety property: -#+BEGIN_SRC sh :results verbatim :exports code +#+BEGIN_SRC sh :epilogue true ltlfilt --count --safety -f 'G(press -> red U green)' #+END_SRC - -#+BEGIN_SRC sh :results verbatim :exports results -ltlfilt --count --safety -f 'G(press -> red U green)' -true -#+END_SRC - #+RESULTS: : 0 Nonetheless, we can still build a monitor for it: #+NAME: tut11b -#+BEGIN_SRC sh :results verbatim :exports none +#+BEGIN_SRC sh :exports none ltl2tgba -D -M 'G(press -> red U green)' -d #+END_SRC #+BEGIN_SRC dot :file tut11b.svg :var txt=tut11b :exports results @@ -233,7 +230,7 @@ The following code shows how to implement the above five steps in C++ without using =spot::translator=. Unless you plan to customize some of these steps, we recommend you use =spot::translator= instead. -#+BEGIN_SRC C++ :results verbatim :exports both +#+BEGIN_SRC C++ #include #include #include diff --git a/doc/org/tut12.org b/doc/org/tut12.org index 741053597..1a77dc74f 100644 --- a/doc/org/tut12.org +++ b/doc/org/tut12.org @@ -3,20 +3,23 @@ #+DESCRIPTION: Code example for using Spot to translate LTLf formulas #+INCLUDE: setup.org #+HTML_LINK_UP: tut.html +#+PROPERTY: header-args:sh :results verbatim :exports both +#+PROPERTY: header-args:python :results output :exports both +#+PROPERTY: header-args:C+++ :results verbatim :exports both The LTL operators used by Spot are defined over infinite words, and the various type of automata supported are all \omega-automata, i.e., automata over infinite words. +#+name: from_ltlf +#+begin_src sh :exports none :var f="bug" +ltlfilt --from-ltlf -f "$f" +#+end_src + However there is a trick we can use in case we want to use Spot to build a finite automaton that recognize some LTLf (i.e. LTL with finite semantics) property. The plan is as follows: -#+name: from_ltlf -#+begin_src sh :results verbatim :exports none :var f="bug" -ltlfilt --from-ltlf -f "$f" -#+end_src - 1. Have Spot read the input formula as if it were LTL. 2. Rewrite this formula in a way that embeds the semantics of LTLf in LTL. First, introduce a new atomic proposition =alive= that will @@ -27,7 +30,7 @@ ltlfilt --from-ltlf -f "$f" call_from_ltlf(f="(a U b) & Fc"). 3. Convert the resulting formula into a Büchi automaton: #+name: tut12a - #+begin_src sh :results verbatim :exports none + #+begin_src sh :exports none ltlfilt --from-ltlf -f "(a U b) & Fc" | ltl2tgba -B -d #+end_src #+BEGIN_SRC dot :file tut12a.svg :var txt=tut12a :exports results @@ -38,7 +41,7 @@ ltlfilt --from-ltlf -f "$f" 4. Remove the =alive= property, and, while we are at it, simplify the Büchi automaton: #+name: tut12b - #+begin_src sh :results verbatim :exports none + #+begin_src sh :exports none ltlfilt --from-ltlf -f "(a U b) & Fc" | ltl2tgba -B | autfilt --remove-ap=alive -B --small -d #+end_src #+BEGIN_SRC dot :file tut12b.svg :var txt=tut12b :exports results @@ -68,7 +71,7 @@ an atomic proposition from an automaton can be done using [[file:autfilt.org][=a automaton). Interpreting the resulting Büchi automaton as a finite automaton is out of scope for Spot. -#+begin_src sh :exports both :results verbatim +#+begin_src sh ltlfilt --from-ltlf -f "(a U b) & Fc" | ltl2tgba -B | autfilt --remove-ap=alive -B --small @@ -115,7 +118,7 @@ simplifications. (Note that =postprocess()= is already called by =translate()=, but in this case removing the atomic proposition allows more simplification opportunities.) -#+begin_src python :results output :exports both +#+begin_src python import spot # Translate LTLf to Büchi. aut = spot.from_ltlf('(a U b) & Fc').translate('ba') @@ -163,37 +166,37 @@ The Python functions =translate()= and =postprocess()= are convenient wrappers around the =spot::translator= and =spot::postprocessor= objects that we need to use here. -#+begin_src cpp :results verbatim :exports both - #include - #include - #include - #include - #include - #include +#+begin_src C++ +#include +#include +#include +#include +#include +#include - int main() - { - spot::parsed_formula pf = spot::parse_infix_psl("(a U b) & Fc"); - if (pf.format_errors(std::cerr)) - return 1; +int main() +{ + spot::parsed_formula pf = spot::parse_infix_psl("(a U b) & Fc"); + if (pf.format_errors(std::cerr)) + return 1; - spot::translator trans; - trans.set_type(spot::postprocessor::BA); - trans.set_pref(spot::postprocessor::Small); - spot::twa_graph_ptr aut = trans.run(spot::from_ltlf(pf.f)); + spot::translator trans; + trans.set_type(spot::postprocessor::BA); + trans.set_pref(spot::postprocessor::Small); + spot::twa_graph_ptr aut = trans.run(spot::from_ltlf(pf.f)); - spot::remove_ap rem; - rem.add_ap("alive"); - aut = rem.strip(aut); + spot::remove_ap rem; + rem.add_ap("alive"); + aut = rem.strip(aut); - spot::postprocessor post; - post.set_type(spot::postprocessor::BA); - post.set_pref(spot::postprocessor::Small); // or ::Deterministic - aut = post.run(aut); + spot::postprocessor post; + post.set_type(spot::postprocessor::BA); + post.set_pref(spot::postprocessor::Small); // or ::Deterministic + aut = post.run(aut); - print_hoa(std::cout, aut) << '\n'; - return 0; - } + print_hoa(std::cout, aut) << '\n'; + return 0; +} #+end_src #+RESULTS: diff --git a/doc/org/tut20.org b/doc/org/tut20.org index b3793d049..74a4d62f2 100644 --- a/doc/org/tut20.org +++ b/doc/org/tut20.org @@ -3,12 +3,15 @@ #+DESCRIPTION: Code example for parsing and printing ω-automata in Spot #+INCLUDE: setup.org #+HTML_LINK_UP: tut.html +#+PROPERTY: header-args:sh :results verbatim :exports both +#+PROPERTY: header-args:python :results output :exports both +#+PROPERTY: header-args:C+++ :results verbatim :exports both The goal is to start from a never claim, as produced by Spin, e.g.: -#+BEGIN_SRC sh :results verbatim :exports both -spin -f '[]<>foo U bar' > tut20.never -cat tut20.never +#+BEGIN_SRC sh + spin -f '[]<>foo U bar' > tut20.never + cat tut20.never #+END_SRC #+RESULTS: @@ -52,12 +55,12 @@ write will read any of those formats. This is very simple: [[file:autfilt.org][=autfilt=]] can read automata in any of the supported formats, and outputs it in the HOA format by default: -#+BEGIN_SRC sh :results verbatim :exports both :wrap SRC hoa +#+BEGIN_SRC sh :wrap SRC hoa autfilt tut20.never #+END_SRC #+RESULTS: -#+BEGIN_SRC hoa +#+begin_SRC hoa HOA: v1 States: 5 Start: 0 @@ -81,7 +84,7 @@ State: 4 [1] 3 [t] 4 --END-- -#+END_SRC +#+end_SRC * Python @@ -89,13 +92,13 @@ Another one-liner. The =spot.automaton()= function reads a single automaton, and each automaton has a =to_str()= method that can print in =hoa=, =lbtt=, =spin= (for never claim) or =dot=. -#+BEGIN_SRC python :results output :exports both :wrap SRC hoa +#+BEGIN_SRC python :wrap SRC hoa import spot print(spot.automaton('tut20.never').to_str('hoa')) #+END_SRC #+RESULTS: -#+BEGIN_SRC hoa +#+begin_SRC hoa HOA: v1 States: 5 Start: 0 @@ -119,7 +122,7 @@ State: 4 [1] 3 [t] 4 --END-- -#+END_SRC +#+end_SRC * C++ @@ -134,7 +137,7 @@ you), and =aut= is the actual automaton. The parser usually tries to recover from errors, so =aut= may not be null even if =errors= is non-empty. -#+BEGIN_SRC C++ :results verbatim :exports both :wrap SRC hoa +#+BEGIN_SRC C++ :wrap SRC hoa #include #include #include @@ -159,7 +162,7 @@ non-empty. #+END_SRC #+RESULTS: -#+BEGIN_SRC hoa +#+begin_SRC hoa HOA: v1 States: 5 Start: 0 @@ -183,7 +186,7 @@ State: 4 [1] 3 [t] 4 --END-- -#+END_SRC +#+end_SRC In the Spot representation of automata, transitions guards are represented by BDDs. The role of the =bdd_dict= object is to keep @@ -222,14 +225,14 @@ wrapper that instantiates an =automaton_stream_parser= and calls its In Python, you can easily iterate over a file containing multiple automata by doing: -#+BEGIN_SRC python :results output :exports code :wrap SRC hoa +#+BEGIN_SRC python :wrap SRC hoa import spot for aut in spot.automata('tut20.never'): print(aut.to_str('hoa')) #+END_SRC #+RESULTS: -#+BEGIN_SRC hoa +#+begin_SRC hoa HOA: v1 States: 5 Start: 0 @@ -253,7 +256,7 @@ State: 4 [1] 3 [t] 4 --END-- -#+END_SRC +#+end_SRC In fact =spot.automaton()= is just a wrapper around =spot.automata()= to return only the first automaton. @@ -265,7 +268,7 @@ accept three types of arguments: be any shell expression, and must have '=|=' as their last character. For instance here is how to convert Spin's output into LBTT's formula without using temporary files. -#+BEGIN_SRC python :results output :exports both +#+BEGIN_SRC python import spot print(spot.automaton('spin -f "[]<>p0" |').to_str('lbtt')) #+END_SRC @@ -285,7 +288,7 @@ print(spot.automaton('spin -f "[]<>p0" |').to_str('lbtt')) to describe an automaton (or multiple automata) and is passed directly to the parser: -#+BEGIN_SRC python :results output :exports both +#+BEGIN_SRC python import spot print(spot.automaton(""" HOA: v1 @@ -306,7 +309,7 @@ State: 1 {0} : never { : T0_init: : if -: :: ((a)) -> goto accept_all +: :: (a) -> goto accept_all : fi; : accept_all: : skip diff --git a/doc/org/tut21.org b/doc/org/tut21.org index 54bd98c6f..8904d2915 100644 --- a/doc/org/tut21.org +++ b/doc/org/tut21.org @@ -3,6 +3,9 @@ #+DESCRIPTION: Code example for iterating over ω-automata in Spot #+INCLUDE: setup.org #+HTML_LINK_UP: tut.html +#+PROPERTY: header-args:sh :results verbatim :exports both +#+PROPERTY: header-args:python :results output :exports both +#+PROPERTY: header-args:C+++ :results verbatim :exports both This example demonstrates how to iterate over an automaton in C++ and Python. This case uses automata stored entirely in memory as a graph: @@ -26,14 +29,14 @@ First let's create an example automaton in HOA format. We use =-U= to request unambiguous automata, as this allows us to demonstrate how property bits are used. -#+BEGIN_SRC sh :results verbatim :exports both :wrap SRC hoa +#+BEGIN_SRC sh :wrap SRC hoa ltl2tgba -U 'Fa | G(Fb&Fc)' | tee tut21.hoa #+END_SRC #+RESULTS: -#+BEGIN_SRC hoa +#+begin_SRC hoa HOA: v1 -name: "Fa | G(Fb & Fc)" -States: 4 +name: "F(a | G(Fb & Fc))" +States: 17 Start: 0 AP: 3 "a" "b" "c" acc-name: generalized-Buchi 2 @@ -44,19 +47,102 @@ properties: stutter-invariant State: 0 [0] 1 [!0] 2 -[!0] 3 +[!0&1&2] 3 +[!0&!1&2] 4 +[!0&!2] 5 +[!0&!2] 6 State: 1 [t] 1 {0 1} State: 2 -[0] 1 -[!0] 2 +[!1&!2] 2 +[!1&2] 2 {1} +[1&!2] 2 {0} +[1&2] 2 {0 1} State: 3 -[!0&1&2] 3 {0 1} -[!0&!1&2] 3 {1} -[!0&1&!2] 3 {0} -[!0&!1&!2] 3 +[!0&1&2] 3 +[!0&!1&2] 4 +[!0&!2] 5 +[!0&!2] 6 +[0&!2] 7 +[0&!1&2] 8 +[0&1&2] 9 +[0&!1&2] 10 +[0&1&!2] 11 +[0&!1&!2] 12 +[0&!1&!2] 13 +State: 4 +[!0&1&2] 3 +[!0&!1&2] 4 +[!0&!2] 5 +[!0&1&!2] 6 +[0&1&!2] 7 +[0&!1] 8 +[0&1&2] 9 +[0&!1&2] 10 +[0&1&!2] 11 +[0&!1&!2] 12 +[0&!1&!2] 14 +[!0&!1&!2] 15 +State: 5 +[!0&1&2] 3 +[!0&!1&2] 4 +[!0&!2] 5 +[0&!1&2] 8 +[0&1&2] 9 +[0&!1&2] 10 +[0&1&!2] 11 +[0&!1&!2] 12 +[0&!1&!2] 13 +State: 6 +[!0&!2] 6 +[0&!2] 7 +State: 7 +[!2] 7 {0 1} +State: 8 +[!1] 8 {0 1} +State: 9 +[!2] 7 +[!1&2] 8 +[1&2] 9 +[!1&2] 10 +[1&!2] 11 +[!1&!2] 12 +[!1&!2] 13 +State: 10 +[1&!2] 7 +[1&2] 9 +[!1&2] 10 +[1&!2] 11 +[!1&!2] 12 +[!1&!2] 14 +State: 11 +[!1&2] 8 +[1&2] 9 +[!1&2] 10 +[1&!2] 11 +[!1&!2] 12 +[!1&!2] 13 +State: 12 +[1&2] 9 +[!1&2] 10 +[1&!2] 11 +[!1&!2] 12 +State: 13 +[!1&2] 8 +[!1&!2] 13 +State: 14 +[1&!2] 7 +[!1&!2] 14 +State: 15 +[!0&1&!2] 6 +[0&1&!2] 7 +[0&!1&!2] 14 +[!0&!1&!2] 15 +[0&!1&!2] 16 +State: 16 +[!1&!2] 16 {0 1} --END-- -#+END_SRC +#+end_SRC * C++ @@ -76,7 +162,7 @@ into a BDD, use the =bdd_dict::varnum()= method to obtain the corresponding BDD variable number, and then use for instance =bdd_ithvar()= to convert this BDD variable number into an actual BDD. -#+BEGIN_SRC C++ :results verbatim :exports both +#+BEGIN_SRC C++ #include #include #include @@ -163,12 +249,286 @@ corresponding BDD variable number, and then use for instance #+END_SRC #+RESULTS: +#+begin_example +Acceptance: Inf(0)&Inf(1) +Number of sets: 2 +Number of states: 17 +Number of edges: 80 +Initial state: 0 +Atomic propositions: a (=0) b (=1) c (=2) +Name: F(a | G(Fb & Fc)) +Complete: no +Deterministic: no +Unambiguous: yes +State-Based Acc: maybe +Terminal: maybe +Weak: maybe +Inherently Weak: maybe +Stutter Invariant: yes +State 0: + edge(0 -> 1) + label = a + acc sets = {} + edge(0 -> 2) + label = !a + acc sets = {} + edge(0 -> 3) + label = !a & b & c + acc sets = {} + edge(0 -> 4) + label = !a & !b & c + acc sets = {} + edge(0 -> 5) + label = !a & !c + acc sets = {} + edge(0 -> 6) + label = !a & !c + acc sets = {} +State 1: + edge(1 -> 1) + label = 1 + acc sets = {0,1} +State 2: + edge(2 -> 2) + label = !b & !c + acc sets = {} + edge(2 -> 2) + label = !b & c + acc sets = {1} + edge(2 -> 2) + label = b & !c + acc sets = {0} + edge(2 -> 2) + label = b & c + acc sets = {0,1} +State 3: + edge(3 -> 3) + label = !a & b & c + acc sets = {} + edge(3 -> 4) + label = !a & !b & c + acc sets = {} + edge(3 -> 5) + label = !a & !c + acc sets = {} + edge(3 -> 6) + label = !a & !c + acc sets = {} + edge(3 -> 7) + label = a & !c + acc sets = {} + edge(3 -> 8) + label = a & !b & c + acc sets = {} + edge(3 -> 9) + label = a & b & c + acc sets = {} + edge(3 -> 10) + label = a & !b & c + acc sets = {} + edge(3 -> 11) + label = a & b & !c + acc sets = {} + edge(3 -> 12) + label = a & !b & !c + acc sets = {} + edge(3 -> 13) + label = a & !b & !c + acc sets = {} +State 4: + edge(4 -> 3) + label = !a & b & c + acc sets = {} + edge(4 -> 4) + label = !a & !b & c + acc sets = {} + edge(4 -> 5) + label = !a & !c + acc sets = {} + edge(4 -> 6) + label = !a & b & !c + acc sets = {} + edge(4 -> 7) + label = a & b & !c + acc sets = {} + edge(4 -> 8) + label = a & !b + acc sets = {} + edge(4 -> 9) + label = a & b & c + acc sets = {} + edge(4 -> 10) + label = a & !b & c + acc sets = {} + edge(4 -> 11) + label = a & b & !c + acc sets = {} + edge(4 -> 12) + label = a & !b & !c + acc sets = {} + edge(4 -> 14) + label = a & !b & !c + acc sets = {} + edge(4 -> 15) + label = !a & !b & !c + acc sets = {} +State 5: + edge(5 -> 3) + label = !a & b & c + acc sets = {} + edge(5 -> 4) + label = !a & !b & c + acc sets = {} + edge(5 -> 5) + label = !a & !c + acc sets = {} + edge(5 -> 8) + label = a & !b & c + acc sets = {} + edge(5 -> 9) + label = a & b & c + acc sets = {} + edge(5 -> 10) + label = a & !b & c + acc sets = {} + edge(5 -> 11) + label = a & b & !c + acc sets = {} + edge(5 -> 12) + label = a & !b & !c + acc sets = {} + edge(5 -> 13) + label = a & !b & !c + acc sets = {} +State 6: + edge(6 -> 6) + label = !a & !c + acc sets = {} + edge(6 -> 7) + label = a & !c + acc sets = {} +State 7: + edge(7 -> 7) + label = !c + acc sets = {0,1} +State 8: + edge(8 -> 8) + label = !b + acc sets = {0,1} +State 9: + edge(9 -> 7) + label = !c + acc sets = {} + edge(9 -> 8) + label = !b & c + acc sets = {} + edge(9 -> 9) + label = b & c + acc sets = {} + edge(9 -> 10) + label = !b & c + acc sets = {} + edge(9 -> 11) + label = b & !c + acc sets = {} + edge(9 -> 12) + label = !b & !c + acc sets = {} + edge(9 -> 13) + label = !b & !c + acc sets = {} +State 10: + edge(10 -> 7) + label = b & !c + acc sets = {} + edge(10 -> 9) + label = b & c + acc sets = {} + edge(10 -> 10) + label = !b & c + acc sets = {} + edge(10 -> 11) + label = b & !c + acc sets = {} + edge(10 -> 12) + label = !b & !c + acc sets = {} + edge(10 -> 14) + label = !b & !c + acc sets = {} +State 11: + edge(11 -> 8) + label = !b & c + acc sets = {} + edge(11 -> 9) + label = b & c + acc sets = {} + edge(11 -> 10) + label = !b & c + acc sets = {} + edge(11 -> 11) + label = b & !c + acc sets = {} + edge(11 -> 12) + label = !b & !c + acc sets = {} + edge(11 -> 13) + label = !b & !c + acc sets = {} +State 12: + edge(12 -> 9) + label = b & c + acc sets = {} + edge(12 -> 10) + label = !b & c + acc sets = {} + edge(12 -> 11) + label = b & !c + acc sets = {} + edge(12 -> 12) + label = !b & !c + acc sets = {} +State 13: + edge(13 -> 8) + label = !b & c + acc sets = {} + edge(13 -> 13) + label = !b & !c + acc sets = {} +State 14: + edge(14 -> 7) + label = b & !c + acc sets = {} + edge(14 -> 14) + label = !b & !c + acc sets = {} +State 15: + edge(15 -> 6) + label = !a & b & !c + acc sets = {} + edge(15 -> 7) + label = a & b & !c + acc sets = {} + edge(15 -> 14) + label = a & !b & !c + acc sets = {} + edge(15 -> 15) + label = !a & !b & !c + acc sets = {} + edge(15 -> 16) + label = a & !b & !c + acc sets = {} +State 16: + edge(16 -> 16) + label = !b & !c + acc sets = {0,1} +#+end_example * Python Here is the very same example, but written in Python: -#+BEGIN_SRC python :results output :exports both +#+BEGIN_SRC python import spot @@ -215,12 +575,12 @@ Here is the very same example, but written in Python: #+begin_example Acceptance: Inf(0)&Inf(1) Number of sets: 2 -Number of states: 4 +Number of states: 17 Initial states: 0 Atomic propositions: a (=0) b (=1) c (=2) -Name: Fa | G(Fb & Fc) +Name: F(a | G(Fb & Fc)) Deterministic: no -Unambiguous: maybe +Unambiguous: yes State-Based Acc: maybe Terminal: maybe Weak: maybe @@ -234,35 +594,257 @@ State 0: label = !a acc sets = {} edge(0 -> 3) - label = !a + label = !a & b & c + acc sets = {} + edge(0 -> 4) + label = !a & !b & c + acc sets = {} + edge(0 -> 5) + label = !a & !c + acc sets = {} + edge(0 -> 6) + label = !a & !c acc sets = {} State 1: edge(1 -> 1) label = 1 acc sets = {0,1} State 2: - edge(2 -> 1) - label = a + edge(2 -> 2) + label = !b & !c acc sets = {} edge(2 -> 2) - label = !a - acc sets = {} + label = !b & c + acc sets = {1} + edge(2 -> 2) + label = b & !c + acc sets = {0} + edge(2 -> 2) + label = b & c + acc sets = {0,1} State 3: edge(3 -> 3) label = !a & b & c - acc sets = {0,1} - edge(3 -> 3) + acc sets = {} + edge(3 -> 4) label = !a & !b & c - acc sets = {1} - edge(3 -> 3) + acc sets = {} + edge(3 -> 5) + label = !a & !c + acc sets = {} + edge(3 -> 6) + label = !a & !c + acc sets = {} + edge(3 -> 7) + label = a & !c + acc sets = {} + edge(3 -> 8) + label = a & !b & c + acc sets = {} + edge(3 -> 9) + label = a & b & c + acc sets = {} + edge(3 -> 10) + label = a & !b & c + acc sets = {} + edge(3 -> 11) + label = a & b & !c + acc sets = {} + edge(3 -> 12) + label = a & !b & !c + acc sets = {} + edge(3 -> 13) + label = a & !b & !c + acc sets = {} +State 4: + edge(4 -> 3) + label = !a & b & c + acc sets = {} + edge(4 -> 4) + label = !a & !b & c + acc sets = {} + edge(4 -> 5) + label = !a & !c + acc sets = {} + edge(4 -> 6) label = !a & b & !c - acc sets = {0} - edge(3 -> 3) + acc sets = {} + edge(4 -> 7) + label = a & b & !c + acc sets = {} + edge(4 -> 8) + label = a & !b + acc sets = {} + edge(4 -> 9) + label = a & b & c + acc sets = {} + edge(4 -> 10) + label = a & !b & c + acc sets = {} + edge(4 -> 11) + label = a & b & !c + acc sets = {} + edge(4 -> 12) + label = a & !b & !c + acc sets = {} + edge(4 -> 14) + label = a & !b & !c + acc sets = {} + edge(4 -> 15) label = !a & !b & !c acc sets = {} +State 5: + edge(5 -> 3) + label = !a & b & c + acc sets = {} + edge(5 -> 4) + label = !a & !b & c + acc sets = {} + edge(5 -> 5) + label = !a & !c + acc sets = {} + edge(5 -> 8) + label = a & !b & c + acc sets = {} + edge(5 -> 9) + label = a & b & c + acc sets = {} + edge(5 -> 10) + label = a & !b & c + acc sets = {} + edge(5 -> 11) + label = a & b & !c + acc sets = {} + edge(5 -> 12) + label = a & !b & !c + acc sets = {} + edge(5 -> 13) + label = a & !b & !c + acc sets = {} +State 6: + edge(6 -> 6) + label = !a & !c + acc sets = {} + edge(6 -> 7) + label = a & !c + acc sets = {} +State 7: + edge(7 -> 7) + label = !c + acc sets = {0,1} +State 8: + edge(8 -> 8) + label = !b + acc sets = {0,1} +State 9: + edge(9 -> 7) + label = !c + acc sets = {} + edge(9 -> 8) + label = !b & c + acc sets = {} + edge(9 -> 9) + label = b & c + acc sets = {} + edge(9 -> 10) + label = !b & c + acc sets = {} + edge(9 -> 11) + label = b & !c + acc sets = {} + edge(9 -> 12) + label = !b & !c + acc sets = {} + edge(9 -> 13) + label = !b & !c + acc sets = {} +State 10: + edge(10 -> 7) + label = b & !c + acc sets = {} + edge(10 -> 9) + label = b & c + acc sets = {} + edge(10 -> 10) + label = !b & c + acc sets = {} + edge(10 -> 11) + label = b & !c + acc sets = {} + edge(10 -> 12) + label = !b & !c + acc sets = {} + edge(10 -> 14) + label = !b & !c + acc sets = {} +State 11: + edge(11 -> 8) + label = !b & c + acc sets = {} + edge(11 -> 9) + label = b & c + acc sets = {} + edge(11 -> 10) + label = !b & c + acc sets = {} + edge(11 -> 11) + label = b & !c + acc sets = {} + edge(11 -> 12) + label = !b & !c + acc sets = {} + edge(11 -> 13) + label = !b & !c + acc sets = {} +State 12: + edge(12 -> 9) + label = b & c + acc sets = {} + edge(12 -> 10) + label = !b & c + acc sets = {} + edge(12 -> 11) + label = b & !c + acc sets = {} + edge(12 -> 12) + label = !b & !c + acc sets = {} +State 13: + edge(13 -> 8) + label = !b & c + acc sets = {} + edge(13 -> 13) + label = !b & !c + acc sets = {} +State 14: + edge(14 -> 7) + label = b & !c + acc sets = {} + edge(14 -> 14) + label = !b & !c + acc sets = {} +State 15: + edge(15 -> 6) + label = !a & b & !c + acc sets = {} + edge(15 -> 7) + label = a & b & !c + acc sets = {} + edge(15 -> 14) + label = a & !b & !c + acc sets = {} + edge(15 -> 15) + label = !a & !b & !c + acc sets = {} + edge(15 -> 16) + label = a & !b & !c + acc sets = {} +State 16: + edge(16 -> 16) + label = !b & !c + acc sets = {0,1} #+end_example - #+BEGIN_SRC sh :results silent :exports results rm -f tut21.hoa #+END_SRC diff --git a/doc/org/tut22.org b/doc/org/tut22.org index 2ce0ca547..d6db5156a 100644 --- a/doc/org/tut22.org +++ b/doc/org/tut22.org @@ -3,6 +3,8 @@ #+DESCRIPTION: Code example for constructing ω-automata in Spot #+INCLUDE: setup.org #+HTML_LINK_UP: tut.html +#+PROPERTY: header-args:python :results output :exports both :wrap SRC hoa +#+PROPERTY: header-args:C+++ :results verbatim :exports both :wrap SRC hoa This example demonstrates how to create an automaton and then print it. @@ -19,7 +21,7 @@ automata in Spot. :CUSTOM_ID: cpp :END: -#+BEGIN_SRC C++ :results verbatim :exports both :wrap SRC hoa +#+BEGIN_SRC C++ #include #include #include @@ -63,7 +65,7 @@ automata in Spot. #+END_SRC #+RESULTS: -#+BEGIN_SRC hoa +#+begin_SRC hoa HOA: v1 States: 3 Start: 0 @@ -80,11 +82,11 @@ State: 1 State: 2 [0 | 1] 1 {0 1} --END-- -#+END_SRC +#+end_SRC ** Python -#+BEGIN_SRC python :results output :exports both :wrap SRC hoa +#+BEGIN_SRC python import spot import buddy @@ -124,7 +126,7 @@ State: 2 #+END_SRC #+RESULTS: -#+BEGIN_SRC hoa +#+begin_SRC hoa HOA: v1 States: 3 Start: 0 @@ -141,7 +143,7 @@ State: 1 State: 2 [0 | 1] 1 {0 1} --END-- -#+END_SRC +#+end_SRC * Büchi automaton, with state-based acceptance :PROPERTIES: @@ -172,7 +174,7 @@ whenever possible". ** C++ -#+BEGIN_SRC C++ :results verbatim :exports both :wrap SRC hoa +#+BEGIN_SRC C++ #include #include #include @@ -240,7 +242,7 @@ State: 2 ** Python -#+BEGIN_SRC python :results output :exports both :wrap SRC hoa +#+BEGIN_SRC python import spot import buddy @@ -313,7 +315,7 @@ Arbitrary acceptance condition can be set with =set_acceptance=. ** C++ -#+BEGIN_SRC C++ :results verbatim :exports both :wrap SRC hoa +#+BEGIN_SRC C++ #include #include #include @@ -362,7 +364,7 @@ State: 2 ** Python -#+BEGIN_SRC python :results output :exports both :wrap SRC hoa +#+BEGIN_SRC python import spot import buddy @@ -384,3 +386,22 @@ State: 2 print(aut.to_str('hoa')) #+END_SRC + +#+RESULTS: +#+begin_SRC hoa +HOA: v1 +States: 3 +Start: 0 +AP: 2 "p1" "p2" +Acceptance: 3 (Inf(0) & Fin(1)) | Fin(2) +properties: trans-labels explicit-labels trans-acc +--BODY-- +State: 0 +[0] 1 +State: 1 +[0&1] 1 {0} +[1] 2 {1} +State: 2 +[0 | 1] 1 {0 2} +--END-- +#+end_SRC diff --git a/doc/org/tut23.org b/doc/org/tut23.org index af38981e8..abfad8823 100644 --- a/doc/org/tut23.org +++ b/doc/org/tut23.org @@ -3,12 +3,15 @@ #+DESCRIPTION: Code example for constructing alternating ω-automata in Spot #+INCLUDE: setup.org #+HTML_LINK_UP: tut.html +#+PROPERTY: header-args:sh :results verbatim :exports both +#+PROPERTY: header-args:python :results output :exports both +#+PROPERTY: header-args:C+++ :results verbatim :exports both This example demonstrates how to create the following alternating co-Büchi automaton (recognizing =GFa=) and then print it. #+NAME: tut23-dot -#+BEGIN_SRC sh :results verbatim :exports none :var txt=tut23-cpp +#+BEGIN_SRC sh :exports none :var txt=tut23-cpp autfilt --dot < #include #include @@ -80,15 +83,15 @@ edges (declared with =new_edge()=) and universal edges (declared with #+END_SRC #+RESULTS: tut23-cpp -#+BEGIN_SRC hoa +#+begin_SRC hoa HOA: v1 States: 3 Start: 0 AP: 1 "a" acc-name: co-Buchi Acceptance: 1 Fin(0) -properties: univ-branch trans-labels explicit-labels trans-acc complete -properties: deterministic +properties: trans-labels explicit-labels trans-acc complete +properties: deterministic univ-branch --BODY-- State: 0 [0] 0 @@ -99,11 +102,11 @@ State: 1 State: 2 [t] 2 --END-- -#+END_SRC +#+end_SRC * Python -#+BEGIN_SRC python :results output :exports both :wrap SRC hoa +#+BEGIN_SRC python :wrap SRC hoa import spot import buddy diff --git a/doc/org/tut24.org b/doc/org/tut24.org index fd61617d2..4a3b1eaab 100644 --- a/doc/org/tut24.org +++ b/doc/org/tut24.org @@ -3,6 +3,8 @@ #+DESCRIPTION: Code example for iterating of alternating ω-automata in Spot #+INCLUDE: setup.org #+HTML_LINK_UP: tut.html +#+PROPERTY: header-args:python :results output :exports both +#+PROPERTY: header-args:C+++ :results verbatim :noweb strip-export Alternating automata can be explored in a very similar way as non-alternating automata. Most of the code from our [[file:tut21.org][custom automaton @@ -54,7 +56,7 @@ and that we run the following code, similar to what we did in the [[file:tut21.org][custom automaton printer]]. #+NAME: nonalt-body -#+BEGIN_SRC C++ +#+BEGIN_SRC C++ :export code std::cout << "Initial state: " << aut->get_init_state_number() << '\n'; const spot::bdd_dict_ptr& dict = aut->get_dict(); @@ -98,7 +100,7 @@ for (unsigned s = 0; s < n; ++s) #+END_SRC #+NAME: nonalt-one -#+BEGIN_SRC C++ :exports none :noweb strip-export :results verbatim +#+BEGIN_SRC C++ :exports none <> void custom_print(spot::twa_graph_ptr& aut) { @@ -136,7 +138,7 @@ unconditionally. In this example, we simply call =is_univ_dest()= to decide whether to enclose the destinations in braces. #+NAME: nonalt-body2 -#+BEGIN_SRC C++ +#+BEGIN_SRC C++ :export code unsigned init = aut->get_init_state_number(); std::cout << "Initial state:"; if (aut->is_univ_dest(init)) @@ -169,7 +171,7 @@ decide whether to enclose the destinations in braces. #+END_SRC #+NAME: nonalt-two -#+BEGIN_SRC C++ :exports none :noweb strip-export :results verbatim +#+BEGIN_SRC C++ :exports none <> void custom_print(spot::twa_graph_ptr& aut) { @@ -187,27 +189,27 @@ decide whether to enclose the destinations in braces. Here is the Python version of this code: -#+BEGIN_SRC python :results output :exports both - import spot +#+BEGIN_SRC python + import spot - aut = spot.automaton("tut24.hoa") + aut = spot.automaton("tut24.hoa") - bdict = aut.get_dict() - init = aut.get_init_state_number() - ui = aut.is_univ_dest(init) - print("Initial states: {}{}{}".format("{ " if ui else "", - " ".join(map(str, aut.univ_dests(init))), - " }" if ui else "")) - for s in range(0, aut.num_states()): - print("State {}:".format(s)) - for t in aut.out(s): - ud = aut.is_univ_dest(t) - print(" edge({} -> {}{}{})".format(t.src, - "{ " if ud else "", - " ".join(map(str, aut.univ_dests(t))), - " }" if ud else "")) - print(" label =", spot.bdd_format_formula(bdict, t.cond)) - print(" acc sets =", t.acc) + bdict = aut.get_dict() + init = aut.get_init_state_number() + ui = aut.is_univ_dest(init) + print("Initial states: {}{}{}".format("{ " if ui else "", + " ".join(map(str, aut.univ_dests(init))), + " }" if ui else "")) + for s in range(0, aut.num_states()): + print("State {}:".format(s)) + for t in aut.out(s): + ud = aut.is_univ_dest(t) + print(" edge({} -> {}{}{})".format(t.src, + "{ " if ud else "", + " ".join(map(str, aut.univ_dests(t))), + " }" if ud else "")) + print(" label =", spot.bdd_format_formula(bdict, t.cond)) + print(" acc sets =", t.acc) #+END_SRC #+RESULTS: diff --git a/doc/org/tut30.org b/doc/org/tut30.org index 026392e0a..5e3bf6e5d 100644 --- a/doc/org/tut30.org +++ b/doc/org/tut30.org @@ -3,17 +3,18 @@ #+DESCRIPTION: Code example for converting ω-automata in Spot #+INCLUDE: setup.org #+HTML_LINK_UP: tut.html +#+PROPERTY: header-args:sh :results verbatim :exports both +#+PROPERTY: header-args:python :results output :exports both +#+PROPERTY: header-args:C+++ :results verbatim :exports both Consider the following Rabin automaton, generated by =ltl2dstar=: -#+BEGIN_SRC sh :results silent :exports both +#+BEGIN_SRC sh :results silent ltldo ltl2dstar -f 'F(Xp1 xor XXp1)' > tut30.hoa #+END_SRC -#+RESULTS: - #+NAME: tut30in -#+BEGIN_SRC sh :results verbatim :exports none +#+BEGIN_SRC sh :exports none autfilt tut30.hoa --dot #+END_SRC @@ -39,11 +40,11 @@ not only be changed to Büchi, but simplification routines (useless SCCs removal, simulation-based reductions, acceptance sets simplifications, WDBA-minimization, ...) will also be applied. -#+BEGIN_SRC sh :results verbatim :exports both :wrap SRC hoa +#+BEGIN_SRC sh :wrap SRC hoa autfilt -B -D tut30.hoa #+END_SRC #+RESULTS: -#+BEGIN_SRC hoa +#+begin_SRC hoa HOA: v1 States: 5 Start: 1 @@ -51,7 +52,7 @@ AP: 1 "p1" acc-name: Buchi Acceptance: 1 Inf(0) properties: trans-labels explicit-labels state-acc complete -properties: deterministic weak +properties: deterministic very-weak --BODY-- State: 0 {0} [t] 0 @@ -67,40 +68,13 @@ State: 4 [!0] 0 [0] 4 --END-- -#+END_SRC +#+end_SRC #+NAME: tut30out -#+BEGIN_SRC sh :results verbatim :exports none +#+BEGIN_SRC sh :exports none autfilt -B -D -d tut30.hoa #+END_SRC -#+RESULTS: tut30out -#+begin_example -digraph G { - rankdir=LR - node [shape="circle"] - fontname="Lato" - node [fontname="Lato"] - edge [fontname="Lato"] - node[style=filled, fillcolor="#ffffa0"] edge[arrowhead=vee, arrowsize=.7] - I [label="", style=invis, width=0] - I -> 1 - 0 [label="0", peripheries=2] - 0 -> 0 [label=<1>] - 1 [label="1"] - 1 -> 2 [label=<1>] - 2 [label="2"] - 2 -> 3 [label=] - 2 -> 4 [label=] - 3 [label="3"] - 3 -> 0 [label=] - 3 -> 3 [label=] - 4 [label="4"] - 4 -> 0 [label=] - 4 -> 4 [label=] -} -#+end_example - #+BEGIN_SRC dot :file tut30out.svg :var txt=tut30out :exports results $txt #+END_SRC @@ -118,7 +92,7 @@ the result further. The Python version uses the =postprocess()= routine: -#+BEGIN_SRC python :results output :exports both :wrap SRC hoa +#+BEGIN_SRC python :wrap SRC hoa import spot aut = spot.automaton('tut30.hoa').postprocess('BA', 'deterministic') print(aut.to_str('hoa')) @@ -153,7 +127,7 @@ State: 4 The =postprocess()= function has an interface similar to [[file:tut10.org][the =translate()= function discussed previously]]: -#+BEGIN_SRC python :results output :exports both +#+BEGIN_SRC python import spot help(spot.postprocess) #+END_SRC @@ -162,7 +136,7 @@ help(spot.postprocess) #+begin_example Help on function postprocess in module spot: -postprocess(automaton, *args) +postprocess(automaton, *args, formula=None, xargs=None) Post process an automaton. This applies a number of simlification algorithms, depending on @@ -171,17 +145,29 @@ postprocess(automaton, *args) not already 'Deterministic'. The optional arguments should be strings among the following: - - at most one in 'Generic', 'TGBA', 'BA', or 'Monitor' - (type of automaton to build) + - at most one in 'Generic', 'TGBA', 'BA', or 'Monitor', + 'parity', 'parity min odd', 'parity min even', + 'parity max odd', 'parity max even' (type of automaton to + build), 'coBuchi' - at most one in 'Small', 'Deterministic', 'Any' (preferred characteristics of the produced automaton) - at most one in 'Low', 'Medium', 'High' (optimization level) - - any combination of 'Complete' and 'StateBasedAcceptance' - (or 'SBAcc' for short) + - any combination of 'Complete', 'StateBasedAcceptance' + (or 'SBAcc' for short), and 'Colored (only for parity + acceptance) The default corresponds to 'generic', 'small' and 'high'. + If a formula denoted by this automaton is known, pass it to as the + optional `formula` argument; it can help some algorithms by + providing an easy way to complement the automaton. + + Additional options can be supplied using a `spot.option_map`, or a + string (that will be converted to `spot.option_map`), as the `xargs` + argument. This is similar to the `-x` option of command-line tools; + so check out the spot-x(7) man page for details. + #+end_example @@ -192,7 +178,7 @@ The C++ version of this code is a bit more verbose, because the =postprocessor= object, configure it, and then call it for each automaton to process. -#+BEGIN_SRC C++ :results verbatim :exports both :wrap SRC hoa +#+BEGIN_SRC C++ :wrap SRC hoa #include #include #include @@ -219,7 +205,7 @@ automaton to process. #+END_SRC #+RESULTS: -#+BEGIN_SRC hoa +#+begin_SRC hoa HOA: v1 States: 5 Start: 1 @@ -227,7 +213,7 @@ AP: 1 "p1" acc-name: Buchi Acceptance: 1 Inf(0) properties: trans-labels explicit-labels state-acc complete -properties: deterministic weak +properties: deterministic very-weak --BODY-- State: 0 {0} [t] 0 @@ -243,8 +229,8 @@ State: 4 [!0] 0 [0] 4 --END-- -#+END_SRC +#+end_SRC -#+BEGIN_SRC sh :results silent :exports results +#+BEGIN_SRC sh :results silent rm -f tut30.hoa #+END_SRC diff --git a/doc/org/tut31.org b/doc/org/tut31.org index 28ffc0bf0..966e8770f 100644 --- a/doc/org/tut31.org +++ b/doc/org/tut31.org @@ -3,6 +3,9 @@ #+DESCRIPTION: Code example for removing alternation in Spot #+INCLUDE: setup.org #+HTML_LINK_UP: tut.html +#+PROPERTY: header-args:sh :results verbatim :exports both +#+PROPERTY: header-args:python :results output :exports both +#+PROPERTY: header-args:C+++ :results verbatim :exports both Consider the following alternating co-Büchi automaton (see [[file:tut23.org][how to create it]]): @@ -30,7 +33,7 @@ State: 2 #+END_SRC #+NAME: tut31dot -#+BEGIN_SRC sh :results verbatim :exports none :noweb strip-export +#+BEGIN_SRC sh :exports none :noweb strip-export cat >tut31.hoa <> EOF @@ -58,7 +61,7 @@ if the input is [[file:concepts.org::#property-flags][very-weak]]. We simply use =autfilt= with option =--tgba=: -#+BEGIN_SRC sh :results verbatim :exports both :wrap SRC hoa +#+BEGIN_SRC sh :wrap SRC hoa autfilt --tgba tut31.hoa #+END_SRC #+RESULTS: @@ -82,7 +85,7 @@ State: 1 #+END_SRC #+NAME: tut31out -#+BEGIN_SRC sh :results verbatim :exports none +#+BEGIN_SRC sh :exports none autfilt --tgba -d tut31.hoa #+END_SRC @@ -97,13 +100,13 @@ $txt In the Python version we call =remove_alternation()= -#+BEGIN_SRC python :results output :exports both :wrap SRC hoa +#+BEGIN_SRC python :wrap SRC hoa import spot aut = spot.remove_alternation(spot.automaton('tut31.hoa')) print(aut.to_str('hoa')) #+END_SRC #+RESULTS: -#+BEGIN_SRC hoa +#+begin_SRC hoa HOA: v1 States: 2 Start: 0 @@ -115,18 +118,18 @@ properties: deterministic --BODY-- State: 0 [0] 0 {0} -[!0] 1 {0} +[!0] 1 State: 1 [0] 0 {0} [!0] 1 --END-- -#+END_SRC +#+end_SRC * C++ The C++ version calls =remove_alternation()= too. -#+BEGIN_SRC C++ :results verbatim :exports both :wrap SRC hoa +#+BEGIN_SRC C++ :wrap SRC hoa #include #include #include @@ -149,7 +152,7 @@ The C++ version calls =remove_alternation()= too. #+END_SRC #+RESULTS: -#+BEGIN_SRC hoa +#+begin_SRC hoa HOA: v1 States: 2 Start: 0 @@ -161,13 +164,13 @@ properties: deterministic --BODY-- State: 0 [0] 0 {0} -[!0] 1 {0} +[!0] 1 State: 1 [0] 0 {0} [!0] 1 --END-- -#+END_SRC +#+end_SRC -#+BEGIN_SRC sh :results silent :exports results +#+BEGIN_SRC sh :results silent rm -f tut31.hoa #+END_SRC diff --git a/doc/org/tut50.org b/doc/org/tut50.org index ef5af56d8..41ee4f7e9 100644 --- a/doc/org/tut50.org +++ b/doc/org/tut50.org @@ -3,6 +3,7 @@ #+DESCRIPTION: Explanation of the explicit and on-the-fly automata interfaces in Spot #+INCLUDE: setup.org #+HTML_LINK_UP: tut.html +#+PROPERTY: header-args:C+++ :results verbatim :exports both When exploring automata (i.e., following its transition structure), @@ -164,7 +165,7 @@ just an index into the state vector of the underlying graph. From a state number =s=, it is possible to iterate over all successors by doing a =for= loop on =out(s)=, as in: -#+BEGIN_SRC C++ :results verbatim :exports both +#+BEGIN_SRC C++ #include #include #include @@ -188,9 +189,9 @@ by doing a =for= loop on =out(s)=, as in: #+END_SRC #+RESULTS: -: 2->0 -: 2->1 -: 2->2 +: 0->0 +: 0->1 +: 0->2 In the above lines, =aut->out(s)= delegates to =aut->get_graphs().out(s)= and returns a =state_out= @@ -198,7 +199,7 @@ instance, which is a small temporary object masquerading as an STL container with =begin()= and =end()= methods. The ranged-for loop syntax of C++ works exactly as if we had typed -#+BEGIN_SRC C++ +#+BEGIN_SRC C++ :exports code // You could write this, but why not let the compiler do it for you? // In any case, do not spell out the types of tmp and i, as those // should be considered internal details. @@ -221,7 +222,7 @@ because the compiler will optimize this away. In fact after operators are inlined and useless temporary variables removed, the above loop compiles to something equivalent to this: -#+BEGIN_SRC C++ +#+BEGIN_SRC C++ :exports code // You could also write this lower-level version, and that sometimes // helps (e.g., if you want to pause the loop and then resume it, as // we will do later). @@ -252,7 +253,7 @@ we call =dfs_rec()= from the initial state, that function updates a vector of visited states in order to not visit them twice, and recurse on all successors of the given state. -#+BEGIN_SRC C++ :results verbatim :exports both +#+BEGIN_SRC C++ #include #include #include @@ -301,7 +302,7 @@ on all successors of the given state. accessible transitions in a "DFS-ish" way, but without producing exactly the same output as above. - #+BEGIN_SRC C++ :results verbatim :exports both + #+BEGIN_SRC C++ #include #include #include @@ -379,7 +380,7 @@ to maintain a stack of edge numbers. Indeed, each edge stores the number of the next edge leaving the same source state, so this is enough to remember where we are. - #+BEGIN_SRC C++ :results verbatim :exports both + #+BEGIN_SRC C++ #include #include #include @@ -576,7 +577,7 @@ saving a =delete= and =new= pair. To summarize, here is a crude loop over the successors of the initial state: -#+BEGIN_SRC C++ :results verbatim :exports both +#+BEGIN_SRC C++ #include #include #include @@ -608,9 +609,9 @@ state: #+END_SRC #+RESULTS: -: 2->0 -: 2->1 -: 2->2 +: 0->0 +: 0->1 +: 0->2 Notice that a =twa_succ_iterator= allows iterating over outgoing edges, but only offers access to =dst()=, =acc()=, and =cond()= for @@ -628,7 +629,7 @@ However =first()= and =next()= also return a Boolean stating whether the loop could continue. This allows rewriting the above code as follows: -#+BEGIN_SRC C++ +#+BEGIN_SRC C++ :exports code void example(spot::const_twa_ptr aut) { const spot::state* s = aut->get_init_state(); @@ -653,7 +654,7 @@ so we halved to number of virtual calls. Using C++11's ranged =for= loop, this example can be reduced to the following equivalent code: -#+BEGIN_SRC C++ :results verbatim :exports both +#+BEGIN_SRC C++ #include #include #include @@ -683,9 +684,9 @@ following equivalent code: #+END_SRC #+RESULTS: -: 2->0 -: 2->1 -: 2->2 +: 0->0 +: 0->1 +: 0->2 This works in a similar way as =out(s)= in the explicit interface. Calling =aut->succ(s)= creates a fake container @@ -703,7 +704,7 @@ track of the states to =destroy()= them only after we do not need them anymore. This tracking can be done using the data structure we use to remember what states we have already seen. -#+BEGIN_SRC C++ :results verbatim :exports both +#+BEGIN_SRC C++ #include #include #include @@ -754,10 +755,10 @@ remember what states we have already seen. #+END_SRC #+RESULTS: -: 2->0 : 0->0 -: 2->1 +: 0->1 : 1->1 +: 0->2 : 2->2 ** Recursive DFS (v2) @@ -772,7 +773,7 @@ previously (in that case the passed state is destroyed). The With this class, the recursive code can be simplified down to this: -#+BEGIN_SRC C++ :results verbatim :exports both +#+BEGIN_SRC C++ #include #include #include @@ -809,10 +810,10 @@ With this class, the recursive code can be simplified down to this: #+END_SRC #+RESULTS: -: 2->0 : 0->0 -: 2->1 +: 0->1 : 1->1 +: 0->2 : 2->2 Note how this completely hides all the calls to =state::destroy()=. @@ -826,7 +827,7 @@ For a non-recursive version, let us use a stack of source, so we better store that in the stack as well if we want to print it. -#+BEGIN_SRC C++ :results verbatim :exports both +#+BEGIN_SRC C++ #include #include #include @@ -883,8 +884,8 @@ print it. #+END_SRC #+RESULTS: -: 2->0 : 0->0 -: 2->1 +: 0->1 : 1->1 +: 0->2 : 2->2 diff --git a/doc/org/upgrade2.org b/doc/org/upgrade2.org index 983239e94..49379ed23 100644 --- a/doc/org/upgrade2.org +++ b/doc/org/upgrade2.org @@ -114,7 +114,7 @@ experience of updating a couple of projects that are using Spot. If Spot 1.2.6 was installed in =/usr/local=, its headers are in =/usr/local/include/spot=. One would to write include statements such as -#+BEGIN_SRC c++ +#+BEGIN_SRC C++ #include #include #+END_SRC @@ -126,7 +126,7 @@ directory. If Spot 2.0 is installed in =/usr/local=, its headers are still in =/usr/local/include/spot= however the =spot/= directory is and should always be used to refer to the header: -#+BEGIN_SRC c++ +#+BEGIN_SRC C++ #include // the new name of tgba/tgba.hh #include // the new name of ltl/formula.hh #+END_SRC @@ -454,7 +454,7 @@ name: handle those larger acceptance conditions, or restricted to generalized Büchi acceptance. The typical way to ensure that an =input= automaton has generalized Büchi acceptance is -#+BEGIN_SRC c++ +#+BEGIN_SRC C++ if (!input->acc().is_generalized_buchi()) throw std::runtime_error ("myalgorithm() can only works with generalized Büchi acceptance"); @@ -600,7 +600,6 @@ for (auto i: aut->succ(s)) * Various renamings - :PROPERTIES: :CUSTOM_ID: renamings :END: @@ -611,7 +610,7 @@ for (auto i: aut->succ(s)) | old name | new name | comment | |-------------------------------------------------------------+---------------------------------------------+-----------------------------------------------------------| | ~dstar_parse()~ | ~parse_aut()~ | single parser for all automata | -| ~dtgba_complement()~ | ~dtwa_complement()~ | | +| ~dtgba_complement()~ | ~dualize()~ | | | ~dupexp_bfs()~ | | deleted | | ~dupexp_dfs()~ | ~make_twa_graph()~ | | | ~format_parse_aut_errors()~ | ~parsed_aut::format_errors()~ | |