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:
Alexandre Duret-Lutz 2015-08-20 22:33:25 +02:00
parent 62f5b9769b
commit f831f729e1
14 changed files with 61 additions and 231 deletions

View file

@ -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.

View file

@ -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);

View file

@ -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";

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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;
} }
} }

View file

@ -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;
} }

View file

@ -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;
}
}

View file

@ -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

View file

@ -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);
/// @} /// @}
} }

View file

@ -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");

View file

@ -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

View file

@ -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