This implement several new options for --dot in order to allow emptiness sets to be output as colored ⓿ or ❶... Also add a SPOT_DOTDEFAULT environment variable. * NEWS, src/bin/man/spot-x.x, src/bin/common_aoutput.cc, src/bin/dstar2tgba.cc: Document the new options. * doc/org/.dir-locals.el, doc/org/init.el.in: Setup SPOT_DOTEXTRA and SPOT_DOTDEFAULT for all documents. * doc/org/autfilt.org, doc/org/dstar2tgba.org, doc/org/ltl2tgba.org, doc/org/ltldo.org, doc/org/oaut.org, doc/org/randaut.org, doc/org/satmin.org: Adjust to this new setup. * src/misc/escape.cc, src/misc/escape.hh (escape_html): New function. * src/tgba/acc.cc, src/tgba/acc.hh (to_text, to_html): New method. * src/tgbaalgos/dotty.cc: Implement the new options. * src/tgbatest/readsave.test, wrap/python/tests/automata.ipynb: More tests. * wrap/python/spot.py: Make sure the default argument for dotty_reachable is None, so that SPOT_DOTDEFAULT is honored.
687 lines
22 KiB
Org Mode
687 lines
22 KiB
Org Mode
# -*- coding: utf-8 -*-
|
|
#+TITLE: =ltl2tgba=
|
|
#+SETUPFILE: setup.org
|
|
#+HTML_LINK_UP: tools.html
|
|
|
|
This tool translates LTL or PSL formulas into two kinds of Büchi
|
|
automata, or to monitors. The default is to output Transition-based
|
|
Generalized Büchi Automata (hereinafter abbreviated TGBA), but more
|
|
traditional Büchi automata (BA) may be requested using the =-B=
|
|
option.
|
|
|
|
* TGBA and BA
|
|
|
|
Formulas to translate may be specified using [[file:ioltl.org][common input options for
|
|
LTL/PSL formulas]].
|
|
|
|
#+BEGIN_SRC sh :results verbatim :exports code
|
|
ltl2tgba -f 'Fa & GFb'
|
|
#+END_SRC
|
|
#+BEGIN_SRC sh :results verbatim :exports results
|
|
SPOT_DOTEXTRA= ltl2tgba -f 'Fa & GFb' --dot=
|
|
#+END_SRC
|
|
#+RESULTS:
|
|
#+begin_example
|
|
digraph G {
|
|
rankdir=LR
|
|
I [label="", style=invis, width=0]
|
|
I -> 1
|
|
0 [label="0"]
|
|
0 -> 0 [label="b\n{0}"]
|
|
0 -> 0 [label="!b"]
|
|
1 [label="1"]
|
|
1 -> 0 [label="a"]
|
|
1 -> 1 [label="!a"]
|
|
}
|
|
#+end_example
|
|
|
|
Actually, because =ltl2tgba= is often used with a single formula
|
|
passed on the command line, the =-f= option can be omitted and any
|
|
command-line parameter that is not the argument of some option will be
|
|
assumed to be a formula to translate (this differs from [[file:ltlfilt.org][=ltlfilt=]],
|
|
where such parameters are assumed to be filenames).
|
|
|
|
=ltl2tgba= honors the [[file:aout.org][common options for selecting the output format]].
|
|
The default output format, as shown above, is [[http://http://www.graphviz.org/][GraphViz]]'s format. This
|
|
can converted into a picture, or into vectorial format using =dot= or
|
|
=dotty=. Typically, you could get a =pdf= of this TGBA using
|
|
#+BEGIN_SRC sh :results verbatim :exports code
|
|
ltl2tgba "Fa & GFb" | dot -Tpdf > tgba.pdf
|
|
#+END_SRC
|
|
#+RESULTS:
|
|
|
|
The result would look like this (note that in this documentation
|
|
we use some [[file:aout.org][environement variables]] to produce a more colorful
|
|
output by default)
|
|
#+NAME: dotex
|
|
#+BEGIN_SRC sh :results verbatim :exports none
|
|
ltl2tgba "Fa & GFb"
|
|
#+END_SRC
|
|
#+RESULTS: dotex
|
|
#+begin_example
|
|
digraph G {
|
|
rankdir=LR
|
|
fontname="Lato"
|
|
node [fontname="Lato"]
|
|
edge [fontname="Lato"]
|
|
node[style=filled, fillcolor="#ffffa0"]
|
|
I [label="", style=invis, width=0]
|
|
I -> 1
|
|
0 [label="0"]
|
|
0 -> 0 [label=<b<br/><font color="#5DA5DA">⓿</font>>]
|
|
0 -> 0 [label=<!b>]
|
|
1 [label="1"]
|
|
1 -> 0 [label=<a>]
|
|
1 -> 1 [label=<!a>]
|
|
}
|
|
#+end_example
|
|
|
|
#+BEGIN_SRC dot :file dotex.png :cmdline -Tpng :var txt=dotex :exports results
|
|
$txt
|
|
#+END_SRC
|
|
|
|
#+RESULTS:
|
|
[[file:dotex.png]]
|
|
|
|
Characters like ⓿, ❶, etc. denotes the acceptance sets a transition
|
|
belongs to. In this case, there is only one acceptance set, called
|
|
=0=, containing a single transition. You may have many transitions in
|
|
the same acceptance set, and a transition may also belong to multiple
|
|
acceptance sets. An infinite path through this automaton is accepting
|
|
iff it visit each acceptance set infinitely often. Therefore, in the
|
|
above example, any accepted path will /necessarily/ leave the initial
|
|
state after a finite amount of steps, and then it will verify the
|
|
property =b= infinitely often. It is also possible that an automaton
|
|
do not use any acceptance set at all, in which any run is accepting.
|
|
|
|
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
|
|
ltl2tgba "GFa & GFb"
|
|
#+END_SRC
|
|
#+RESULTS: dotex2
|
|
#+begin_example
|
|
digraph G {
|
|
rankdir=LR
|
|
fontname="Lato"
|
|
node [fontname="Lato"]
|
|
edge [fontname="Lato"]
|
|
node[style=filled, fillcolor="#ffffa0"]
|
|
I [label="", style=invis, width=0]
|
|
I -> 0
|
|
0 [label="0"]
|
|
0 -> 0 [label=<a & b<br/><font color="#5DA5DA">⓿</font><font color="#F17CB0">❶</font>>]
|
|
0 -> 0 [label=<!a & !b>]
|
|
0 -> 0 [label=<!a & b<br/><font color="#F17CB0">❶</font>>]
|
|
0 -> 0 [label=<a & !b<br/><font color="#5DA5DA">⓿</font>>]
|
|
}
|
|
#+end_example
|
|
|
|
#+BEGIN_SRC dot :file dotex2.png :cmdline -Tpng :var txt=dotex2 :exports results
|
|
$txt
|
|
#+END_SRC
|
|
#+RESULTS:
|
|
[[file:dotex2.png]]
|
|
|
|
The above TGBA has two acceptance sets: ⓿ and ❶. The position of
|
|
these acceptance sets ensures that atomic propositions =a= and =b= must
|
|
be true infinitely often.
|
|
|
|
A Büchi automaton for the previous formula can be obtained with the
|
|
=-B= option:
|
|
|
|
#+NAME: dotex2ba
|
|
#+BEGIN_SRC sh :results verbatim :exports code
|
|
ltl2tgba -B 'GFa & GFb'
|
|
#+END_SRC
|
|
#+RESULTS: dotex2ba
|
|
#+begin_example
|
|
digraph G {
|
|
rankdir=LR
|
|
fontname="Lato"
|
|
node [fontname="Lato"]
|
|
edge [fontname="Lato"]
|
|
node[style=filled, fillcolor="#ffffa0"]
|
|
I [label="", style=invis, width=0]
|
|
I -> 0
|
|
0 [label="0", peripheries=2]
|
|
0 -> 0 [label=<a & b>]
|
|
0 -> 1 [label=<!b>]
|
|
0 -> 2 [label=<!a & b>]
|
|
1 [label="1"]
|
|
1 -> 0 [label=<a & b>]
|
|
1 -> 1 [label=<!b>]
|
|
1 -> 2 [label=<!a & b>]
|
|
2 [label="2"]
|
|
2 -> 0 [label=<a>]
|
|
2 -> 2 [label=<!a>]
|
|
}
|
|
#+end_example
|
|
|
|
#+BEGIN_SRC dot :file dotex2ba.png :cmdline -Tpng :var txt=dotex2ba :exports results
|
|
$txt
|
|
#+END_SRC
|
|
#+RESULTS:
|
|
[[file:dotex2ba.png]]
|
|
|
|
Although accepting states in the Büchi automaton are pictured with
|
|
double-lines, internally this automaton is still handled as a TGBA
|
|
with a single acceptance set such that the transitions
|
|
leaving the state are either all accepting, or all non-accepting.
|
|
You can see this underlying TGBA if you pass the =--dot=t= option
|
|
(the =t= requests the use of transition-based acceptance at it
|
|
is done internally):
|
|
|
|
#+BEGIN_SRC sh :results verbatim :exports code
|
|
ltl2tgba --dot=t -B 'GFa & GFb'
|
|
#+END_SRC
|
|
|
|
#+NAME: dotex2ba-t
|
|
#+BEGIN_SRC sh :results verbatim :exports none
|
|
ltl2tgba --dot=.t -B 'GFa & GFb'
|
|
#+END_SRC
|
|
|
|
#+RESULTS: dotex2ba-t
|
|
#+begin_example
|
|
digraph G {
|
|
rankdir=LR
|
|
fontname="Lato"
|
|
node [fontname="Lato"]
|
|
edge [fontname="Lato"]
|
|
node[style=filled, fillcolor="#ffffa0"]
|
|
I [label="", style=invis, width=0]
|
|
I -> 0
|
|
0 [label="0"]
|
|
0 -> 0 [label=<a & b<br/><font color="#5DA5DA">⓿</font>>]
|
|
0 -> 1 [label=<!b<br/><font color="#5DA5DA">⓿</font>>]
|
|
0 -> 2 [label=<!a & b<br/><font color="#5DA5DA">⓿</font>>]
|
|
1 [label="1"]
|
|
1 -> 0 [label=<a & b>]
|
|
1 -> 1 [label=<!b>]
|
|
1 -> 2 [label=<!a & b>]
|
|
2 [label="2"]
|
|
2 -> 0 [label=<a>]
|
|
2 -> 2 [label=<!a>]
|
|
}
|
|
#+end_example
|
|
|
|
#+BEGIN_SRC dot :file dotex2ba-t.png :cmdline -Tpng :var txt=dotex2ba-t :exports results
|
|
$txt
|
|
#+END_SRC
|
|
#+RESULTS:
|
|
[[file:dotex2ba-t.png]]
|
|
|
|
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
|
|
ltl2tgba --help | sed -n '/Output format:/,/^$/p' | sed '1d;$d'
|
|
#+END_SRC
|
|
#+RESULTS:
|
|
#+begin_example
|
|
-8, --utf8 enable UTF-8 characters in output (ignored with
|
|
--lbtt or --spin)
|
|
--dot[=a|b|c|f(FONT)|h|n|N|r|R|s|t|v]
|
|
GraphViz's format (default). Add letters for (a)
|
|
acceptance display, (b) acceptance sets as
|
|
bullets,(c) circular nodes, (f(FONT)) use FONT,
|
|
(h) horizontal layout, (v) vertical layout, (n)
|
|
with name, (N) without name, (r) rainbow colors
|
|
for acceptance set, (R) color acceptance set by
|
|
Inf/Fin, (s) with SCCs, (t) force transition-based
|
|
acceptance.
|
|
-H, --hoaf[=i|s|t|m|l] Output the automaton in HOA format. Add letters
|
|
to select (i) use implicit labels for complete
|
|
deterministic automata, (s) prefer state-based
|
|
acceptance when possible [default], (t) force
|
|
transition-based acceptance, (m) mix state and
|
|
transition-based acceptance, (l) single-line
|
|
output
|
|
--lbtt[=t] LBTT's format (add =t to force transition-based
|
|
acceptance even on Büchi automata)
|
|
--name=FORMAT set the name of the output automaton
|
|
-o, --output=FORMAT send output to a file named FORMAT instead of
|
|
standard output. The first automaton sent to a
|
|
file truncates it unless FORMAT starts with '>>'.
|
|
-q, --quiet suppress all normal output
|
|
-s, --spin[=6|c] Spin neverclaim (implies --ba). Add letters to
|
|
select (6) Spin's 6.2.4 style, (c) comments on
|
|
states
|
|
--stats=FORMAT output statistics about the automaton
|
|
#+end_example
|
|
|
|
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
|
|
ltl2tgba -B8 "GFa & GFb"
|
|
#+END_SRC
|
|
#+RESULTS: dotex2ba8
|
|
#+begin_example
|
|
digraph G {
|
|
rankdir=LR
|
|
fontname="Lato"
|
|
node [fontname="Lato"]
|
|
edge [fontname="Lato"]
|
|
node[style=filled, fillcolor="#ffffa0"]
|
|
I [label="", style=invis, width=0]
|
|
I -> 0
|
|
0 [label="0", peripheries=2]
|
|
0 -> 0 [label=<a∧b>]
|
|
0 -> 1 [label=<b̅>]
|
|
0 -> 2 [label=<a̅∧b>]
|
|
1 [label="1"]
|
|
1 -> 0 [label=<a∧b>]
|
|
1 -> 1 [label=<b̅>]
|
|
1 -> 2 [label=<a̅∧b>]
|
|
2 [label="2"]
|
|
2 -> 0 [label=<a>]
|
|
2 -> 2 [label=<a̅>]
|
|
}
|
|
#+end_example
|
|
|
|
#+BEGIN_SRC dot :file dotex2ba8.png :cmdline -Tpng :var txt=dotex2ba8 :exports results
|
|
$txt
|
|
#+END_SRC
|
|
#+RESULTS:
|
|
[[file:dotex2ba8.png]]
|
|
|
|
* Spin output
|
|
|
|
Using the =--spin= or =-s= option, =ltl2tgba= will produce a Büchi automaton
|
|
(the =-B= option is implied) as a never claim that can be fed to Spin.
|
|
=ltl2tgba -s= is therefore a drop-in replacement for =spin -f=.
|
|
|
|
|
|
#+BEGIN_SRC sh :results verbatim :exports both
|
|
ltl2tgba -s 'GFa & GFb'
|
|
#+END_SRC
|
|
#+RESULTS:
|
|
#+begin_example
|
|
never { /* G(Fa & Fb) */
|
|
accept_init:
|
|
if
|
|
:: ((a) && (b)) -> goto accept_init
|
|
:: ((!(b))) -> goto T0_S2
|
|
:: ((!(a)) && (b)) -> goto T0_S3
|
|
fi;
|
|
T0_S2:
|
|
if
|
|
:: ((a) && (b)) -> goto accept_init
|
|
:: ((!(b))) -> goto T0_S2
|
|
:: ((!(a)) && (b)) -> goto T0_S3
|
|
fi;
|
|
T0_S3:
|
|
if
|
|
:: ((a)) -> goto accept_init
|
|
:: ((!(a))) -> goto T0_S3
|
|
fi;
|
|
}
|
|
#+end_example
|
|
|
|
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
|
|
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
|
|
: :: ((a < b) && (!(process[2]@ok))) -> goto T0_init
|
|
: fi;
|
|
: accept_all:
|
|
: skip
|
|
: }
|
|
|
|
|
|
* Do you favor deterministic or small automata?
|
|
|
|
The translation procedure can be controled by a few switches. A first
|
|
set of options specifies the intent of the translation: whenever
|
|
possible, would you prefer a small automaton or a deterministic
|
|
automaton?
|
|
|
|
#+BEGIN_SRC sh :results verbatim :exports results
|
|
ltl2tgba --help | sed -n '/Translation intent:/,/^$/p' | sed '1d;$d'
|
|
#+END_SRC
|
|
#+RESULTS:
|
|
: -a, --any no preference
|
|
: -C, --complete output a complete automaton (combine with other
|
|
: intents)
|
|
: -D, --deterministic prefer deterministic automata
|
|
: --small prefer small automata (default)
|
|
|
|
The =--any= option tells the translator that it should not target any
|
|
particular form of result: any automaton denoting the given formula is
|
|
OK. This effectively disables post-processings and speeds up the
|
|
translation.
|
|
|
|
With the =-D= option, the translator will /attempt/ to produce a
|
|
deterministic automaton, even if this requires a lot of states. =ltl2tgba=
|
|
knows how to produce the minimal deterministic Büchi automaton for
|
|
any obligation property (this includes safety properties).
|
|
|
|
With the =--small= option (the default), the translator will not
|
|
produce a deterministic automaton when it knows how to build smaller
|
|
automaton.
|
|
|
|
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
|
|
ltl2tgba "Ga|Gb|Gc"
|
|
#+END_SRC
|
|
#+RESULTS: gagbgc1
|
|
#+begin_example
|
|
digraph G {
|
|
rankdir=LR
|
|
fontname="Lato"
|
|
node [fontname="Lato"]
|
|
edge [fontname="Lato"]
|
|
node[style=filled, fillcolor="#ffffa0"]
|
|
I [label="", style=invis, width=0]
|
|
I -> 0
|
|
0 [label="0"]
|
|
0 -> 1 [label=<a>]
|
|
0 -> 2 [label=<b>]
|
|
0 -> 3 [label=<c>]
|
|
1 [label="1"]
|
|
1 -> 1 [label=<a>]
|
|
2 [label="2"]
|
|
2 -> 2 [label=<b>]
|
|
3 [label="3"]
|
|
3 -> 3 [label=<c>]
|
|
}
|
|
#+end_example
|
|
|
|
#+BEGIN_SRC dot :file gagbgc1.png :cmdline -Tpng :var txt=gagbgc1 :exports results
|
|
$txt
|
|
#+END_SRC
|
|
#+RESULTS:
|
|
[[file:gagbgc1.png]]
|
|
|
|
#+NAME: gagbgc2
|
|
#+BEGIN_SRC sh :results verbatim :exports code
|
|
ltl2tgba -D 'Ga|Gb|Gc'
|
|
#+END_SRC
|
|
#+RESULTS: gagbgc2
|
|
#+begin_example
|
|
digraph G {
|
|
rankdir=LR
|
|
fontname="Lato"
|
|
node [fontname="Lato"]
|
|
edge [fontname="Lato"]
|
|
node[style=filled, fillcolor="#ffffa0"]
|
|
I [label="", style=invis, width=0]
|
|
I -> 6
|
|
0 [label="0", peripheries=2]
|
|
0 -> 0 [label=<c>]
|
|
1 [label="1", peripheries=2]
|
|
1 -> 0 [label=<!b & c>]
|
|
1 -> 1 [label=<b & c>]
|
|
1 -> 2 [label=<b & !c>]
|
|
2 [label="2", peripheries=2]
|
|
2 -> 2 [label=<b>]
|
|
3 [label="3", peripheries=2]
|
|
3 -> 2 [label=<!a & b>]
|
|
3 -> 3 [label=<a & b>]
|
|
3 -> 5 [label=<a & !b>]
|
|
4 [label="4", peripheries=2]
|
|
4 -> 0 [label=<!a & c>]
|
|
4 -> 4 [label=<a & c>]
|
|
4 -> 5 [label=<a & !c>]
|
|
5 [label="5", peripheries=2]
|
|
5 -> 5 [label=<a>]
|
|
6 [label="6", peripheries=2]
|
|
6 -> 0 [label=<!a & !b & c>]
|
|
6 -> 1 [label=<!a & b & c>]
|
|
6 -> 2 [label=<!a & b & !c>]
|
|
6 -> 3 [label=<a & b & !c>]
|
|
6 -> 4 [label=<a & !b & c>]
|
|
6 -> 5 [label=<a & !b & !c>]
|
|
6 -> 6 [label=<a & b & c>]
|
|
}
|
|
#+end_example
|
|
|
|
#+BEGIN_SRC dot :file gagbgc2.png :cmdline -Tpng :var txt=gagbgc2 :exports results
|
|
$txt
|
|
#+END_SRC
|
|
#+RESULTS:
|
|
[[file:gagbgc2.png]]
|
|
|
|
You can augment the number of terms in the disjunction to magnify the
|
|
difference. For N terms, the =--small= automaton has N+1 states,
|
|
while the =--deterministic= automaton needs 2^N-1 states.
|
|
|
|
Add the =--complete= option if you want to obtain a complete
|
|
automaton, with a sink state capturing that rejected words that would
|
|
not otherwise have a run in the output automaton.
|
|
|
|
|
|
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
|
|
ltl2tgba --help | sed -n '/Optimization level:/,/^$/p' | sed '1d;$d'
|
|
#+END_SRC
|
|
#+RESULTS:
|
|
: --high all available optimizations (slow, default)
|
|
: --low minimal optimizations (fast)
|
|
: --medium moderate optimizations
|
|
|
|
Pre-processings are rewritings done on the LTL formulas, usually to
|
|
reduce its size, but mainly to put it in a form that will help the
|
|
translator (for instance =F(a|b)= is easier to translate than
|
|
=F(a)|F(b)=). At =--low= level, only simple syntactic rewritings are
|
|
performed. At =--medium= level, additional simplifications based on
|
|
syntactic implications are performed. At =--high= level, language
|
|
containment is used instead of syntactic implications.
|
|
|
|
Post-processings are cleanups and simplifications of the automaton
|
|
produced by the core translator. The algorithms used during post-processing
|
|
are
|
|
- SCC filtering: removing useless strongly connected components,
|
|
and useless acceptance sets.
|
|
- direct simulation: merge states based on suffix inclusion.
|
|
- iterated simulations: merge states based on suffix inclusion,
|
|
or prefix inclusion, in a loop.
|
|
- WDBA minimization: determinize and minimize automata representing
|
|
obligation properties.
|
|
- degeneralization: convert a TGBA into a BA
|
|
|
|
The chaining of these various algorithms depends on the selected
|
|
combination of optimization level (=--low=, =--medium=, =--high=),
|
|
translation intent (=--small=, =--deterministic=) and type of
|
|
automaton desired (=--tgba=, =--ba=).
|
|
|
|
A notable configuration is =--any --low=, which will produce a TGBA as
|
|
fast as possible. In this case, post-processing is disabled, and only
|
|
syntactic rewritings are performed. This can be used for
|
|
satisfiability checking, although in this context even building an
|
|
automaton is overkill (you only need an accepted run).
|
|
|
|
Finally, it should be noted that the default optimization options
|
|
(=--small --high=) are usually overkill. =--low= will produce good
|
|
automata most of the time. Most of pattern formulas of [[file:genltl.org][=genltl=]] will
|
|
be efficiently translated in this configuration (meaning that =--small
|
|
--high= will not produce a better automaton). If you are planning to
|
|
generate automata for large family of pattern formulas, it makes sense
|
|
to experiment with the different settings on a small version of the
|
|
pattern, and select the lowest setting that satisfies your
|
|
expectations.
|
|
|
|
* Translating multiple formulas for statistics
|
|
|
|
If multiple formulas are given to =ltl2tgba=, the corresponding
|
|
automata will be output one after the other. This is not very
|
|
convenient, since most of these output formats are not designed to
|
|
represent multiple automata, and tools like =dot= will only display
|
|
the first one.
|
|
|
|
One situation where passing many formulas to =ltl2tgba= is useful is
|
|
in combination with the =--stats=FORMAT= option. This option will
|
|
output statistics about the translated automata instead of the
|
|
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
|
|
ltl2tgba --help | sed -n '/^ *%/p'
|
|
#+END_SRC
|
|
#+RESULTS:
|
|
#+begin_example
|
|
%% a single %
|
|
%a number of acceptance sets
|
|
%c number of SCCs
|
|
%d 1 if the output is deterministic, 0 otherwise
|
|
%e number of edges
|
|
%f the formula, in Spot's syntax
|
|
%F name of the input file
|
|
%L location in the input file
|
|
%m name of the automaton
|
|
%n number of nondeterministic states in output
|
|
%p 1 if the output is complete, 0 otherwise
|
|
%r processing time (excluding parsing) in seconds
|
|
%s number of states
|
|
%t number of transitions
|
|
%w one word accepted by the output automaton
|
|
#+end_example
|
|
|
|
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
|
|
genltl --u-right=1..8 | ltl2tgba -F - --stats '%s states and %e edges for "%f"'
|
|
#+END_SRC
|
|
#+RESULTS:
|
|
: 2 states and 2 edges for "p1"
|
|
: 2 states and 3 edges for "p1 U p2"
|
|
: 3 states and 6 edges for "p1 U (p2 U p3)"
|
|
: 4 states and 10 edges for "p1 U (p2 U (p3 U p4))"
|
|
: 5 states and 15 edges for "p1 U (p2 U (p3 U (p4 U p5)))"
|
|
: 6 states and 21 edges for "p1 U (p2 U (p3 U (p4 U (p5 U p6))))"
|
|
: 7 states and 28 edges for "p1 U (p2 U (p3 U (p4 U (p5 U (p6 U p7)))))"
|
|
: 8 states and 36 edges for "p1 U (p2 U (p3 U (p4 U (p5 U (p6 U (p7 U p8))))))"
|
|
|
|
Here =-F -= means that formulas should be read from the standard input.
|
|
|
|
When computing the size of an automaton, we distinguish /transitions/
|
|
and /edges/. An edge between two states is labeled by a Boolean
|
|
formula and may in fact represent several transitions labeled by
|
|
compatible Boolean assignment.
|
|
|
|
For instance if the atomic propositions are =x= and =y=, an edge labeled
|
|
by the formula =!x= actually represents two transitions labeled respectively
|
|
with =!x&y= and =!x&!y=.
|
|
|
|
Two automata with the same structures (states and edges) but differing
|
|
labels, may have a different count of transitions, e.g., if one has
|
|
more restricted labels.
|
|
|
|
[[file:csv.org][More examples of how to use =--stats= to create CSV
|
|
files are on a separate page]].
|
|
|
|
* Building Monitors
|
|
|
|
In addition to TGBA and BA, =ltl2tgba= can output /monitor/ using the
|
|
=-M= option. These are finite automata that accept all prefixes of a
|
|
formula. The idea is that you can use these automata to monitor a
|
|
system as it is running, and report a violation as soon as no
|
|
compatible outgoing transition exist.
|
|
|
|
=ltl2tgba -M= may output non-deterministic monitors while =ltl2tgba
|
|
-MD= (short for =--monitor --deterministic=) will output the minimal
|
|
deterministic monitor for the given formula.
|
|
|
|
#+NAME: monitor1
|
|
#+BEGIN_SRC sh :results verbatim :exports code
|
|
ltl2tgba -M '(Xa & Fb) | Gc'
|
|
#+END_SRC
|
|
|
|
#+RESULTS: monitor1
|
|
#+begin_example
|
|
digraph G {
|
|
rankdir=LR
|
|
fontname="Lato"
|
|
node [fontname="Lato"]
|
|
edge [fontname="Lato"]
|
|
node[style=filled, fillcolor="#ffffa0"]
|
|
I [label="", style=invis, width=0]
|
|
I -> 0
|
|
0 [label="0"]
|
|
0 -> 1 [label=<1>]
|
|
0 -> 3 [label=<c>]
|
|
1 [label="1"]
|
|
1 -> 2 [label=<a>]
|
|
2 [label="2"]
|
|
2 -> 2 [label=<1>]
|
|
3 [label="3"]
|
|
3 -> 3 [label=<c>]
|
|
}
|
|
#+end_example
|
|
|
|
#+BEGIN_SRC dot :file monitor1.png :cmdline -Tpng :var txt=monitor1 :exports results
|
|
$txt
|
|
#+END_SRC
|
|
|
|
#+RESULTS:
|
|
[[file:monitor1.png]]
|
|
|
|
#+NAME: monitor2
|
|
#+BEGIN_SRC sh :results verbatim :exports code
|
|
ltl2tgba -MD '(Xa & Fb) | Gc'
|
|
#+END_SRC
|
|
|
|
#+RESULTS: monitor2
|
|
#+begin_example
|
|
digraph G {
|
|
rankdir=LR
|
|
fontname="Lato"
|
|
node [fontname="Lato"]
|
|
edge [fontname="Lato"]
|
|
node[style=filled, fillcolor="#ffffa0"]
|
|
I [label="", style=invis, width=0]
|
|
I -> 3
|
|
0 [label="0"]
|
|
0 -> 0 [label=<1>]
|
|
1 [label="1"]
|
|
1 -> 0 [label=<a>]
|
|
2 [label="2"]
|
|
2 -> 2 [label=<c>]
|
|
3 [label="3"]
|
|
3 -> 1 [label=<!c>]
|
|
3 -> 4 [label=<c>]
|
|
4 [label="4"]
|
|
4 -> 0 [label=<a>]
|
|
4 -> 2 [label=<!a & c>]
|
|
}
|
|
#+end_example
|
|
|
|
#+BEGIN_SRC dot :file monitor2.png :cmdline -Tpng :var txt=monitor2 :exports results
|
|
$txt
|
|
#+END_SRC
|
|
|
|
#+RESULTS:
|
|
[[file:monitor2.png]]
|
|
|
|
Because they accept all finite executions that could be extended to
|
|
match the formula, monitor cannot be used to check for eventualities
|
|
such as =F(a)=: indeed, any finite execution can be extended to match
|
|
=F(a)=.
|
|
|
|
# LocalWords: ltl tgba num toc PSL Büchi automata SRC GFb invis Acc
|
|
# LocalWords: ltlfilt filenames GraphViz vectorial pdf Tpdf dotex
|
|
# LocalWords: sed png cmdline Tpng txt iff GFa ba utf UTF lbtt Fb
|
|
# LocalWords: GraphViz's LBTT's neverclaim SPOT's init goto fi Gb
|
|
# LocalWords: controled Gc gagbgc disjunction pre rewritings SCC Xa
|
|
# LocalWords: WDBA determinize degeneralization satisfiability SCCs
|
|
# LocalWords: genltl nondeterministic eval setenv concat getenv
|
|
# LocalWords: setq
|