spot/doc/org/ltldo.org
Alexandre Duret-Lutz 847270b480 ltlcross: replace %H,%T,%N by %O
Also get rid of the lbt_parser, and fix the LBT support of the HOA
parser.

* doc/org/ltlcross.org, doc/org/ltldo.org: Update.
* src/bin/common_trans.cc, src/bin/common_trans.hh: Add support for
%O, and keep %T,%N,%H as hidden aliases without disabling them.
* src/bin/ltlcross.cc, src/bin/ltldo.cc, src/tgbatest/ltl2tgba.cc:
Call hoa_parse instead of lbt_parse.
* src/hoaparse/hoaparse.yy: Improve error reporting from LBT.
* src/hoaparse/hoascan.ll: Fix typos preventing parsing of
LBT files with more than 10 states.
* src/tgbaalgos/lbtt.cc, src/tgbaalgos/lbtt.hh: Delete the lbt
parser.
* src/tgbatest/lbttparse.test: Adjust the expected error message.
* NEWS: Update.
2015-02-01 02:09:48 +01:00

462 lines
13 KiB
Org Mode

# -*- coding: utf-8 -*-
#+TITLE: =ltldo=
#+SETUPFILE: setup.org
#+HTML_LINK_UP: tools.html
This tool is a wrapper for tools that read LTL/PSL formulas and
(optionally) output automata.
It reads formulas specified using the [[file:ioltl.org][common options for specifying
input]] and passes each formula to a tool (or a list of tools) specified
using options similar to those of [[file:ltlcross.org][=ltlcross=]]. In case that tool
returns an automaton, the resulting automaton is read back by =ltldo=
and is finally output as specified using the [[file:oaut.org][common options for
outputing automata]].
In effect, =ltldo= wraps the I/O interface of the Spot tools on top of
any other tool.
* Example: computing statistics for =ltl3ba=
As a motivating example, consider a scenario where we want to run
[[http://sourceforge.net/projects/ltl3ba/][=ltl3ba=]] on a set of 10 formulas stored in a file. For each formula
we would like to compute compute the number of states and edges in the
Büchi automaton produced by =ltl3ba=.
Here is the input file:
#+BEGIN_SRC sh :results verbatim :exports code
cat >sample.ltl <<EOF
1
1 U a
!(!((a U Gb) U b) U GFa)
(b <-> Xc) xor Fb
FXb R (a R (1 U b))
Ga
G(!(c | (a & (a W Gb))) M Xa)
GF((b R !a) U (Xc M 1))
G(Xb | Gc)
XG!F(a xor Gb)
EOF
#+END_SRC
#+RESULTS:
We will first implement this scenario without =ltldo=.
A first problem that the input is not in the correct syntax: although
=ltl3ba= understands =G= and =F=, it does not support =xor= or =M=,
and requires the Boolean operators =||= and =&&=. This syntax
issue can be fixed by processing the input with [[file:ltlfilt.org][=ltlfilt -s=]].
A second problem is that =ltl3ba= (at least version 1.1.1) can only
process one formula at a time. So we'll need to call =ltl3ba= in a
loop.
Finally, one way to compute the size of the resulting Büchi automaton
is to pipe the output of =ltl3ba= through [[file:autfilt.org][=autfilt=]].
Here is how the shell command could look like:
#+BEGIN_SRC sh :results verbatim :exports both
ltlfilt -F sample.ltl -s |
while read f; do
ltl3ba -f "$f" | autfilt --stats="$f,%s,%t"
done
#+END_SRC
#+RESULTS:
#+begin_example
true,1,1
true U a,2,4
!(!((a U []b) U b) U []<>a),2,4
(((!b && !Xc) || (b && Xc)) && !<>b) || (<>b && !((!b && !Xc) || (b && Xc))),7,21
<>Xb V (a V (true U b)),6,28
[]a,1,1
[](Xa U (Xa && !(c || (a && ([]b V (a || []b)))))),1,0
[]<>((b V !a) U (true U Xc)),2,4
[](Xb || []c),3,11
X[]!<>((a && ![]b) || (!a && []b)),4,10
#+end_example
Using =ltldo= the above command can be reduced to this:
#+BEGIN_SRC sh :results verbatim :exports both
ltldo 'ltl3ba -f %s>%O' -F sample.ltl --stats='%f,%s,%t'
#+END_SRC
#+RESULTS:
#+begin_example
1,1,1
1 U a,2,4
!(!((a U Gb) U b) U GFa),2,4
(b <-> Xc) xor Fb,7,21
FXb R (a R (1 U b)),6,28
Ga,1,1
G(!(c | (a & (a W Gb))) M Xa),1,0
GF((b R !a) U (Xc M 1)),2,4
G(Xb | Gc),3,11
XG!F(a xor Gb),4,10
#+end_example
Note that the formulas look different in both cases, because in the
=while= loop the formula printed has already been processed with
=ltlfilt=, while =ltldo= emits the input string untouched.
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
ltldo ltl3ba -F sample.ltl --stats='%f,%s,%t'
#+END_SRC
#+RESULTS:
#+begin_example
1,1,1
1 U a,2,4
!(!((a U Gb) U b) U GFa),2,4
(b <-> Xc) xor Fb,7,21
FXb R (a R (1 U b)),6,28
Ga,1,1
G(!(c | (a & (a W Gb))) M Xa),1,0
GF((b R !a) U (Xc M 1)),2,4
G(Xb | Gc),3,11
XG!F(a xor Gb),4,10
#+end_example
* Example: running =spin= and producing HOA
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
ltldo -f a -f GFa 'spin -f %s>%O' -H
#+END_SRC
#+RESULTS:
#+begin_example
HOA: v1
States: 2
Start: 0
AP: 1 "a"
acc-name: Buchi
Acceptance: 1 Inf(0)
properties: trans-labels explicit-labels state-acc deterministic
--BODY--
State: 0 {0}
[0] 1
State: 1 {0}
[t] 1
--END--
HOA: v1
States: 2
Start: 0
AP: 1 "a"
acc-name: Buchi
Acceptance: 1 Inf(0)
properties: trans-labels explicit-labels state-acc complete
--BODY--
State: 0
[0] 1
[t] 0
State: 1 {0}
[t] 0
--END--
#+end_example
Again, using the shorthands defined below, the previous command can be
simplified to just this:
#+BEGIN_SRC sh :results verbatim :exports code
ltldo spin -f a -f GFa -H
#+END_SRC
* Syntax for specifying tools to call
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
ltldo --help | sed -n '/character sequences:/,/^$/p' | sed '1d;$d'
#+END_SRC
#+RESULTS:
: %f,%s,%l,%w the formula as a (quoted) string in Spot, Spin,
: LBT, or Wring's syntax
: %F,%S,%L,%W the formula as a file in Spot, Spin, LBT, or
: Wring's syntax
: %O,%D the automaton is output as either (%O) HOA/never
: claim/LBTT, or (%D) in LTL2DSTAR's format
Contrarily to =ltlcross=, it this not mandatory to specify an output
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
ltldo -f 'p0 U p1' -f 'GFp0' 'echo %f, %s, %l, %w'
#+END_SRC
#+RESULTS:
: (p0) U (p1), (p0) U (p1), U p0 p1, (p0=1) U (p1=1)
: (G(F(p0))), ([](<>(p0))), G F p0, (G(F(p0=1)))
In this case (i.e., when the command does not specify any output
filename), =ltldo= will not output anything.
As will =ltlcross=, multiple commands can be given, and they will be
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
ltldo -F sample.ltl 'spin -f %s>%O' 'ltl3ba -f %s>%O' --stats=%T,%f,%s,%e
#+END_SRC
#+RESULTS:
#+begin_example
spin -f %s>%O,1,2,2
ltl3ba -f %s>%O,1,1,1
spin -f %s>%O,1 U a,2,3
ltl3ba -f %s>%O,1 U a,2,3
spin -f %s>%O,!(!((a U Gb) U b) U GFa),23,86
ltl3ba -f %s>%O,!(!((a U Gb) U b) U GFa),2,3
spin -f %s>%O,(b <-> Xc) xor Fb,12,23
ltl3ba -f %s>%O,(b <-> Xc) xor Fb,7,11
spin -f %s>%O,FXb R (a R (1 U b)),28,176
ltl3ba -f %s>%O,FXb R (a R (1 U b)),6,20
spin -f %s>%O,Ga,1,1
ltl3ba -f %s>%O,Ga,1,1
spin -f %s>%O,G(!(c | (a & (a W Gb))) M Xa),15,51
ltl3ba -f %s>%O,G(!(c | (a & (a W Gb))) M Xa),1,0
spin -f %s>%O,GF((b R !a) U (Xc M 1)),12,60
ltl3ba -f %s>%O,GF((b R !a) U (Xc M 1)),2,4
spin -f %s>%O,G(Xb | Gc),4,8
ltl3ba -f %s>%O,G(Xb | Gc),3,5
spin -f %s>%O,XG!F(a xor Gb),8,21
ltl3ba -f %s>%O,XG!F(a xor Gb),4,7
#+end_example
Here we used =%T= to output the name of the tool used to translate the
formula =%f= as an automaton with =%s= states and =%e= edges.
If you feel that =%T= has too much clutter, you can give each tool
a shorter name by prefixing its command with ={name}=.
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
ltldo -F sample.ltl --stats=%T,%s,%e \
'echo "#" %f' '{spin}spin -f %s>%O' '{ltl3ba}ltl3ba -f %s>%O'
#+END_SRC
#+RESULTS:
#+begin_example
# (1)
spin,2,2
ltl3ba,1,1
# (1) U (a)
spin,2,3
ltl3ba,2,3
# (!((!(((a) U (G(b))) U (b))) U (G(F(a)))))
spin,23,86
ltl3ba,2,3
# ((b) <-> (X(c))) xor (F(b))
spin,12,23
ltl3ba,7,11
# (F(X(b))) R ((a) R ((1) U (b)))
spin,28,176
ltl3ba,6,20
# (G(a))
spin,1,1
ltl3ba,1,1
# (G((!((c) | ((a) & ((a) W (G(b)))))) M (X(a))))
spin,15,51
ltl3ba,1,0
# (G(F(((b) R (!(a))) U ((X(c)) M (1)))))
spin,12,60
ltl3ba,2,4
# (G((X(b)) | (G(c))))
spin,4,8
ltl3ba,3,5
# (X(G(!(F((a) xor (G(b)))))))
spin,8,21
ltl3ba,4,7
#+end_example
Much more readable!
* Shorthands for existing tools
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
ltldo --list-shorthands
#+END_SRC
#+RESULTS:
#+begin_example
If a COMMANDFMT does not use any %-sequence, and starts with one of
the following words, then the string on the right is appended.
lbt <%L>%O
ltl2ba -f %s>%O
ltl2dstar %L %D
ltl2tgba -H %f>%O
ltl3ba -f %s>%O
ltl3dra -f %f>%D
modella %L %O
spin -f %s>%O
#+end_example
So for instance you can type just
#+BEGIN_SRC sh :results verbatim :exports both
ltldo ltl2ba -f a
#+END_SRC
to obtain a Dot output (this is the default output format for =ltldo=)
for the neverclaim produced by =ltl2ba -f a=.
#+RESULTS:
: digraph G {
: rankdir=LR
: I [label="", style=invis, width=0]
: I -> 0
: 0 [label="0", peripheries=2]
: 0 -> 1 [label="a"]
: 1 [label="1", peripheries=2]
: 1 -> 1 [label="1"]
: }
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
string that does not use any =%= character. This makes it possible to
add options:
#+BEGIN_SRC sh :results verbatim :exports both
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
* Transparent renaming
Have you 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
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
: -------------^
All these tools are based on the same LTL parser, that allows
only atomic propositions starting with a lowercase letter.
Running the same command through =ltldo= will work:
#+BEGIN_SRC sh :results verbatim :exports both
ltldo spin -f '[]!Error' -s
#+END_SRC
#+RESULTS:
: never {
: accept_init:
: if
: :: ((!(Error))) -> goto accept_init
: fi;
: }
(We need the =-s= option to obtain a never claim, instead of the
default GraphViz output.)
What happened is that =ltldo= renamed the atomic propositions in the
formula before calling =spin=. So =spin= actually received the
formula =[]!p0=, produced a never claim using =p0=, and that never
claim was then relabeled by =ltldo= to use =Error= instead of =p0=.
This renaming occurs any time some command uses =%s= or =%S= and the
formula has atomic propositions incompatible with Spin's conventions;
or when some command uses =%l= or =%L=, and the formula has
atomic propositions incompatible with [[http://www.tcs.hut.fi/Software/maria/tools/lbt/][LBT's conventions]].
There are some cases where the renaming is not completely transparent.
For instance if a translator tool outputs some HOA file named after
the formula translated, the name will be output unmodified (since this
can be any text string, there is not way for =ltldo= to assume it is
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
ltldo 'ltl3ba -H' -f '[]!Error' -H
#+END_SRC
#+RESULTS:
#+begin_example
HOA: v1
name: "BA for ([](!(p0)))"
States: 1
Start: 0
AP: 1 "Error"
acc-name: Buchi
Acceptance: 1 Inf(0)
properties: trans-labels explicit-labels state-acc deterministic
--BODY--
State: 0 "accept_init" {0}
[!0] 0
--END--
#+end_example
If this is a problem, you can always force a new name with the
=--name= option:
#+BEGIN_SRC sh :results verbatim :exports both
ltldo 'ltl3ba -H' -f '[]!Error' -H --name='BA for %f'
#+END_SRC
#+RESULTS:
#+begin_example
HOA: v1
name: "BA for []!Error"
States: 1
Start: 0
AP: 1 "Error"
acc-name: Buchi
Acceptance: 1 Inf(0)
properties: trans-labels explicit-labels state-acc deterministic
--BODY--
State: 0 "accept_init" {0}
[!0] 0
--END--
#+end_example
* Controlling and measuring time
The run time of each command can be restricted with the =-T NUM=
option. The argument is the maximum number of seconds that each
command is allowed to run.
When a timeout occurs a warning is printed on stderr, and no automaton
(or statistic) is output by =ltdo= for this specific pair of
command/formula. The processing then continue with other formulas and
tools. Timeouts are not considered as errors, so they have no effect
on the exit status of =ltldo=.
For each command (that does not terminate with a timeout) the runtime
can be printed using the =%r= escape sequence. This makes =ltldo= an
alternative to [[file:ltlcross.org][=ltlcross=]] for running benchmarks without any
verification.