parseaut: support multiple dstar automata

* src/parseaut/parseaut.yy, src/parseaut/scanaut.ll: All multiple
dstar automata to be chained.
* src/bin/dstar2tgba.cc: Loop over multiple automata in a file.
* src/tests/dstar.test: Test that.
This commit is contained in:
Alexandre Duret-Lutz 2015-09-07 22:27:07 +02:00
parent 209e89a94c
commit c59e994a2c
4 changed files with 98 additions and 28 deletions

View file

@ -46,11 +46,11 @@
#include "twaalgos/sccinfo.hh" #include "twaalgos/sccinfo.hh"
static const char argp_program_doc[] ="\ static const char argp_program_doc[] ="\
Convert Rabin and Streett automata into Büchi automata.\n\n\ Convert automata with any acceptance condition into variants of \
This reads the output format of ltl2dstar and will output a\n\ Büchi automata.\n\nThis reads automata into any supported format \
Transition-based Generalized Büchi Automata in GraphViz's format by default.\n\ (HOA, LBTT, ltl2dstar, never claim) and outputs a \
If multiple files are supplied (one automaton per file), several automata\n\ Transition-based Generalized Büchi Automata in GraphViz's format by default. \
will be output."; Each supplied file may contain multiple automata.";
enum { enum {
OPT_TGBA = 1, OPT_TGBA = 1,
@ -143,26 +143,53 @@ namespace
SPOT_UNREACHABLE(); SPOT_UNREACHABLE();
} }
int
process_automaton(const spot::const_parsed_aut_ptr& haut,
const char* filename)
{
spot::stopwatch sw;
sw.start();
auto nba = spot::to_generalized_buchi(haut->aut);
auto aut = post.run(nba, 0);
const double conversion_time = sw.stop();
printer.print(aut, nullptr, filename, -1, conversion_time, haut);
flush_cout();
return 0;
}
int
aborted(const spot::const_parsed_aut_ptr& h, const char* filename)
{
std::cerr << filename << ':' << h->loc << ": aborted input automaton\n";
return 2;
}
int int
process_file(const char* filename) process_file(const char* filename)
{ {
spot::parse_aut_error_list pel; spot::parse_aut_error_list pel;
auto daut = spot::parse_aut(filename, pel, spot::make_bdd_dict()); auto hp = spot::automaton_stream_parser(filename);
int err = 0;
while (!abort_run)
{
pel.clear();
auto haut = hp.parse(pel, spot::make_bdd_dict());
if (!haut && pel.empty())
break;
if (spot::format_parse_aut_errors(std::cerr, filename, pel)) if (spot::format_parse_aut_errors(std::cerr, filename, pel))
return 2; err = 2;
if (!daut) if (!haut)
error(2, 0, "failed to read automaton from %s", filename); error(2, 0, "failed to read automaton from %s", filename);
else if (haut->aborted)
err = std::max(err, aborted(haut, filename));
else
process_automaton(haut, filename);
}
spot::stopwatch sw; return err;
sw.start();
auto nba = spot::to_generalized_buchi(daut->aut);
auto aut = post.run(nba, 0);
const double conversion_time = sw.stop();
printer.print(aut, nullptr, filename, -1, conversion_time, daut);
flush_cout();
return 0;
} }
}; };
} }

View file

@ -228,6 +228,7 @@
/**** LBTT tokens *****/ /**** LBTT tokens *****/
// Also using INT, STRING // Also using INT, STRING
%token ENDAUT "-1" %token ENDAUT "-1"
%token ENDDSTAR "end of DSTAR automaton"
%token <num> LBTT "LBTT header" %token <num> LBTT "LBTT header"
%token <num> INT_S "state acceptance" %token <num> INT_S "state acceptance"
%token <num> LBTT_EMPTY "acceptance sets for empty automaton" %token <num> LBTT_EMPTY "acceptance sets for empty automaton"
@ -264,7 +265,7 @@ aut: aut-1 { res.h->loc = @$; YYACCEPT; }
aut-1: hoa { res.h->type = spot::parsed_aut_type::HOA; } aut-1: hoa { res.h->type = spot::parsed_aut_type::HOA; }
| never { res.h->type = spot::parsed_aut_type::NeverClaim; } | never { res.h->type = spot::parsed_aut_type::NeverClaim; }
| lbtt { res.h->type = spot::parsed_aut_type::LBTT; } | lbtt { res.h->type = spot::parsed_aut_type::LBTT; }
| dstar /* we will set type as DSA or DRA while parsing first line */ | dstar /* will set type as DSA or DRA while parsing first line */
/**********************************************************************/ /**********************************************************************/
/* Rules for HOA */ /* Rules for HOA */
@ -1101,7 +1102,7 @@ incorrectly-labeled-edge: trans-label unlabeled-edge
/* Rules for LTL2DSTAR's format */ /* Rules for LTL2DSTAR's format */
/**********************************************************************/ /**********************************************************************/
dstar: dstar_header "---" dstar_states dstar: dstar_header "---" dstar_states ENDDSTAR
dstar_type: "DRA" dstar_type: "DRA"
{ {

View file

@ -43,6 +43,7 @@ static unsigned lbtt_states = 0;
eol \n+|\r+ eol \n+|\r+
eol2 (\n\r)+|(\r\n)+ eol2 (\n\r)+|(\r\n)+
eols ({eol}|{eol2})*
identifier [[:alpha:]_][[:alnum:]_-]* identifier [[:alpha:]_][[:alnum:]_-]*
%x in_COMMENT in_STRING in_NEVER_PAR %x in_COMMENT in_STRING in_NEVER_PAR
@ -150,6 +151,14 @@ identifier [[:alpha:]_][[:alnum:]_-]*
"Acc-Sig:" return token::ACCSIG; "Acc-Sig:" return token::ACCSIG;
"---" return token::ENDOFHEADER; "---" return token::ENDOFHEADER;
[0-9]+ parse_int(); return token::INT; [0-9]+ parse_int(); return token::INT;
/* The start of any automaton is the end of this one.
We do not try to detect LBTT automata, as that would
be too hard to distinguish from state numbers. */
""/{eols}("HOA:"|"never"|"DSA"|"DRA") {
BEGIN(INITIAL);
return token::ENDDSTAR;
}
<<EOF>> return token::ENDDSTAR;
} }
<in_NEVER>{ <in_NEVER>{
@ -185,7 +194,7 @@ identifier [[:alpha:]_][[:alnum:]_-]*
If we only tokenize it as a stream of INTs, the parser will have If we only tokenize it as a stream of INTs, the parser will have
a very hard time recognizing what is a state from what is a a very hard time recognizing what is a state from what is a
transitions. As a consequence we abuse the start conditions to transitions. As a consequence we abuse the start conditions to
maintain a state an return integers with different sementic types maintain a state an return integers with different semantic types
depending on the purpose of those integers. */ depending on the purpose of those integers. */
<in_LBTT_HEADER>{ <in_LBTT_HEADER>{
[0-9]+[st]* { [0-9]+[st]* {

View file

@ -154,7 +154,7 @@ test "`../../bin/dstar2tgba -DC dsa.dstar --stats '%s %t %p %d'`" = "5 11 1 0"
# DRA generated with # DRA generated with
# ltlfilt -f 'Ga | Fb' -l | ltl2dstar --ltl2nba=spin:path/ltl2tgba@-sD - - # ltlfilt -f 'Ga | Fb' -l | ltl2dstar --ltl2nba=spin:path/ltl2tgba@-Ds - -
# (State name and comments added by hand to test the parser.) # (State name and comments added by hand to test the parser.)
cat >dra.dstar <<EOF cat >dra.dstar <<EOF
DRA v2 explicit DRA v2 explicit
@ -198,9 +198,21 @@ Acc-Sig: +0 +1
4 4
3 3
4 4
/* Same automaton with DSA instead of DRA, no comments, and less \n */
DSA v2 explicit
States: 5
Acceptance-Pairs: 2
Start: 0
AP: 2 "a" "b"
---
State: 0 "bla" Acc-Sig: 1 2 3 4
State: 1 "foo" Acc-Sig: -0 1 1 3 3
State: 2 "baz" Acc-Sig: +0 1 2 3 4
State: 3 "str\n\"ing" Acc-Sig: -0 +1 3 3 3 3
State: 4 "more\"string\"" Acc-Sig: +0 +1 3 4 3 4
EOF EOF
run 0 ../ikwiad -XDB dra.dstar | tee stdout run 0 ../../bin/autfilt -B dra.dstar | tee stdout
cat >expected <<EOF cat >expected <<EOF
digraph G { digraph G {
@ -227,12 +239,33 @@ digraph G {
4 -> 3 [label="!a"] 4 -> 3 [label="!a"]
4 -> 4 [label="a"] 4 -> 4 [label="a"]
} }
digraph G {
rankdir=LR
node [shape="circle"]
I [label="", style=invis, width=0]
I -> 0
0 [label="0"]
0 -> 1 [label="!a & !b"]
0 -> 2 [label="a & !b"]
1 [label="1", peripheries=2]
1 -> 1 [label="!b"]
2 [label="2"]
2 -> 1 [label="!a & !b"]
2 -> 2 [label="a & !b"]
}
EOF EOF
diff expected stdout diff expected stdout
test "`../../bin/dstar2tgba --name=%F -D dra.dstar --stats '%s %t %p %d %m'`" \ cat >expected <<EOF
= "3 12 1 1 dra.dstar" 3 12 1 1 dra.dstar:1.1-42.70
2 4 0 1 dra.dstar:43.1-54.1
EOF
../../bin/dstar2tgba --name=%F:%L -D dra.dstar --stats '%s %t %p %d %m' > out
cat out
diff expected out
# This has caused a crash at some point when dealing with 0-sized # This has caused a crash at some point when dealing with 0-sized
# bitsets to represent acceptance sets. # bitsets to represent acceptance sets.