bin: add shorthands for ltlcross and ltldo
* src/bin/common_trans.cc: Implement shorthands. * doc/org/ltlcross.org, doc/org/ltldo.org: Document them. * src/tgbatest/ltldo2.test: Quick test. * NEWS: Mention it.
This commit is contained in:
parent
259c9faaae
commit
a24a021964
5 changed files with 217 additions and 27 deletions
6
NEWS
6
NEWS
|
|
@ -37,6 +37,12 @@ New in spot 1.99a (not yet released)
|
|||
now. The short '-n NUM' option is now the same as the new
|
||||
--max-count=N option, for consistency with other tools.
|
||||
|
||||
- ltlcross (and ltldo) have a list of hard-coded shorthands
|
||||
for some existing tools. So for instance running
|
||||
'ltlcross spin ...' is the same as running
|
||||
'ltlcross "spin -f %s>%N" ...'. This feature is much
|
||||
more useful for ltldo.
|
||||
|
||||
- There is a parser for the HOA format
|
||||
(http://adl.github.io/hoaf/) available as a
|
||||
spot::hoa_stream_parser object or spot::hoa_parse() function.
|
||||
|
|
|
|||
|
|
@ -149,6 +149,35 @@ tools:
|
|||
so we have to rename =%D.dst= as =%D= so that =ltlcross= can find the file)
|
||||
- '=ltl3dra -f %s >%D='
|
||||
|
||||
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
|
||||
ltlcross --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>%T
|
||||
ltl2ba -f %s>%N
|
||||
ltl2dstar %L %D
|
||||
ltl2tgba -H %f>%H
|
||||
ltl3ba -f %s>%N
|
||||
ltl3dra -f %f>%D
|
||||
modella %L %T
|
||||
spin -f %s>%N
|
||||
#+end_example
|
||||
|
||||
What this implies is that running =ltlcross ltl2ba ltl3ba ...= is
|
||||
the same as running =ltlcross 'ltl2ba -f %s>%N' 'ltl3ba -f %s>%N' ...=
|
||||
|
||||
Because only the prefix of the actual command is checked, you can
|
||||
still specify some options. For instance =ltlcross 'ltl2tgba -D' ...=
|
||||
is short for =ltlcross 'ltl2tgba -D -H %F>%H' ...=
|
||||
|
||||
* Getting statistics
|
||||
|
||||
Detailed statistics about the result of each translation, and the
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ X[]!<>((a && ![]b) || (!a && []b)),4,10
|
|||
Using =ltldo= the above command can be reduced to this:
|
||||
|
||||
#+BEGIN_SRC sh :results verbatim :exports both
|
||||
ltldo -F sample.ltl 'ltl3ba -f %s>%N' --stats='%f,%s,%t'
|
||||
ltldo 'ltl3ba -f %s>%N' -F sample.ltl --stats='%f,%s,%t'
|
||||
#+END_SRC
|
||||
#+RESULTS:
|
||||
#+begin_example
|
||||
|
|
@ -101,6 +101,27 @@ 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
|
||||
|
|
@ -142,6 +163,13 @@ State: 1 {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
|
||||
|
|
@ -159,9 +187,10 @@ ltldo --help | sed -n '/character sequences:/,/^$/p' | sed '1d;$d'
|
|||
: %N,%T,%D,%H the automaton is output as a Never claim, or in
|
||||
: LBTT's, in LTL2DSTAR's, or in the HOA format
|
||||
|
||||
Contrarily to =ltlcross=, it this not mandatory to specify an output filename
|
||||
using one of the sequence for that later lines. For instance we could
|
||||
simply run a formula though =echo= to compare different output syntaxes:
|
||||
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'
|
||||
|
|
@ -257,6 +286,66 @@ ltl3ba,4,7
|
|||
|
||||
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>%T
|
||||
ltl2ba -f %s>%N
|
||||
ltl2dstar %L %D
|
||||
ltl2tgba -H %f>%H
|
||||
ltl3ba -f %s>%N
|
||||
ltl3dra -f %f>%D
|
||||
modella %L %T
|
||||
spin -f %s>%N
|
||||
#+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>%N=.
|
||||
|
||||
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
|
||||
|
|
@ -281,7 +370,7 @@ only atomic propositions starting with a lowercase letter.
|
|||
Running the same command through =ltldo= will work:
|
||||
|
||||
#+BEGIN_SRC sh :results verbatim :exports both
|
||||
ltldo -t 'spin -f %s>%N' -f '[]!Error' -s
|
||||
ltldo spin -f '[]!Error' -s
|
||||
#+END_SRC
|
||||
#+RESULTS:
|
||||
: never {
|
||||
|
|
@ -291,6 +380,9 @@ ltldo -t 'spin -f %s>%N' -f '[]!Error' -s
|
|||
: 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
|
||||
|
|
@ -311,7 +403,7 @@ 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 %s>%H' -f '[]!Error' -H
|
||||
ltldo 'ltl3ba -H' -f '[]!Error' -H
|
||||
#+END_SRC
|
||||
#+RESULTS:
|
||||
#+begin_example
|
||||
|
|
@ -333,7 +425,7 @@ 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 %s>%H' -f '[]!Error' -H --name='BA for %f'
|
||||
ltldo 'ltl3ba -H' -f '[]!Error' -H --name='BA for %f'
|
||||
#+END_SRC
|
||||
|
||||
#+RESULTS:
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <sys/wait.h>
|
||||
#include <iomanip>
|
||||
|
||||
#include "error.h"
|
||||
|
||||
|
|
@ -31,12 +32,40 @@
|
|||
#include "ltlvisit/lbt.hh"
|
||||
#include "common_conv.hh"
|
||||
|
||||
// A set of tools for which we know the correct output
|
||||
static struct shorthands_t
|
||||
{
|
||||
const char* prefix;
|
||||
const char* suffix;
|
||||
}
|
||||
shorthands[] = {
|
||||
{ "lbt", " <%L>%T" },
|
||||
{ "ltl2ba", " -f %s>%N" },
|
||||
{ "ltl2dstar", " %L %D"},
|
||||
{ "ltl2tgba", " -H %f>%H" },
|
||||
{ "ltl3ba", " -f %s>%N" },
|
||||
{ "ltl3dra", " -f %f>%D" },
|
||||
{ "modella", " %L %T" },
|
||||
{ "spin", " -f %s>%N" },
|
||||
};
|
||||
|
||||
void show_shorthands()
|
||||
{
|
||||
std::cout
|
||||
<< ("If a COMMANDFMT does not use any %-sequence, and starts with one of\n"
|
||||
"the following words, then the string on the right is appended.\n\n");
|
||||
for (auto& s: shorthands)
|
||||
std::cout << " "
|
||||
<< std::left << std::setw(12) << s.prefix
|
||||
<< s.suffix << '\n';
|
||||
}
|
||||
|
||||
|
||||
translator_spec::translator_spec(const char* spec)
|
||||
: spec(spec), cmd(spec), name(spec)
|
||||
{
|
||||
if (*cmd != '{')
|
||||
return;
|
||||
|
||||
if (*cmd == '{')
|
||||
{
|
||||
// Match the closing '}'
|
||||
const char* pos = cmd;
|
||||
unsigned count = 1;
|
||||
|
|
@ -54,6 +83,30 @@ translator_spec::translator_spec(const char* spec)
|
|||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// If we recognize a shorthand, add the suffixes.
|
||||
bool allocated = false;
|
||||
if (!strchr(cmd, '%'))
|
||||
{
|
||||
for (auto& p: shorthands)
|
||||
{
|
||||
int n = strlen(p.prefix);
|
||||
if (strncmp(cmd, p.prefix, n) == 0 &&
|
||||
(cmd[n] == 0 || cmd[n] == ' '))
|
||||
{
|
||||
int m = strlen(p.suffix);
|
||||
int q = strlen(cmd);
|
||||
char* tmp = static_cast<char*>(malloc(q + m + 1));
|
||||
strcpy(tmp, cmd);
|
||||
strcpy(tmp + q, p.suffix);
|
||||
cmd = tmp;
|
||||
allocated = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!allocated)
|
||||
cmd = strdup(cmd);
|
||||
}
|
||||
|
||||
translator_spec::translator_spec(const translator_spec& other)
|
||||
|
|
@ -61,12 +114,16 @@ translator_spec::translator_spec(const translator_spec& other)
|
|||
{
|
||||
if (name != spec)
|
||||
name = strdup(name);
|
||||
if (cmd != spec)
|
||||
cmd = strdup(cmd);
|
||||
}
|
||||
|
||||
translator_spec::~translator_spec()
|
||||
{
|
||||
if (name != spec)
|
||||
free(const_cast<char*>(name));
|
||||
if (cmd != spec)
|
||||
free(const_cast<char*>(cmd));
|
||||
}
|
||||
|
||||
std::vector<translator_spec> translators;
|
||||
|
|
@ -326,6 +383,7 @@ exec_with_timeout(const char* cmd)
|
|||
return status;
|
||||
}
|
||||
|
||||
#define OPT_LIST 1
|
||||
static const argp_option options[] =
|
||||
{
|
||||
/**************************************************/
|
||||
|
|
@ -333,6 +391,8 @@ static const argp_option options[] =
|
|||
{ "translator", 't', "COMMANDFMT", 0,
|
||||
"register one translator to call", 0 },
|
||||
{ "timeout", 'T', "NUMBER", 0, "kill translators after NUMBER seconds", 0 },
|
||||
{ "list-shorthands", OPT_LIST, 0 , 0,
|
||||
"list availabled shorthands to use in COMMANDFMT", 0},
|
||||
/**************************************************/
|
||||
{ 0, 0, 0, 0,
|
||||
"COMMANDFMT should specify input and output arguments using the "
|
||||
|
|
@ -369,6 +429,9 @@ static int parse_opt_trans(int key, char* arg, struct argp_state*)
|
|||
<< "on your platform" << std::endl;
|
||||
#endif
|
||||
break;
|
||||
case OPT_LIST:
|
||||
show_shorthands();
|
||||
exit(0);
|
||||
default:
|
||||
return ARGP_ERR_UNKNOWN;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,5 +27,5 @@ genltl=../../bin/genltl
|
|||
test -n "$LTL2BA" || exit 77
|
||||
|
||||
$genltl --or-g=1..2 |
|
||||
run 0 $ltldo '{ltl2ba}ltl2ba -f %s>%H' >output
|
||||
test 2 = `grep -c digraph output`
|
||||
run 0 $ltldo 'ltl2ba -f %s>%H' '{foo}ltl2ba' >output
|
||||
test 4 = `grep -c digraph output`
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue