ltlcross: add support for alternating automata
* bin/ltlcross.cc: Add an alternation-removal pass, and adjust CSV output. * doc/org/ltlcross.org: Update. * tests/core/ltl3dra.test, tests/core/ltl3ba.test: Add more tests. * tests/Makefile.am: Add tests/core/ltl3ba.test. * NEWS: Mention it.
This commit is contained in:
parent
543e0db9a0
commit
87c9d6f039
6 changed files with 205 additions and 51 deletions
5
NEWS
5
NEWS
|
|
@ -1,5 +1,10 @@
|
||||||
New in spot 2.2.2.dev (Not yet released)
|
New in spot 2.2.2.dev (Not yet released)
|
||||||
|
|
||||||
|
Tools:
|
||||||
|
|
||||||
|
* ltlcross supports translators that output weak alternating
|
||||||
|
automata in the HOA format (not necessarily *very* weak).
|
||||||
|
|
||||||
Library:
|
Library:
|
||||||
|
|
||||||
* A twa is required to have at least one state, the initial state.
|
* A twa is required to have at least one state, the initial state.
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,7 @@
|
||||||
#include <spot/twaalgos/word.hh>
|
#include <spot/twaalgos/word.hh>
|
||||||
#include <spot/twaalgos/complement.hh>
|
#include <spot/twaalgos/complement.hh>
|
||||||
#include <spot/twaalgos/cleanacc.hh>
|
#include <spot/twaalgos/cleanacc.hh>
|
||||||
|
#include <spot/twaalgos/alternation.hh>
|
||||||
#include <spot/misc/formater.hh>
|
#include <spot/misc/formater.hh>
|
||||||
#include <spot/twaalgos/stats.hh>
|
#include <spot/twaalgos/stats.hh>
|
||||||
#include <spot/twaalgos/isdet.hh>
|
#include <spot/twaalgos/isdet.hh>
|
||||||
|
|
@ -146,9 +147,10 @@ static const argp_option options[] =
|
||||||
"store automata (in the HOA format) into the CSV or JSON output", 0 },
|
"store automata (in the HOA format) into the CSV or JSON output", 0 },
|
||||||
{ "strength", OPT_STRENGTH, nullptr, 0,
|
{ "strength", OPT_STRENGTH, nullptr, 0,
|
||||||
"output statistics about SCC strengths (non-accepting, terminal, weak, "
|
"output statistics about SCC strengths (non-accepting, terminal, weak, "
|
||||||
"strong)", 0 },
|
"strong) [not supported for alternating automata]", 0 },
|
||||||
{ "ambiguous", OPT_AMBIGUOUS, nullptr, 0,
|
{ "ambiguous", OPT_AMBIGUOUS, nullptr, 0,
|
||||||
"output statistics about ambiguous automata", 0 },
|
"output statistics about ambiguous automata "
|
||||||
|
"[not supported for alternating automata]", 0 },
|
||||||
{ "unambiguous", 0, nullptr, OPTION_ALIAS, nullptr, 0 },
|
{ "unambiguous", 0, nullptr, OPTION_ALIAS, nullptr, 0 },
|
||||||
/**************************************************/
|
/**************************************************/
|
||||||
{ nullptr, 0, nullptr, 0, "Miscellaneous options:", -2 },
|
{ nullptr, 0, nullptr, 0, "Miscellaneous options:", -2 },
|
||||||
|
|
@ -257,6 +259,7 @@ struct statistics
|
||||||
{
|
{
|
||||||
statistics()
|
statistics()
|
||||||
: ok(false),
|
: ok(false),
|
||||||
|
alternating(false),
|
||||||
status_str(nullptr),
|
status_str(nullptr),
|
||||||
status_code(0),
|
status_code(0),
|
||||||
time(0),
|
time(0),
|
||||||
|
|
@ -280,6 +283,7 @@ struct statistics
|
||||||
// If OK is false, only the status_str, status_code, and time fields
|
// If OK is false, only the status_str, status_code, and time fields
|
||||||
// should be valid.
|
// should be valid.
|
||||||
bool ok;
|
bool ok;
|
||||||
|
bool alternating;
|
||||||
const char* status_str;
|
const char* status_str;
|
||||||
int status_code;
|
int status_code;
|
||||||
double time;
|
double time;
|
||||||
|
|
@ -351,18 +355,33 @@ struct statistics
|
||||||
<< acc << ','
|
<< acc << ','
|
||||||
<< scc << ',';
|
<< scc << ',';
|
||||||
if (opt_strength)
|
if (opt_strength)
|
||||||
|
{
|
||||||
|
if (alternating)
|
||||||
|
os << ",,,,";
|
||||||
|
else
|
||||||
os << nonacc_scc << ','
|
os << nonacc_scc << ','
|
||||||
<< terminal_scc << ','
|
<< terminal_scc << ','
|
||||||
<< weak_scc << ','
|
<< weak_scc << ','
|
||||||
<< strong_scc << ',';
|
<< strong_scc << ',';
|
||||||
|
}
|
||||||
os << nondetstates << ','
|
os << nondetstates << ','
|
||||||
<< nondeterministic << ',';
|
<< nondeterministic << ',';
|
||||||
if (opt_strength)
|
if (opt_strength)
|
||||||
|
{
|
||||||
|
if (alternating)
|
||||||
|
os << ",,,";
|
||||||
|
else
|
||||||
os << terminal_aut << ','
|
os << terminal_aut << ','
|
||||||
<< weak_aut << ','
|
<< weak_aut << ','
|
||||||
<< strong_aut << ',';
|
<< strong_aut << ',';
|
||||||
|
}
|
||||||
if (opt_ambiguous)
|
if (opt_ambiguous)
|
||||||
|
{
|
||||||
|
if (alternating)
|
||||||
|
os << ',';
|
||||||
|
else
|
||||||
os << ambiguous << ',';
|
os << ambiguous << ',';
|
||||||
|
}
|
||||||
os << complete;
|
os << complete;
|
||||||
if (!products_avg)
|
if (!products_avg)
|
||||||
{
|
{
|
||||||
|
|
@ -627,6 +646,7 @@ namespace
|
||||||
if (verbose)
|
if (verbose)
|
||||||
std::cerr << "info: getting statistics\n";
|
std::cerr << "info: getting statistics\n";
|
||||||
st->ok = true;
|
st->ok = true;
|
||||||
|
st->alternating = res->is_alternating();
|
||||||
spot::twa_sub_statistics s = sub_stats_reachable(res);
|
spot::twa_sub_statistics s = sub_stats_reachable(res);
|
||||||
st->states = s.states;
|
st->states = s.states;
|
||||||
st->edges = s.edges;
|
st->edges = s.edges;
|
||||||
|
|
@ -637,7 +657,7 @@ namespace
|
||||||
st->scc = c;
|
st->scc = c;
|
||||||
st->nondetstates = spot::count_nondet_states(res);
|
st->nondetstates = spot::count_nondet_states(res);
|
||||||
st->nondeterministic = st->nondetstates != 0;
|
st->nondeterministic = st->nondetstates != 0;
|
||||||
if (opt_strength)
|
if (opt_strength && !st->alternating)
|
||||||
{
|
{
|
||||||
m.determine_unknown_acceptance();
|
m.determine_unknown_acceptance();
|
||||||
for (unsigned n = 0; n < c; ++n)
|
for (unsigned n = 0; n < c; ++n)
|
||||||
|
|
@ -658,7 +678,7 @@ namespace
|
||||||
else
|
else
|
||||||
st->terminal_aut = true;
|
st->terminal_aut = true;
|
||||||
}
|
}
|
||||||
if (opt_ambiguous)
|
if (opt_ambiguous && !st->alternating)
|
||||||
st->ambiguous = !spot::is_unambiguous(res);
|
st->ambiguous = !spot::is_unambiguous(res);
|
||||||
st->complete = spot::is_complete(res);
|
st->complete = spot::is_complete(res);
|
||||||
|
|
||||||
|
|
@ -1037,11 +1057,6 @@ namespace
|
||||||
bool prob;
|
bool prob;
|
||||||
pos[n] = runner.translate(n, 'P', pstats, prob);
|
pos[n] = runner.translate(n, 'P', pstats, prob);
|
||||||
problems += prob;
|
problems += prob;
|
||||||
|
|
||||||
// If the automaton is deterministic, compute its complement
|
|
||||||
// as well.
|
|
||||||
if (!no_complement && pos[n] && is_deterministic(pos[n]))
|
|
||||||
comp_pos[n] = dtwa_complement(pos[n]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------- Negative Formula ----------
|
// ---------- Negative Formula ----------
|
||||||
|
|
@ -1073,11 +1088,6 @@ namespace
|
||||||
bool prob;
|
bool prob;
|
||||||
neg[n] = runner.translate(n, 'N', nstats, prob);
|
neg[n] = runner.translate(n, 'N', nstats, prob);
|
||||||
problems += prob;
|
problems += prob;
|
||||||
|
|
||||||
// If the automaton is deterministic, compute its
|
|
||||||
// complement as well.
|
|
||||||
if (!no_complement && neg[n] && is_deterministic(neg[n]))
|
|
||||||
comp_neg[n] = dtwa_complement(neg[n]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1102,6 +1112,8 @@ namespace
|
||||||
std::cerr << "info: " << prefix << i << "\t(";
|
std::cerr << "info: " << prefix << i << "\t(";
|
||||||
printsize(x[i]);
|
printsize(x[i]);
|
||||||
std::cerr << ')';
|
std::cerr << ')';
|
||||||
|
if (x[i]->is_alternating())
|
||||||
|
std::cerr << " univ-edges";
|
||||||
if (is_deterministic(x[i]))
|
if (is_deterministic(x[i]))
|
||||||
std::cerr << " deterministic";
|
std::cerr << " deterministic";
|
||||||
if (is_complete(x[i]))
|
if (is_complete(x[i]))
|
||||||
|
|
@ -1120,9 +1132,51 @@ namespace
|
||||||
std::cerr << "Performing sanity checks and gathering statistics..."
|
std::cerr << "Performing sanity checks and gathering statistics..."
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
|
||||||
|
bool print_first = verbose;
|
||||||
|
auto unalt = [&](std::vector<spot::twa_graph_ptr>& x,
|
||||||
|
unsigned i, char prefix)
|
||||||
|
{
|
||||||
|
if (!(x[i] && x[i]->is_alternating()))
|
||||||
|
return;
|
||||||
|
if (verbose)
|
||||||
|
{
|
||||||
|
if (print_first)
|
||||||
|
{
|
||||||
|
std::cerr <<
|
||||||
|
"info: getting rid of universal edges...\n";
|
||||||
|
print_first = false;
|
||||||
|
}
|
||||||
|
std::cerr << "info: " << prefix << i << "\t(";
|
||||||
|
printsize(x[i]);
|
||||||
|
std::cerr << ") ->";
|
||||||
|
}
|
||||||
|
x[i] = remove_alternation(x[i]);
|
||||||
|
if (verbose)
|
||||||
|
{
|
||||||
|
std::cerr << " (";
|
||||||
|
printsize(x[i]);
|
||||||
|
std::cerr << ")\n";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
auto complement = [&](const std::vector<spot::twa_graph_ptr>& x,
|
||||||
|
std::vector<spot::twa_graph_ptr>& comp,
|
||||||
|
unsigned i)
|
||||||
|
{
|
||||||
|
if (!no_complement && x[i] && is_deterministic(x[i]))
|
||||||
|
comp[i] = dtwa_complement(x[i]);
|
||||||
|
};
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < m; ++i)
|
||||||
|
{
|
||||||
|
unalt(pos, i, 'P');
|
||||||
|
complement(pos, comp_pos, i);
|
||||||
|
unalt(neg, i, 'N');
|
||||||
|
complement(neg, comp_neg, i);
|
||||||
|
}
|
||||||
|
|
||||||
if (determinize && !no_complement)
|
if (determinize && !no_complement)
|
||||||
{
|
{
|
||||||
bool print_first = verbose;
|
print_first = verbose;
|
||||||
auto tmp = [&](std::vector<spot::twa_graph_ptr>& from,
|
auto tmp = [&](std::vector<spot::twa_graph_ptr>& from,
|
||||||
std::vector<spot::twa_graph_ptr>& to, unsigned i,
|
std::vector<spot::twa_graph_ptr>& to, unsigned i,
|
||||||
char prefix)
|
char prefix)
|
||||||
|
|
@ -1157,7 +1211,7 @@ namespace
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool print_first = verbose;
|
print_first = verbose;
|
||||||
auto tmp = [&](std::vector<spot::twa_graph_ptr>& x, unsigned i,
|
auto tmp = [&](std::vector<spot::twa_graph_ptr>& x, unsigned i,
|
||||||
const char* prefix, const char* suffix)
|
const char* prefix, const char* suffix)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -9,19 +9,22 @@ translators. It is actually a Spot-based clone of [[http://www.tcs.hut.fi/Softw
|
||||||
/LTL-to-Büchi Translator Testbench/, that essentially performs the
|
/LTL-to-Büchi Translator Testbench/, that essentially performs the
|
||||||
same sanity checks.
|
same sanity checks.
|
||||||
|
|
||||||
The main differences are:
|
The main differences with LBTT are:
|
||||||
- support for PSL formulas in addition to LTL
|
- *support for PSL formulas in addition to LTL*
|
||||||
- more statistics, especially:
|
- support for (non-alternating) automata with *any type of acceptance condition*,
|
||||||
|
- support for *weak alternating automata*,
|
||||||
|
- additional intersection *checks with the complement*, allowing
|
||||||
|
to check equivalence of automata more precisely,
|
||||||
|
- *more statistics*, especially:
|
||||||
- the number of logical transitions represented by each physical edge,
|
- the number of logical transitions represented by each physical edge,
|
||||||
- the number of deterministic states and automata
|
- the number of deterministic states and automata
|
||||||
- the number of SCCs with their various strengths (nonaccepting, terminal, weak, strong)
|
- the number of SCCs with their various strengths (nonaccepting, terminal, weak, strong)
|
||||||
- the number of terminal, weak, and strong automata
|
- the number of terminal, weak, and strong automata
|
||||||
- statistics output in a format that can be more easily be post-processed,
|
- an option to *reduce counterexample* by attempting to mutate and
|
||||||
- more precise time measurement (LBTT was only precise to
|
shorten troublesome formulas,
|
||||||
1/100 of a second, reporting most times as "0.00s"),
|
- statistics output in *CSV* for easier post-processing,
|
||||||
- support for any type of acceptance condition,
|
- *more precise time measurement* (LBTT was only precise to
|
||||||
- additional intersection checks with the complement, allowing
|
1/100 of a second, reporting most times as "0.00s").
|
||||||
to check equivalence of automata more precisely.
|
|
||||||
|
|
||||||
Although =ltlcross= performs the same sanity checks as LBTT, it does
|
Although =ltlcross= performs the same sanity checks as LBTT, it does
|
||||||
not implement any of the interactive features of LBTT. In our almost
|
not implement any of the interactive features of LBTT. In our almost
|
||||||
|
|
@ -120,6 +123,7 @@ be rewritten using the other supported operators.
|
||||||
--lbtt=.
|
--lbtt=.
|
||||||
- Non-alternating automata in [[file:http://adl.github.io/hoaf/][the HOA format]] with any acceptance
|
- Non-alternating automata in [[file:http://adl.github.io/hoaf/][the HOA format]] with any acceptance
|
||||||
condition.
|
condition.
|
||||||
|
- [[file:concepts.org::#property-flags][Weak]] alternating automata in [[file:http://adl.github.io/hoaf/][the HOA format]].
|
||||||
- [[http://www.ltl2dstar.de/docs/ltl2dstar.html][=ltl2dstar='s format]], which supports deterministic Rabin or Streett
|
- [[http://www.ltl2dstar.de/docs/ltl2dstar.html][=ltl2dstar='s format]], which supports deterministic Rabin or Streett
|
||||||
automata.
|
automata.
|
||||||
|
|
||||||
|
|
@ -496,7 +500,9 @@ This classification is used to fill the =terminal_aut=, =weak_aut=,
|
||||||
=--strength= is passed). Only one of these should contain =1=. We
|
=--strength= is passed). Only one of these should contain =1=. We
|
||||||
usually prefer terminal automata over weak automata, and weak automata
|
usually prefer terminal automata over weak automata, and weak automata
|
||||||
over strong automata, because the emptiness check of terminal (and
|
over strong automata, because the emptiness check of terminal (and
|
||||||
weak) automata is easier.
|
weak) automata is easier. When working with alternating automata, all
|
||||||
|
those strength-related columns will be empty, because the routines
|
||||||
|
used to compute those statistic do not yet support universal edges.
|
||||||
|
|
||||||
=nondetstates= counts the number of non-deterministic states in the
|
=nondetstates= counts the number of non-deterministic states in the
|
||||||
automaton. =nondeterministic= is a Boolean value indicating if the
|
automaton. =nondeterministic= is a Boolean value indicating if the
|
||||||
|
|
@ -509,7 +515,8 @@ assignment $ab$) and is therefore not deterministic.
|
||||||
If option =--aumbiguous= was passed to =ltlcross=, the column
|
If option =--aumbiguous= was passed to =ltlcross=, the column
|
||||||
=ambiguous_aut= holds a Boolean indicating whether the automaton is
|
=ambiguous_aut= holds a Boolean indicating whether the automaton is
|
||||||
ambiguous, i.e., if there exists a word that can be accepted by at
|
ambiguous, i.e., if there exists a word that can be accepted by at
|
||||||
least two different runs.
|
least two different runs. (This information is not yet available for
|
||||||
|
alternating automata.)
|
||||||
|
|
||||||
=complete_aut= is a Boolean indicating whether the automaton is
|
=complete_aut= is a Boolean indicating whether the automaton is
|
||||||
complete.
|
complete.
|
||||||
|
|
@ -962,30 +969,40 @@ The verbose option can be useful to troubleshoot problems or simply
|
||||||
follow the list of transformations and tests performed by =ltlcross=.
|
follow the list of transformations and tests performed by =ltlcross=.
|
||||||
|
|
||||||
For instance here is what happens if we try to cross check =ltl2tgba=
|
For instance here is what happens if we try to cross check =ltl2tgba=
|
||||||
and =ltl3ba= on the formula =FGa=.
|
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 :results verbatim :exports code
|
||||||
ltlcross -f 'FGa' ltl2tgba ltl3ba --determinize --verbose
|
ltlcross -f 'FGa' ltl2tgba 'ltl3ba -H1' --determinize --verbose
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
#+BEGIN_SRC sh :results verbatim :exports results
|
#+BEGIN_SRC sh :results verbatim :exports results
|
||||||
ltlcross -f 'FGa' ltl2tgba ltl3ba --determinize --verbose 2>&1
|
ltlcross -f 'FGa' ltl2tgba 'ltl3ba -H1' --determinize --verbose 2>&1
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
#+RESULTS:
|
#+RESULTS:
|
||||||
#+begin_example
|
#+begin_example
|
||||||
F(G(a))
|
F(G(a))
|
||||||
Running [P0]: ltl2tgba -H 'F(G(a))'>'lcr-o0-vfVUzt'
|
Running [P0]: ltl2tgba -H 'F(G(a))'>'lcr-o0-Ak0bYx'
|
||||||
Running [P1]: ltl3ba -f '<>([](a))'>'lcr-o1-IiXGfZ'
|
Running [P1]: ltl3ba -H1 -f '<>([](a))'>'lcr-o1-5U1MyT'
|
||||||
Running [N0]: ltl2tgba -H '!(F(G(a)))'>'lcr-o0-T02eWu'
|
Running [N0]: ltl2tgba -H '!(F(G(a)))'>'lcr-o0-sX2kaf'
|
||||||
Running [N1]: ltl3ba -f '!(<>([](a)))'>'lcr-o1-0DpXF0'
|
Running [N1]: ltl3ba -H1 -f '!(<>([](a)))'>'lcr-o1-4siKPA'
|
||||||
|
info: collected automata:
|
||||||
|
info: P0 (2 st.,3 ed.,1 sets)
|
||||||
|
info: N0 (1 st.,2 ed.,1 sets) deterministic complete
|
||||||
|
info: P1 (2 st.,3 ed.,1 sets)
|
||||||
|
info: N1 (3 st.,5 ed.,1 sets) univ-edges deterministic complete
|
||||||
Performing sanity checks and gathering statistics...
|
Performing sanity checks and gathering statistics...
|
||||||
|
info: getting rid of universal edges...
|
||||||
|
info: N1 (3 st.,5 ed.,1 sets) -> (2 st.,4 ed.,1 sets)
|
||||||
info: complementing non-deterministic automata via determinization...
|
info: complementing non-deterministic automata via determinization...
|
||||||
info: P0 (2 st.,3 ed.,1 sets) -> (2 st.,4 ed.,2 sets) Comp(P0)
|
info: P0 (2 st.,3 ed.,1 sets) -> (2 st.,4 ed.,2 sets) Comp(P0)
|
||||||
info: P1 (2 st.,3 ed.,1 sets) -> (2 st.,4 ed.,2 sets) Comp(P1)
|
info: P1 (2 st.,3 ed.,1 sets) -> (2 st.,4 ed.,2 sets) Comp(P1)
|
||||||
info: getting rid of any Fin acceptance...
|
info: getting rid of any Fin acceptance...
|
||||||
info: Comp(P0) (2 st.,4 ed.,2 sets) -> (3 st.,7 ed.,2 sets)
|
info: Comp(P0) (2 st.,4 ed.,2 sets) -> (3 st.,7 ed.,2 sets)
|
||||||
info: Comp(N0) (1 st.,2 ed.,1 sets) -> (2 st.,3 ed.,1 sets)
|
info: Comp(N0) (1 st.,2 ed.,1 sets) -> (2 st.,3 ed.,1 sets)
|
||||||
|
info: P1 (2 st.,3 ed.,1 sets) -> (2 st.,3 ed.,1 sets)
|
||||||
info: Comp(P1) (2 st.,4 ed.,2 sets) -> (4 st.,9 ed.,2 sets)
|
info: Comp(P1) (2 st.,4 ed.,2 sets) -> (4 st.,9 ed.,2 sets)
|
||||||
info: Comp(N1) (2 st.,4 ed.,1 sets) -> (3 st.,6 ed.,1 sets)
|
info: Comp(N1) (2 st.,4 ed.,1 sets) -> (3 st.,6 ed.,1 sets)
|
||||||
info: check_empty P0*N0
|
info: check_empty P0*N0
|
||||||
|
|
@ -999,10 +1016,19 @@ No problem detected.
|
||||||
#+end_example
|
#+end_example
|
||||||
|
|
||||||
First =FGa= and its negations =!FGa= are translated with the two
|
First =FGa= and its negations =!FGa= are translated with the two
|
||||||
tools, resulting in four automata: to positive automata =P0= and =P1=
|
tools, resulting in four automata: two positive automata =P0= and =P1=
|
||||||
for =FGa=, and two negative automata =N0= and =N1=.
|
for =FGa=, and two negative automata =N0= and =N1=.
|
||||||
|
|
||||||
=ltlcross= then proceeds to compute the complement of these four
|
Some basic information about the collected automata are displayed.
|
||||||
|
For instance we can see that although =ltl3ba -H1= outputs co-Büchi
|
||||||
|
alternating automata, only automaton =N1= uses universal edges: the
|
||||||
|
automaton =P1= can be used like a non-alternating co-Büchi automaton.
|
||||||
|
|
||||||
|
=ltlcross= then proceeds to transform alternating automata (only weak
|
||||||
|
alternating automata are supported) into non-alternating automata.
|
||||||
|
Here only =N1= needs this transformation.
|
||||||
|
|
||||||
|
Then =ltlcross= computes the complement of these four
|
||||||
automata. Since =P0= and =P1= are nondeterministic and the
|
automata. Since =P0= and =P1= are nondeterministic and the
|
||||||
=--determinize= option was given, a first pass determinize and
|
=--determinize= option was given, a first pass determinize and
|
||||||
complete these two automata, creating =Comp(P0)= and =Comp(P1)=.
|
complete these two automata, creating =Comp(P0)= and =Comp(P1)=.
|
||||||
|
|
@ -1030,23 +1056,31 @@ Note that if we had not used the =--determinize= option, the procedure
|
||||||
would look slightly more complex:
|
would look slightly more complex:
|
||||||
|
|
||||||
#+BEGIN_SRC sh :results verbatim :exports code
|
#+BEGIN_SRC sh :results verbatim :exports code
|
||||||
ltlcross -f 'FGa' ltl2tgba ltl3ba --verbose
|
ltlcross -f 'FGa' ltl2tgba 'ltl3ba -H1' --verbose
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
#+BEGIN_SRC sh :results verbatim :exports results
|
#+BEGIN_SRC sh :results verbatim :exports results
|
||||||
ltlcross -f 'FGa' ltl2tgba ltl3ba --verbose 2>&1
|
ltlcross -f 'FGa' ltl2tgba 'ltl3ba -H1' --verbose 2>&1
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
#+RESULTS:
|
#+RESULTS:
|
||||||
#+begin_example
|
#+begin_example
|
||||||
F(G(a))
|
F(G(a))
|
||||||
Running [P0]: ltl2tgba -H 'F(G(a))'>'lcr-o0-YvMdzU'
|
Running [P0]: ltl2tgba -H 'F(G(a))'>'lcr-o0-jD32mW'
|
||||||
Running [P1]: ltl3ba -f '<>([](a))'>'lcr-o1-Ixj7RI'
|
Running [P1]: ltl3ba -H1 -f '<>([](a))'>'lcr-o1-w6IJYI'
|
||||||
Running [N0]: ltl2tgba -H '!(F(G(a)))'>'lcr-o0-uBbTbx'
|
Running [N0]: ltl2tgba -H '!(F(G(a)))'>'lcr-o0-dac1Av'
|
||||||
Running [N1]: ltl3ba -f '!(<>([](a)))'>'lcr-o1-eo0fzl'
|
Running [N1]: ltl3ba -H1 -f '!(<>([](a)))'>'lcr-o1-OZL7fi'
|
||||||
|
info: collected automata:
|
||||||
|
info: P0 (2 st.,3 ed.,1 sets)
|
||||||
|
info: N0 (1 st.,2 ed.,1 sets) deterministic complete
|
||||||
|
info: P1 (2 st.,3 ed.,1 sets)
|
||||||
|
info: N1 (3 st.,5 ed.,1 sets) univ-edges deterministic complete
|
||||||
Performing sanity checks and gathering statistics...
|
Performing sanity checks and gathering statistics...
|
||||||
|
info: getting rid of universal edges...
|
||||||
|
info: N1 (3 st.,5 ed.,1 sets) -> (2 st.,4 ed.,1 sets)
|
||||||
info: getting rid of any Fin acceptance...
|
info: getting rid of any Fin acceptance...
|
||||||
info: Comp(N0) (1 st.,2 ed.,1 sets) -> (2 st.,3 ed.,1 sets)
|
info: Comp(N0) (1 st.,2 ed.,1 sets) -> (2 st.,3 ed.,1 sets)
|
||||||
|
info: P1 (2 st.,3 ed.,1 sets) -> (2 st.,3 ed.,1 sets)
|
||||||
info: Comp(N1) (2 st.,4 ed.,1 sets) -> (3 st.,6 ed.,1 sets)
|
info: Comp(N1) (2 st.,4 ed.,1 sets) -> (3 st.,6 ed.,1 sets)
|
||||||
info: check_empty P0*N0
|
info: check_empty P0*N0
|
||||||
info: check_empty P0*N1
|
info: check_empty P0*N1
|
||||||
|
|
|
||||||
|
|
@ -256,6 +256,7 @@ TESTS_twa = \
|
||||||
core/dra2dba.test \
|
core/dra2dba.test \
|
||||||
core/unambig.test \
|
core/unambig.test \
|
||||||
core/ltlcross4.test \
|
core/ltlcross4.test \
|
||||||
|
core/ltl3ba.test \
|
||||||
core/streett.test \
|
core/streett.test \
|
||||||
core/ltl3dra.test \
|
core/ltl3dra.test \
|
||||||
core/ltl2dstar.test \
|
core/ltl2dstar.test \
|
||||||
|
|
|
||||||
42
tests/core/ltl3ba.test
Executable file
42
tests/core/ltl3ba.test
Executable file
|
|
@ -0,0 +1,42 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright (C) 2016 Laboratoire de Recherche et Développement de
|
||||||
|
# l'Epita (LRDE).
|
||||||
|
#
|
||||||
|
# This file is part of Spot, a model checking library.
|
||||||
|
#
|
||||||
|
# Spot is free software; you can redistribute it and/or modify it
|
||||||
|
# under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||||
|
# License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# Do some quick translations to make sure the neverclaims produced by
|
||||||
|
# spot actually look correct! We do that by parsing them via ltlcross.
|
||||||
|
# ltl2neverclaim-lbtt.test does the same with LBTT if it is installed.
|
||||||
|
|
||||||
|
. ./defs
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Skip this test if ltl3dra is not installed.
|
||||||
|
(ltl3ba -v) || exit 77
|
||||||
|
|
||||||
|
# The -H1 option will output alternating automata, so this tests
|
||||||
|
# ltlcross's support in this area.
|
||||||
|
randltl -n 30 2 |
|
||||||
|
ltlcross 'ltl3ba -H1' 'ltl3ba -H2' 'ltl3ba -H3' \
|
||||||
|
--ambiguous --strength --csv=output.csv
|
||||||
|
|
||||||
|
# Make sure all lines in output.csv have the same number of comas
|
||||||
|
sed 's/[^,]//g' <output.csv |
|
||||||
|
( read first
|
||||||
|
while read l; do
|
||||||
|
test "x$first" = "x$l" || exit 1
|
||||||
|
done)
|
||||||
|
|
@ -29,7 +29,7 @@ set -e
|
||||||
(ltl3dra -v) || exit 77
|
(ltl3dra -v) || exit 77
|
||||||
|
|
||||||
# This used to crash ltlcross because the number of
|
# This used to crash ltlcross because the number of
|
||||||
# acceptance sets generated was to high.
|
# acceptance sets generated was too high.
|
||||||
ltlcross 'ltl2tgba' 'ltl3dra' -f '(<>((((p0) &&
|
ltlcross 'ltl2tgba' 'ltl3dra' -f '(<>((((p0) &&
|
||||||
(!(<>(p2)))) || ((!(p0)) && (<>(p2)))) U ((<>(((p0) && (!([](((!(p1))
|
(!(<>(p2)))) || ((!(p0)) && (<>(p2)))) U ((<>(((p0) && (!([](((!(p1))
|
||||||
&& ([](p3))) || ((p1) && (!([](p3)))))))) || ((!(p0)) && ([](((!(p1))
|
&& ([](p3))) || ((p1) && (!([](p3)))))))) || ((!(p0)) && ([](((!(p1))
|
||||||
|
|
@ -41,3 +41,21 @@ ltlcross 'ltl2tgba' 'ltl3dra' -f '(<>((((p0) &&
|
||||||
# relabeled p0&p1, and then p0 was unregistered despite being one of
|
# relabeled p0&p1, and then p0 was unregistered despite being one of
|
||||||
# the new variables.
|
# the new variables.
|
||||||
ltldo ltl3dra -f '"a=0" & p0' | grep 'AP: 2.*p0'
|
ltldo ltl3dra -f '"a=0" & p0' | grep 'AP: 2.*p0'
|
||||||
|
|
||||||
|
# ltl3dra 0.2.2 has a bug were 'ltl3dra -H1 -f true' produce an
|
||||||
|
# empty automaton. ltl3dra 0.2.3 fixes that but introduces another
|
||||||
|
# bug where 'ltl3dra -f "!(a <-> Fb)" rejects cycle{!a & b}.
|
||||||
|
#
|
||||||
|
# # The -H1 option will output alternating automata, so this tests
|
||||||
|
# # ltlcross's support in this area.
|
||||||
|
# randltl -n 30 2 |
|
||||||
|
# ltlcross 'ltl3dra -H1' 'ltl3dra -H2' 'ltl3dra -H3' \
|
||||||
|
# --ignore-execution-failures --ambiguous \
|
||||||
|
# --strength --csv=output.csv
|
||||||
|
#
|
||||||
|
# # Make sure all lines in output.csv have the same number of comas
|
||||||
|
# sed 's/[^,]//g' <output.csv |
|
||||||
|
# ( read first
|
||||||
|
# while read l; do
|
||||||
|
# test "x$first" = "x$l" || exit 1
|
||||||
|
# done)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue