homogenize dstar_parse() and parse_aut() outputs
* src/dstarparse/dstarparse.yy, src/dstarparse/dstarscan.ll src/dstarparse/parsedecl.hh, src/dstarparse/public.hh: Adjust to return the same return types as parse_aut. * src/dstarparse/fmterror.cc: Delete, we can use the one of parse_aut. * src/dstarparse/Makefile.am: Adjust. * src/tests/ikwiad.cc, src/bin/dstar2tgba.cc, src/bin/ltldo.cc: Adjust usage. * src/bin/ltlcross.cc: The the result of dstar_parse() as-is, now that it is a TωA like those produced by parse_aut(). As a consequence, get rid of all the code storing statistics about the input automaton. * src/tests/ltlcross3.test, src/tests/ltl2dstar.test: Adjust expected CSV output. * doc/org/ltlcross.org, src/bin/man/ltlcross.x: Adjust to not mention that %D performs a tranformation to Büchi.
This commit is contained in:
parent
62f5b9769b
commit
f831f729e1
14 changed files with 61 additions and 231 deletions
|
|
@ -145,10 +145,8 @@ tools:
|
||||||
--output-format=hoa %L %O~' deterministic Streett output in HOA,
|
--output-format=hoa %L %O~' deterministic Streett output in HOA,
|
||||||
as supported since version 0.5.2 of =ltl2dstar=.
|
as supported since version 0.5.2 of =ltl2dstar=.
|
||||||
- '=ltl2dstar --ltl2nba=spin:path/to/ltl2tgba@-sD %L %D=' (Rabin
|
- '=ltl2dstar --ltl2nba=spin:path/to/ltl2tgba@-sD %L %D=' (Rabin
|
||||||
output in DSTAR format, as supported in older version of
|
output in DSTAR format, as supported in older versions of
|
||||||
=ltl2dstar=. Note that when reading this format, =ltl2dstar=
|
=ltl2dstar=.
|
||||||
automatically converts the Rabin automaton into a Büchi automaton
|
|
||||||
for historical reason.)
|
|
||||||
- '=ltl2dstar --ltl2nba=spin:path/to/ltl2tgba@-sD %L - | dstar2tgba
|
- '=ltl2dstar --ltl2nba=spin:path/to/ltl2tgba@-sD %L - | dstar2tgba
|
||||||
-s >%O=' (external conversion from Rabin to Büchi done by
|
-s >%O=' (external conversion from Rabin to Büchi done by
|
||||||
=dstar2tgba= for more reduction of the Büchi automaton than what
|
=dstar2tgba= for more reduction of the Büchi automaton than what
|
||||||
|
|
@ -420,20 +418,6 @@ All the values that follow will be missing if =exit_status= is not
|
||||||
equal to "=ok=". (You may instruct =ltlcross= not to output lines with
|
equal to "=ok=". (You may instruct =ltlcross= not to output lines with
|
||||||
such missing data with the option =--omit-missing=.)
|
such missing data with the option =--omit-missing=.)
|
||||||
|
|
||||||
The columns =in_type=, =in_states=, =in_edges=, =in_transitions=,
|
|
||||||
=in_acc=, and =in_scc= are only output if one of the translator
|
|
||||||
produces Rabin or Streett automata in =ltl2dstar='s format (i.e., if
|
|
||||||
=%D= is used to specify one output filename for any translator). In
|
|
||||||
that case these columns give the type (DRA or DSA) of the produced
|
|
||||||
automaton, as well as its size (states, edges, transitions, number of
|
|
||||||
acceptance pairs, and number of SCCs). This input automaton is then
|
|
||||||
converted by =ltlcross= into a TGBA before being checked the result of
|
|
||||||
other translators, and all the following columns are measures of that
|
|
||||||
converted automaton. This conversion to TGBA is historical. When the
|
|
||||||
automata are produced in the HOA format (i.e., not in =ltl2dstar='s
|
|
||||||
format) then no conversion occur, and =ltlcross= works directly with
|
|
||||||
the given acceptance condition.
|
|
||||||
|
|
||||||
=states=, =edges=, =transitions=, =acc= are size measures for the
|
=states=, =edges=, =transitions=, =acc= are size measures for the
|
||||||
automaton that was translated. =acc= counts the number of acceptance
|
automaton that was translated. =acc= counts the number of acceptance
|
||||||
sets. When building (degeneralized) Büchi automata, it will always be
|
sets. When building (degeneralized) Büchi automata, it will always be
|
||||||
|
|
@ -647,9 +631,9 @@ positive and negative formulas by the ith translator).
|
||||||
coverage. Using '=ltl2tgba -lD %f >%O=' will produce
|
coverage. Using '=ltl2tgba -lD %f >%O=' will produce
|
||||||
deterministic automata for all obligation properties and many
|
deterministic automata for all obligation properties and many
|
||||||
recurrence properties. Using '=ltl2dstar
|
recurrence properties. Using '=ltl2dstar
|
||||||
--ltl2nba=spin:pathto/ltl2tgba@-sD %L %D=' is more expansive, but
|
--ltl2nba=spin:pathto/ltl2tgba@-Ds %L %D=' will systematically
|
||||||
it will produce a deterministic Büchi automaton whenever one
|
produce a deterministic Rabin automaton (that =ltlcross= can
|
||||||
exists.
|
complement easily).
|
||||||
|
|
||||||
- Cross-comparison checks: for some state-space $S$,
|
- Cross-comparison checks: for some state-space $S$,
|
||||||
all $P_i\otimes S$ are either all empty, or all non-empty.
|
all $P_i\otimes S$ are either all empty, or all non-empty.
|
||||||
|
|
|
||||||
|
|
@ -266,7 +266,7 @@ namespace
|
||||||
/// The \a f argument is not needed if the Formula does not need
|
/// The \a f argument is not needed if the Formula does not need
|
||||||
/// to be output.
|
/// to be output.
|
||||||
std::ostream&
|
std::ostream&
|
||||||
print(const spot::const_dstar_aut_ptr& daut,
|
print(const spot::const_parsed_aut_ptr& daut,
|
||||||
const spot::const_twa_graph_ptr& aut,
|
const spot::const_twa_graph_ptr& aut,
|
||||||
const char* filename, double run_time)
|
const char* filename, double run_time)
|
||||||
{
|
{
|
||||||
|
|
@ -347,9 +347,9 @@ namespace
|
||||||
int
|
int
|
||||||
process_file(const char* filename)
|
process_file(const char* filename)
|
||||||
{
|
{
|
||||||
spot::dstar_parse_error_list pel;
|
spot::parse_aut_error_list pel;
|
||||||
auto daut = spot::dstar_parse(filename, pel, spot::make_bdd_dict());
|
auto daut = spot::dstar_parse(filename, pel, spot::make_bdd_dict());
|
||||||
if (spot::format_dstar_parse_errors(std::cerr, filename, pel))
|
if (spot::format_parse_aut_errors(std::cerr, filename, pel))
|
||||||
return 2;
|
return 2;
|
||||||
if (!daut)
|
if (!daut)
|
||||||
error(2, 0, "failed to read automaton from %s", filename);
|
error(2, 0, "failed to read automaton from %s", filename);
|
||||||
|
|
|
||||||
|
|
@ -199,7 +199,6 @@ static int seed = 0;
|
||||||
static unsigned products = 1;
|
static unsigned products = 1;
|
||||||
static bool products_avg = true;
|
static bool products_avg = true;
|
||||||
static bool opt_omit = false;
|
static bool opt_omit = false;
|
||||||
static bool has_sr = false; // Has Streett or Rabin automata to process.
|
|
||||||
static const char* bogus_output_filename = 0;
|
static const char* bogus_output_filename = 0;
|
||||||
static output_file* bogus_output = 0;
|
static output_file* bogus_output = 0;
|
||||||
static output_file* grind_output = 0;
|
static output_file* grind_output = 0;
|
||||||
|
|
@ -240,16 +239,9 @@ struct statistics
|
||||||
{
|
{
|
||||||
statistics()
|
statistics()
|
||||||
: ok(false),
|
: ok(false),
|
||||||
has_in(false),
|
|
||||||
status_str(0),
|
status_str(0),
|
||||||
status_code(0),
|
status_code(0),
|
||||||
time(0),
|
time(0),
|
||||||
in_type(0),
|
|
||||||
in_states(0),
|
|
||||||
in_edges(0),
|
|
||||||
in_transitions(0),
|
|
||||||
in_acc(0),
|
|
||||||
in_scc(0),
|
|
||||||
states(0),
|
states(0),
|
||||||
edges(0),
|
edges(0),
|
||||||
transitions(0),
|
transitions(0),
|
||||||
|
|
@ -270,17 +262,9 @@ 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;
|
||||||
// has in_* data to display.
|
|
||||||
bool has_in;
|
|
||||||
const char* status_str;
|
const char* status_str;
|
||||||
int status_code;
|
int status_code;
|
||||||
double time;
|
double time;
|
||||||
const char* in_type;
|
|
||||||
unsigned in_states;
|
|
||||||
unsigned in_edges;
|
|
||||||
unsigned in_transitions;
|
|
||||||
unsigned in_acc;
|
|
||||||
unsigned in_scc;
|
|
||||||
unsigned states;
|
unsigned states;
|
||||||
unsigned edges;
|
unsigned edges;
|
||||||
unsigned transitions;
|
unsigned transitions;
|
||||||
|
|
@ -303,15 +287,12 @@ struct statistics
|
||||||
std::string hoa_str;
|
std::string hoa_str;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fields(std::ostream& os, bool show_exit, bool show_sr)
|
fields(std::ostream& os, bool show_exit)
|
||||||
{
|
{
|
||||||
if (show_exit)
|
if (show_exit)
|
||||||
os << "\"exit_status\",\"exit_code\",";
|
os << "\"exit_status\",\"exit_code\",";
|
||||||
os << "\"time\",";
|
os << ("\"time\","
|
||||||
if (show_sr)
|
"\"states\","
|
||||||
os << ("\"in_type\",\"in_states\",\"in_edges\",\"in_transitions\","
|
|
||||||
"\"in_acc\",\"in_scc\",");
|
|
||||||
os << ("\"states\","
|
|
||||||
"\"edges\","
|
"\"edges\","
|
||||||
"\"transitions\","
|
"\"transitions\","
|
||||||
"\"acc\","
|
"\"acc\","
|
||||||
|
|
@ -335,7 +316,7 @@ struct statistics
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
to_csv(std::ostream& os, bool show_exit, bool show_sr, const char* na = "",
|
to_csv(std::ostream& os, bool show_exit, const char* na = "",
|
||||||
bool csv_escape = true)
|
bool csv_escape = true)
|
||||||
{
|
{
|
||||||
if (show_exit)
|
if (show_exit)
|
||||||
|
|
@ -343,16 +324,6 @@ struct statistics
|
||||||
os << time << ',';
|
os << time << ',';
|
||||||
if (ok)
|
if (ok)
|
||||||
{
|
{
|
||||||
if (has_in)
|
|
||||||
os << '"' << in_type << "\","
|
|
||||||
<< in_states << ','
|
|
||||||
<< in_edges << ','
|
|
||||||
<< in_transitions << ','
|
|
||||||
<< in_acc << ','
|
|
||||||
<< in_scc << ',';
|
|
||||||
else if (show_sr)
|
|
||||||
os << na << ',' << na << ',' << na << ','
|
|
||||||
<< na << ',' << na << ',' << na << ',';
|
|
||||||
os << states << ','
|
os << states << ','
|
||||||
<< edges << ','
|
<< edges << ','
|
||||||
<< transitions << ','
|
<< transitions << ','
|
||||||
|
|
@ -396,7 +367,7 @@ struct statistics
|
||||||
{
|
{
|
||||||
size_t m = products_avg ? 1U : products;
|
size_t m = products_avg ? 1U : products;
|
||||||
m *= 3;
|
m *= 3;
|
||||||
m += 15 + show_sr * 6;
|
m += 15;
|
||||||
os << na;
|
os << na;
|
||||||
for (size_t i = 0; i < m; ++i)
|
for (size_t i = 0; i < m; ++i)
|
||||||
os << ',' << na;
|
os << ',' << na;
|
||||||
|
|
@ -509,7 +480,6 @@ namespace
|
||||||
xtranslator_runner(spot::bdd_dict_ptr dict)
|
xtranslator_runner(spot::bdd_dict_ptr dict)
|
||||||
: translator_runner(dict)
|
: translator_runner(dict)
|
||||||
{
|
{
|
||||||
has_sr = has('D');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
spot::twa_graph_ptr
|
spot::twa_graph_ptr
|
||||||
|
|
@ -580,7 +550,7 @@ namespace
|
||||||
{
|
{
|
||||||
case printable_result_filename::Dstar:
|
case printable_result_filename::Dstar:
|
||||||
{
|
{
|
||||||
spot::dstar_parse_error_list pel;
|
spot::parse_aut_error_list pel;
|
||||||
std::string filename = output.val()->name();
|
std::string filename = output.val()->name();
|
||||||
auto aut = spot::dstar_parse(filename, pel, dict);
|
auto aut = spot::dstar_parse(filename, pel, dict);
|
||||||
if (!pel.empty())
|
if (!pel.empty())
|
||||||
|
|
@ -591,43 +561,13 @@ namespace
|
||||||
std::ostream& err = global_error();
|
std::ostream& err = global_error();
|
||||||
err << "error: failed to parse the produced DSTAR"
|
err << "error: failed to parse the produced DSTAR"
|
||||||
" output.\n";
|
" output.\n";
|
||||||
spot::format_dstar_parse_errors(err, filename, pel);
|
spot::format_parse_aut_errors(err, filename, pel);
|
||||||
end_error();
|
end_error();
|
||||||
res = nullptr;
|
res = nullptr;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const char* type = 0;
|
res = aut->aut;
|
||||||
switch (aut->type)
|
|
||||||
{
|
|
||||||
case spot::Rabin:
|
|
||||||
type = "DRA";
|
|
||||||
break;
|
|
||||||
case spot::Streett:
|
|
||||||
type = "DSA";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
assert(type);
|
|
||||||
|
|
||||||
// Gather statistics about the input automaton
|
|
||||||
if (want_stats)
|
|
||||||
{
|
|
||||||
statistics* st = &(*fstats)[translator_num];
|
|
||||||
st->has_in = true;
|
|
||||||
st->in_type = type;
|
|
||||||
spot::tgba_sub_statistics s =
|
|
||||||
sub_stats_reachable(aut->aut);
|
|
||||||
st->in_states= s.states;
|
|
||||||
st->in_edges = s.transitions;
|
|
||||||
st->in_transitions = s.sub_transitions;
|
|
||||||
st->in_acc = aut->aut->num_sets() / 2;
|
|
||||||
|
|
||||||
st->in_scc = spot::scc_info(aut->aut).scc_count();
|
|
||||||
}
|
|
||||||
// convert it into TGBA for further processing
|
|
||||||
if (verbose)
|
|
||||||
std::cerr << "info: converting " << type << " to TGBA\n";
|
|
||||||
res = remove_fin(aut->aut);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -1407,7 +1347,7 @@ print_stats_csv(const char* filename)
|
||||||
// Do not output the header line if we append to a file.
|
// Do not output the header line if we append to a file.
|
||||||
// (Even if that file was empty initially.)
|
// (Even if that file was empty initially.)
|
||||||
out << "\"formula\",\"tool\",";
|
out << "\"formula\",\"tool\",";
|
||||||
statistics::fields(out, !opt_omit, has_sr);
|
statistics::fields(out, !opt_omit);
|
||||||
out << '\n';
|
out << '\n';
|
||||||
}
|
}
|
||||||
for (unsigned r = 0; r < rounds; ++r)
|
for (unsigned r = 0; r < rounds; ++r)
|
||||||
|
|
@ -1419,7 +1359,7 @@ print_stats_csv(const char* filename)
|
||||||
out << "\",\"";
|
out << "\",\"";
|
||||||
spot::escape_rfc4180(out, translators[t].name);
|
spot::escape_rfc4180(out, translators[t].name);
|
||||||
out << "\",";
|
out << "\",";
|
||||||
vstats[r][t].to_csv(out, !opt_omit, has_sr);
|
vstats[r][t].to_csv(out, !opt_omit);
|
||||||
out << '\n';
|
out << '\n';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1452,7 +1392,7 @@ print_stats_json(const char* filename)
|
||||||
spot::escape_str(out, formulas[r]);
|
spot::escape_str(out, formulas[r]);
|
||||||
}
|
}
|
||||||
out << ("\"\n ],\n \"fields\": [\n \"formula\",\"tool\",");
|
out << ("\"\n ],\n \"fields\": [\n \"formula\",\"tool\",");
|
||||||
statistics::fields(out, !opt_omit, has_sr);
|
statistics::fields(out, !opt_omit);
|
||||||
out << "\n ],\n \"inputs\": [ 0, 1 ],";
|
out << "\n ],\n \"inputs\": [ 0, 1 ],";
|
||||||
out << "\n \"results\": [";
|
out << "\n \"results\": [";
|
||||||
bool notfirst = false;
|
bool notfirst = false;
|
||||||
|
|
@ -1464,7 +1404,7 @@ print_stats_json(const char* filename)
|
||||||
out << ',';
|
out << ',';
|
||||||
notfirst = true;
|
notfirst = true;
|
||||||
out << "\n [ " << r << ',' << t << ',';
|
out << "\n [ " << r << ',' << t << ',';
|
||||||
vstats[r][t].to_csv(out, !opt_omit, has_sr, "null", false);
|
vstats[r][t].to_csv(out, !opt_omit, "null", false);
|
||||||
out << " ]";
|
out << " ]";
|
||||||
}
|
}
|
||||||
out << "\n ]\n}\n";
|
out << "\n ]\n}\n";
|
||||||
|
|
|
||||||
|
|
@ -173,7 +173,7 @@ namespace
|
||||||
{
|
{
|
||||||
case printable_result_filename::Dstar:
|
case printable_result_filename::Dstar:
|
||||||
{
|
{
|
||||||
spot::dstar_parse_error_list pel;
|
spot::parse_aut_error_list pel;
|
||||||
std::string filename = output.val()->name();
|
std::string filename = output.val()->name();
|
||||||
auto aut = spot::dstar_parse(filename, pel, dict);
|
auto aut = spot::dstar_parse(filename, pel, dict);
|
||||||
if (!pel.empty())
|
if (!pel.empty())
|
||||||
|
|
@ -181,7 +181,7 @@ namespace
|
||||||
problem = true;
|
problem = true;
|
||||||
std::cerr << "error: failed to parse the output of \""
|
std::cerr << "error: failed to parse the output of \""
|
||||||
<< cmd << "\" as a DSTAR automaton.\n";
|
<< cmd << "\" as a DSTAR automaton.\n";
|
||||||
spot::format_dstar_parse_errors(std::cerr, filename, pel);
|
spot::format_parse_aut_errors(std::cerr, filename, pel);
|
||||||
res = nullptr;
|
res = nullptr;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -50,38 +50,31 @@ distinguish and understand these three formats.
|
||||||
.PP
|
.PP
|
||||||
Rabin or Streett automata output by
|
Rabin or Streett automata output by
|
||||||
.B ltl2dstar
|
.B ltl2dstar
|
||||||
can be read from a
|
in its historical format can be read from a
|
||||||
file specified with \f(CW%D\fR instead of \f(CW%O\fR. For instance:
|
file specified with \f(CW%D\fR instead of \f(CW%O\fR. For instance:
|
||||||
.PP
|
.PP
|
||||||
.in +4n
|
.in +4n
|
||||||
.nf
|
.nf
|
||||||
.ft C
|
.ft C
|
||||||
% ltlcross \-F input.ltl \e
|
% ltlcross \-F input.ltl \e
|
||||||
'ltl2dstar \-\-ltl2nba=spin:ltl2tgba@\-s %L %D' \e
|
'ltl2dstar \-\-ltl2nba=spin:ltl2tgba@\-Ds %L %D' \e
|
||||||
'ltl2dstar \-\-automata=streett \-\-ltl2nba=spin:ltl2tgba@\-s %L %D' \e
|
'ltl2dstar \-\-automata=streett \-\-ltl2nba=spin:ltl2tgba@\-Ds %L %D' \e
|
||||||
.fi
|
.fi
|
||||||
.PP
|
.PP
|
||||||
However, for historical reasons these Rabin and
|
However, we now recommand to use the HOA output of
|
||||||
Streett automata are immediately converted to TGBA before further
|
.BR ltl2dstar ,
|
||||||
processing by
|
as supported since version 0.5.2:
|
||||||
.BR ltlcross .
|
|
||||||
This is still interesting to search for bugs
|
|
||||||
in translators to Rabin or Streett automata, but the statistics might
|
|
||||||
not be very relevant. If statistics matters to you and you do not want
|
|
||||||
this conversion to occur, use the HOA format to interface with ltl2dstar:
|
|
||||||
.PP
|
.PP
|
||||||
.in +4n
|
.in +4n
|
||||||
.nf
|
.nf
|
||||||
.ft C
|
.ft C
|
||||||
% ltlcross \-F input.ltl \e
|
% ltlcross \-F input.ltl \e
|
||||||
'ltl2dstar \-\-output\-format=hoa \-\-ltl2nba=spin:ltl2tgba@\-s %L %O' \e
|
'ltl2dstar \-\-output\-format=hoa \-\-ltl2nba=spin:ltl2tgba@\-Ds %L %O' \e
|
||||||
'ltl2dstar \-\-output\-format=hoa \-\-automata=streett \-\-ltl2nba=spin:ltl2tgba@\-s %L %O' \e
|
'ltl2dstar \-\-output\-format=hoa \-\-automata=streett \-\-ltl2nba=spin:ltl2tgba@\-Ds %L %O' \e
|
||||||
.fi
|
.fi
|
||||||
.PP
|
.PP
|
||||||
If you use ltlcross in an automated testsuite just to check for
|
In more recent versions of ltl2dstar, \fB\-\-output\-format=hoa\fR can
|
||||||
potential problems, avoid the \fB\-\-csv\fR and \fB\-\-json\fR
|
be abbreviated \fB-H\fR.
|
||||||
options: ltlcross is faster when it does not have to compute these
|
|
||||||
statistics.
|
|
||||||
|
|
||||||
[ENVIRONMENT VARIABLES]
|
[ENVIRONMENT VARIABLES]
|
||||||
.TP
|
.TP
|
||||||
|
|
@ -151,16 +144,6 @@ This is reported for all executions, even failling ones.
|
||||||
Unless the \fB\-\-omit\-missing\fR option is used, data for all the
|
Unless the \fB\-\-omit\-missing\fR option is used, data for all the
|
||||||
following columns might be missing.
|
following columns might be missing.
|
||||||
.TP
|
.TP
|
||||||
\fBin_type\fR, \fBin_states\fR, \fBin_edges\fR, \fBin_transitions\fR,
|
|
||||||
\fBin_acc\fR , \fBin_scc\fR These columns are only output if
|
|
||||||
\f(CW%D\fR appears in any command specification, i.e., if any of the
|
|
||||||
tools output some Streett or Rabin automata. In this case
|
|
||||||
\fBin_type\fR contains a string that is either \f(CWDRA\fR
|
|
||||||
(Deterministic Rabin Automaton) or \f(CWDSA\fR (Deterministic Streett
|
|
||||||
Automaton). The other columns respectively give the number of states,
|
|
||||||
edges, transitions, acceptance pairs, and strongly connected
|
|
||||||
components in that automaton.
|
|
||||||
.TP
|
|
||||||
\fBstates\fR, \fBedges\fR, \fBtransitions\fR, \fBacc\fR
|
\fBstates\fR, \fBedges\fR, \fBtransitions\fR, \fBacc\fR
|
||||||
The number of states, edges, transitions, and acceptance sets in the
|
The number of states, edges, transitions, and acceptance sets in the
|
||||||
translated automaton. Column \fBedges\fR counts the number of edges
|
translated automaton. Column \fBedges\fR counts the number of edges
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,6 @@ $(FROM_DSTARPARSE_YY_OTHERS): $(DSTARPARSE_YY)
|
||||||
EXTRA_DIST = $(DSTARPARSE_YY)
|
EXTRA_DIST = $(DSTARPARSE_YY)
|
||||||
|
|
||||||
libdstarparse_la_SOURCES = \
|
libdstarparse_la_SOURCES = \
|
||||||
fmterror.cc \
|
|
||||||
$(FROM_DSTARPARSE_YY) \
|
$(FROM_DSTARPARSE_YY) \
|
||||||
dstarscan.ll \
|
dstarscan.ll \
|
||||||
parsedecl.hh
|
parsedecl.hh
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@
|
||||||
%name-prefix "dstaryy"
|
%name-prefix "dstaryy"
|
||||||
%debug
|
%debug
|
||||||
%error-verbose
|
%error-verbose
|
||||||
%lex-param { spot::dstar_parse_error_list& error_list }
|
%lex-param { spot::parse_aut_error_list& error_list }
|
||||||
%define api.location.type "spot::location"
|
%define api.location.type "spot::location"
|
||||||
|
|
||||||
%code requires
|
%code requires
|
||||||
|
|
@ -38,9 +38,12 @@
|
||||||
{
|
{
|
||||||
typedef std::map<int, bdd> map_t;
|
typedef std::map<int, bdd> map_t;
|
||||||
|
|
||||||
|
enum dstar_type { Rabin, Streett };
|
||||||
|
|
||||||
struct result_
|
struct result_
|
||||||
{
|
{
|
||||||
spot::dstar_aut_ptr d;
|
spot::parsed_aut_ptr d;
|
||||||
|
dstar_type type;
|
||||||
spot::ltl::environment* env;
|
spot::ltl::environment* env;
|
||||||
std::vector<bdd> guards;
|
std::vector<bdd> guards;
|
||||||
std::vector<bdd>::const_iterator cur_guard;
|
std::vector<bdd>::const_iterator cur_guard;
|
||||||
|
|
@ -70,7 +73,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
%parse-param {spot::dstar_parse_error_list& error_list}
|
%parse-param {spot::parse_aut_error_list& error_list}
|
||||||
%parse-param {result_& result}
|
%parse-param {result_& result}
|
||||||
%union
|
%union
|
||||||
{
|
{
|
||||||
|
|
@ -118,19 +121,20 @@
|
||||||
|
|
||||||
%%
|
%%
|
||||||
dstar: header ENDOFHEADER eols states
|
dstar: header ENDOFHEADER eols states
|
||||||
|
{ result.d->loc = @$; }
|
||||||
|
|
||||||
eols : EOL | eols EOL
|
eols : EOL | eols EOL
|
||||||
opt_eols: | opt_eols EOL
|
opt_eols: | opt_eols EOL
|
||||||
|
|
||||||
auttype: DRA
|
auttype: DRA
|
||||||
{
|
{
|
||||||
result.d->type = spot::Rabin;
|
result.type = Rabin;
|
||||||
result.plus = 1;
|
result.plus = 1;
|
||||||
result.minus = 0;
|
result.minus = 0;
|
||||||
}
|
}
|
||||||
| DSA
|
| DSA
|
||||||
{
|
{
|
||||||
result.d->type = spot::Streett;
|
result.type = Streett;
|
||||||
result.plus = 0;
|
result.plus = 0;
|
||||||
result.minus = 1;
|
result.minus = 1;
|
||||||
}
|
}
|
||||||
|
|
@ -185,7 +189,7 @@ sizes:
|
||||||
result.accpair_count = $4;
|
result.accpair_count = $4;
|
||||||
result.accpair_count_seen = true;
|
result.accpair_count_seen = true;
|
||||||
result.d->aut->set_acceptance(2 * $4,
|
result.d->aut->set_acceptance(2 * $4,
|
||||||
result.d->type == spot::Rabin ?
|
result.type == Rabin ?
|
||||||
spot::acc_cond::acc_code::rabin($4) :
|
spot::acc_cond::acc_code::rabin($4) :
|
||||||
spot::acc_cond::acc_code::streett($4));
|
spot::acc_cond::acc_code::streett($4));
|
||||||
}
|
}
|
||||||
|
|
@ -332,9 +336,9 @@ dstaryy::parser::error(const location_type& location,
|
||||||
|
|
||||||
namespace spot
|
namespace spot
|
||||||
{
|
{
|
||||||
dstar_aut_ptr
|
parsed_aut_ptr
|
||||||
dstar_parse(const std::string& name,
|
dstar_parse(const std::string& name,
|
||||||
dstar_parse_error_list& error_list,
|
parse_aut_error_list& error_list,
|
||||||
const bdd_dict_ptr& dict,
|
const bdd_dict_ptr& dict,
|
||||||
ltl::environment& env,
|
ltl::environment& env,
|
||||||
bool debug)
|
bool debug)
|
||||||
|
|
@ -343,10 +347,10 @@ namespace spot
|
||||||
{
|
{
|
||||||
error_list.emplace_back(spot::location(),
|
error_list.emplace_back(spot::location(),
|
||||||
std::string("Cannot open file ") + name);
|
std::string("Cannot open file ") + name);
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
result_ r;
|
result_ r;
|
||||||
r.d = std::make_shared<spot::dstar_aut>();
|
r.d = std::make_shared<spot::parsed_aut>();
|
||||||
r.d->aut = make_twa_graph(dict);
|
r.d->aut = make_twa_graph(dict);
|
||||||
r.d->aut->prop_deterministic(true);
|
r.d->aut->prop_deterministic(true);
|
||||||
r.d->aut->prop_state_based_acc(true);
|
r.d->aut->prop_state_based_acc(true);
|
||||||
|
|
@ -355,9 +359,6 @@ namespace spot
|
||||||
parser.set_debug_level(debug);
|
parser.set_debug_level(debug);
|
||||||
parser.parse();
|
parser.parse();
|
||||||
dstaryyclose();
|
dstaryyclose();
|
||||||
|
|
||||||
if (!r.d->aut)
|
|
||||||
return nullptr;
|
|
||||||
return r.d;
|
return r.d;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,7 @@ eol2 (\n\r)+|(\r\n)+
|
||||||
if (errno || yylval->num != n)
|
if (errno || yylval->num != n)
|
||||||
{
|
{
|
||||||
error_list.push_back(
|
error_list.push_back(
|
||||||
spot::dstar_parse_error(*yylloc,
|
spot::parse_aut_error(*yylloc,
|
||||||
"value too large"));
|
"value too large"));
|
||||||
yylval->num = 0;
|
yylval->num = 0;
|
||||||
}
|
}
|
||||||
|
|
@ -88,7 +88,7 @@ eol2 (\n\r)+|(\r\n)+
|
||||||
"*"+"/" BEGIN(INITIAL);
|
"*"+"/" BEGIN(INITIAL);
|
||||||
<<EOF>> {
|
<<EOF>> {
|
||||||
error_list.push_back(
|
error_list.push_back(
|
||||||
spot::dstar_parse_error(*yylloc,
|
spot::parse_aut_error(*yylloc,
|
||||||
"unclosed comment"));
|
"unclosed comment"));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -105,7 +105,7 @@ eol2 (\n\r)+|(\r\n)+
|
||||||
[^\\\"]+ s.append(yytext, yyleng);
|
[^\\\"]+ s.append(yytext, yyleng);
|
||||||
<<EOF>> {
|
<<EOF>> {
|
||||||
error_list.push_back(
|
error_list.push_back(
|
||||||
spot::dstar_parse_error(*yylloc,
|
spot::parse_aut_error(*yylloc,
|
||||||
"unclosed string"));
|
"unclosed string"));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,42 +0,0 @@
|
||||||
// -*- coding: utf-8 -*-
|
|
||||||
// Copyright (C) 2013, 2014 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/>.
|
|
||||||
|
|
||||||
#include <ostream>
|
|
||||||
#include "public.hh"
|
|
||||||
|
|
||||||
namespace spot
|
|
||||||
{
|
|
||||||
bool
|
|
||||||
format_dstar_parse_errors(std::ostream& os,
|
|
||||||
const std::string& filename,
|
|
||||||
dstar_parse_error_list& error_list)
|
|
||||||
{
|
|
||||||
bool printed = false;
|
|
||||||
spot::dstar_parse_error_list::iterator it;
|
|
||||||
for (it = error_list.begin(); it != error_list.end(); ++it)
|
|
||||||
{
|
|
||||||
if (filename != "-")
|
|
||||||
os << filename << ':';
|
|
||||||
os << it->first << ": ";
|
|
||||||
os << it->second << std::endl;
|
|
||||||
printed = true;
|
|
||||||
}
|
|
||||||
return printed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2013 Laboratoire de Recherche et Développement
|
// Copyright (C) 2013, 2015 Laboratoire de Recherche et Développement
|
||||||
// de l'EPITA.
|
// de l'EPITA.
|
||||||
//
|
//
|
||||||
// This file is part of Spot, a model checking library.
|
// This file is part of Spot, a model checking library.
|
||||||
|
|
@ -22,11 +22,12 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "dstarparse.hh"
|
#include "dstarparse.hh"
|
||||||
#include "misc/location.hh"
|
#include "misc/location.hh"
|
||||||
|
#include "parseaut/public.hh"
|
||||||
|
|
||||||
# define YY_DECL \
|
# define YY_DECL \
|
||||||
int dstaryylex(dstaryy::parser::semantic_type *yylval, \
|
int dstaryylex(dstaryy::parser::semantic_type *yylval, \
|
||||||
spot::location *yylloc, \
|
spot::location *yylloc, \
|
||||||
spot::dstar_parse_error_list& error_list)
|
spot::parse_aut_error_list& error_list)
|
||||||
YY_DECL;
|
YY_DECL;
|
||||||
|
|
||||||
namespace spot
|
namespace spot
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@
|
||||||
#include "twa/twagraph.hh"
|
#include "twa/twagraph.hh"
|
||||||
#include "misc/location.hh"
|
#include "misc/location.hh"
|
||||||
#include "ltlenv/defaultenv.hh"
|
#include "ltlenv/defaultenv.hh"
|
||||||
|
#include "parseaut/public.hh"
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
@ -32,28 +33,7 @@ namespace spot
|
||||||
/// \addtogroup twa_io
|
/// \addtogroup twa_io
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
/// \brief A parse diagnostic with its location.
|
/// \brief Build a spot::twa_graph_ptr from ltl2dstar's output.
|
||||||
typedef std::pair<spot::location, std::string> dstar_parse_error;
|
|
||||||
/// \brief A list of parser diagnostics, as filled by parse.
|
|
||||||
typedef std::list<dstar_parse_error> dstar_parse_error_list;
|
|
||||||
|
|
||||||
enum dstar_type { Rabin, Streett };
|
|
||||||
|
|
||||||
/// \brief Temporary encoding of an omega automaton produced by
|
|
||||||
/// ltl2dstar.
|
|
||||||
struct SPOT_API dstar_aut
|
|
||||||
{
|
|
||||||
// Transition structure of the automaton.
|
|
||||||
// This is encoded as a TGBA without acceptance condition.
|
|
||||||
twa_graph_ptr aut;
|
|
||||||
/// Type of the acceptance.
|
|
||||||
dstar_type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef std::shared_ptr<dstar_aut> dstar_aut_ptr;
|
|
||||||
typedef std::shared_ptr<const dstar_aut> const_dstar_aut_ptr;
|
|
||||||
|
|
||||||
/// \brief Build a spot::twa_graph from ltl2dstar's output.
|
|
||||||
/// \param filename The name of the file to parse.
|
/// \param filename The name of the file to parse.
|
||||||
/// \param error_list A list that will be filled with
|
/// \param error_list A list that will be filled with
|
||||||
/// parse errors that occured during parsing.
|
/// parse errors that occured during parsing.
|
||||||
|
|
@ -70,22 +50,12 @@ namespace spot
|
||||||
/// was parsed succesfully, check \a error_list for emptiness.
|
/// was parsed succesfully, check \a error_list for emptiness.
|
||||||
///
|
///
|
||||||
/// \warning This function is not reentrant.
|
/// \warning This function is not reentrant.
|
||||||
SPOT_API dstar_aut_ptr
|
SPOT_API parsed_aut_ptr
|
||||||
dstar_parse(const std::string& filename,
|
dstar_parse(const std::string& filename,
|
||||||
dstar_parse_error_list& error_list,
|
parse_aut_error_list& error_list,
|
||||||
const bdd_dict_ptr& dict,
|
const bdd_dict_ptr& dict,
|
||||||
ltl::environment& env = ltl::default_environment::instance(),
|
ltl::environment& env = ltl::default_environment::instance(),
|
||||||
bool debug = false);
|
bool debug = false);
|
||||||
|
|
||||||
/// \brief Format diagnostics produced by spot::dstar_parse.
|
|
||||||
/// \param os Where diagnostics should be output.
|
|
||||||
/// \param filename The filename that should appear in the diagnostics.
|
|
||||||
/// \param error_list The error list filled by spot::ltl::parse while
|
|
||||||
/// parsing \a ltl_string.
|
|
||||||
/// \return \c true iff any diagnostic was output.
|
|
||||||
SPOT_API bool
|
|
||||||
format_dstar_parse_errors(std::ostream& os,
|
|
||||||
const std::string& filename,
|
|
||||||
dstar_parse_error_list& error_list);
|
|
||||||
/// @}
|
/// @}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -598,7 +598,7 @@ checked_main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
tm.start("reading -P's argument");
|
tm.start("reading -P's argument");
|
||||||
|
|
||||||
spot::dstar_parse_error_list pel;
|
spot::parse_aut_error_list pel;
|
||||||
auto daut = spot::parse_aut(argv[formula_index] + 2, pel,
|
auto daut = spot::parse_aut(argv[formula_index] + 2, pel,
|
||||||
dict, env, debug_opt);
|
dict, env, debug_opt);
|
||||||
if (spot::format_parse_aut_errors(std::cerr,
|
if (spot::format_parse_aut_errors(std::cerr,
|
||||||
|
|
@ -961,11 +961,11 @@ checked_main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
case ReadDstar:
|
case ReadDstar:
|
||||||
{
|
{
|
||||||
spot::dstar_parse_error_list pel;
|
spot::parse_aut_error_list pel;
|
||||||
tm.start("parsing dstar");
|
tm.start("parsing dstar");
|
||||||
auto daut = spot::dstar_parse(input, pel, dict, env, debug_opt);
|
auto daut = spot::dstar_parse(input, pel, dict, env, debug_opt);
|
||||||
tm.stop("parsing dstar");
|
tm.stop("parsing dstar");
|
||||||
if (spot::format_dstar_parse_errors(std::cerr, input, pel))
|
if (spot::format_parse_aut_errors(std::cerr, input, pel))
|
||||||
return 2;
|
return 2;
|
||||||
tm.start("dstar2tgba");
|
tm.start("dstar2tgba");
|
||||||
if (nra2nba)
|
if (nra2nba)
|
||||||
|
|
@ -984,7 +984,7 @@ checked_main(int argc, char** argv)
|
||||||
break;
|
break;
|
||||||
case ReadHoa:
|
case ReadHoa:
|
||||||
{
|
{
|
||||||
spot::dstar_parse_error_list pel;
|
spot::parse_aut_error_list pel;
|
||||||
tm.start("parsing hoa");
|
tm.start("parsing hoa");
|
||||||
auto daut = spot::parse_aut(input, pel, dict, env, debug_opt);
|
auto daut = spot::parse_aut(input, pel, dict, env, debug_opt);
|
||||||
tm.stop("parsing hoa");
|
tm.stop("parsing hoa");
|
||||||
|
|
|
||||||
|
|
@ -57,12 +57,6 @@ $ltlcross -F - -f 'GFa & GFb & GFc' -f '(GFa -> GFb) & (GFc -> GFd)' \
|
||||||
"ltl2dstar $STR --ltl2nba=spin:$ltl2tgba@-s %L - | $dstar2tgba --low -s >%N" \
|
"ltl2dstar $STR --ltl2nba=spin:$ltl2tgba@-s %L - | $dstar2tgba --low -s >%N" \
|
||||||
--csv=out.csv
|
--csv=out.csv
|
||||||
|
|
||||||
grep '"in_type"' out.csv
|
|
||||||
grep '"DSA"' out.csv
|
|
||||||
grep '"DRA"' out.csv
|
|
||||||
grep ',,,,' out.csv
|
|
||||||
|
|
||||||
|
|
||||||
# A bug in ltlcross <=1.2.5 caused it to not use the complement of the
|
# A bug in ltlcross <=1.2.5 caused it to not use the complement of the
|
||||||
# negative automaton. So running ltlcross with GFa would check one
|
# negative automaton. So running ltlcross with GFa would check one
|
||||||
# complement (the positive one), but running with FGa would ignore
|
# complement (the positive one), but running with FGa would ignore
|
||||||
|
|
|
||||||
|
|
@ -138,7 +138,7 @@ echo "$first" > bug.txt
|
||||||
run 1 ../../bin/ltlcross "$ltl2tgba -s %f >%N" 'false %f >%D' \
|
run 1 ../../bin/ltlcross "$ltl2tgba -s %f >%N" 'false %f >%D' \
|
||||||
-f 'X a' --csv=out.csv --save-bogus='>>bug.txt' 2>stderr
|
-f 'X a' --csv=out.csv --save-bogus='>>bug.txt' 2>stderr
|
||||||
q=`sed 's/[^,]//g;q' out.csv | wc -c`
|
q=`sed 's/[^,]//g;q' out.csv | wc -c`
|
||||||
test $q -eq `expr $p + 5`
|
test $q -eq `expr $p - 1`
|
||||||
grep '"exit_status"' out.csv
|
grep '"exit_status"' out.csv
|
||||||
grep '"exit_code"' out.csv
|
grep '"exit_code"' out.csv
|
||||||
test `grep 'error:.*returned exit code 1' stderr | wc -l` -eq 2
|
test `grep 'error:.*returned exit code 1' stderr | wc -l` -eq 2
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue