bin: allow %l to be used to print serial numbers
* NEWS: Mention it. * bin/autfilt.cc, bin/common_aoutput.cc, bin/common_aoutput.hh, bin/common_output.cc, bin/common_output.hh, bin/dstar2tgba.cc, bin/genaut.cc, bin/genltl.cc, bin/ltl2tgba.cc, bin/ltldo.cc, bin/ltlfilt.cc, bin/ltlgrind.cc, bin/randaut.cc, bin/randltl.cc: Implement it. * doc/org/oaut.org: Add a short example. * tests/core/serial.test: New file. * tests/Makefile.am: Add it.
This commit is contained in:
parent
8369663380
commit
61b457a37e
18 changed files with 183 additions and 41 deletions
12
NEWS
12
NEWS
|
|
@ -1,5 +1,17 @@
|
||||||
New in spot 2.11.5.dev (not yet released)
|
New in spot 2.11.5.dev (not yet released)
|
||||||
|
|
||||||
|
Command-line tools:
|
||||||
|
|
||||||
|
- In places that accept format strings with '%' sequences, like
|
||||||
|
options --stats, --name, or --output, the new '%l' can now be used
|
||||||
|
to produce the 0-based serial number of the produced object. This
|
||||||
|
differs from the existing '%L' that is usually related to the line
|
||||||
|
number of the input (when that makes sense). For instance to
|
||||||
|
split a file that contains many automaton into several files, one
|
||||||
|
per automata, do
|
||||||
|
|
||||||
|
autfilt input.hoa -o output-%l.hoa
|
||||||
|
|
||||||
Library:
|
Library:
|
||||||
|
|
||||||
- The following new trivial simplifications have been implemented for SEREs:
|
- The following new trivial simplifications have been implemented for SEREs:
|
||||||
|
|
|
||||||
|
|
@ -1680,8 +1680,6 @@ namespace
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
++match_count;
|
|
||||||
|
|
||||||
if (aliases)
|
if (aliases)
|
||||||
{
|
{
|
||||||
if (opt_aliases)
|
if (opt_aliases)
|
||||||
|
|
@ -1690,7 +1688,9 @@ namespace
|
||||||
set_aliases(aut, {});
|
set_aliases(aut, {});
|
||||||
}
|
}
|
||||||
printer.print(aut, timer, nullptr, haut->filename.c_str(), -1,
|
printer.print(aut, timer, nullptr, haut->filename.c_str(), -1,
|
||||||
haut, prefix, suffix);
|
match_count, haut, prefix, suffix);
|
||||||
|
|
||||||
|
++match_count;
|
||||||
|
|
||||||
if (opt_max_count >= 0 && match_count >= opt_max_count)
|
if (opt_max_count >= 0 && match_count >= opt_max_count)
|
||||||
abort_run = true;
|
abort_run = true;
|
||||||
|
|
|
||||||
|
|
@ -198,6 +198,8 @@ static const argp_option io_options[] =
|
||||||
" minuscules for output):", 4 },
|
" minuscules for output):", 4 },
|
||||||
{ "%F", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE, F_doc, 0 },
|
{ "%F", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE, F_doc, 0 },
|
||||||
{ "%L", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE, L_doc, 0 },
|
{ "%L", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE, L_doc, 0 },
|
||||||
|
{ "%l", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||||
|
"serial number of the output automaton (0-based)", 0 },
|
||||||
{ "%H, %h", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
{ "%H, %h", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||||
"the automaton in HOA format on a single line (use %[opt]H or %[opt]h "
|
"the automaton in HOA format on a single line (use %[opt]H or %[opt]h "
|
||||||
"to specify additional options as in --hoa=opt)", 0 },
|
"to specify additional options as in --hoa=opt)", 0 },
|
||||||
|
|
@ -269,6 +271,8 @@ static const argp_option o_options[] =
|
||||||
"the following interpreted sequences:", 4 },
|
"the following interpreted sequences:", 4 },
|
||||||
{ "%F", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE, F_doc, 0 },
|
{ "%F", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE, F_doc, 0 },
|
||||||
{ "%L", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE, L_doc, 0 },
|
{ "%L", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE, L_doc, 0 },
|
||||||
|
{ "%l", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||||
|
"serial number of the output automaton (0-based)", 0 },
|
||||||
{ "%h", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
{ "%h", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||||
"the automaton in HOA format on a single line (use %[opt]h "
|
"the automaton in HOA format on a single line (use %[opt]h "
|
||||||
"to specify additional options as in --hoa=opt)", 0 },
|
"to specify additional options as in --hoa=opt)", 0 },
|
||||||
|
|
@ -442,6 +446,7 @@ hoa_stat_printer::hoa_stat_printer(std::ostream& os, const char* format,
|
||||||
if (input != ltl_input)
|
if (input != ltl_input)
|
||||||
declare('f', &filename_); // Override the formula printer.
|
declare('f', &filename_); // Override the formula printer.
|
||||||
declare('h', &output_aut_);
|
declare('h', &output_aut_);
|
||||||
|
declare('l', &index_);
|
||||||
declare('m', &aut_name_);
|
declare('m', &aut_name_);
|
||||||
declare('u', &aut_univbranch_);
|
declare('u', &aut_univbranch_);
|
||||||
declare('w', &aut_word_);
|
declare('w', &aut_word_);
|
||||||
|
|
@ -453,11 +458,12 @@ hoa_stat_printer::print(const spot::const_parsed_aut_ptr& haut,
|
||||||
const spot::const_twa_graph_ptr& aut,
|
const spot::const_twa_graph_ptr& aut,
|
||||||
spot::formula f,
|
spot::formula f,
|
||||||
const char* filename, int loc,
|
const char* filename, int loc,
|
||||||
|
unsigned index,
|
||||||
const spot::process_timer& ptimer,
|
const spot::process_timer& ptimer,
|
||||||
const char* csv_prefix, const char* csv_suffix)
|
const char* csv_prefix, const char* csv_suffix)
|
||||||
{
|
{
|
||||||
timer_ = ptimer;
|
timer_ = ptimer;
|
||||||
|
index_ = index;
|
||||||
filename_ = filename ? filename : "";
|
filename_ = filename ? filename : "";
|
||||||
csv_prefix_ = csv_prefix ? csv_prefix : "";
|
csv_prefix_ = csv_prefix ? csv_prefix : "";
|
||||||
csv_suffix_ = csv_suffix ? csv_suffix : "";
|
csv_suffix_ = csv_suffix ? csv_suffix : "";
|
||||||
|
|
@ -599,6 +605,7 @@ automaton_printer::print(const spot::twa_graph_ptr& aut,
|
||||||
// Input location for errors and statistics.
|
// Input location for errors and statistics.
|
||||||
const char* filename,
|
const char* filename,
|
||||||
int loc,
|
int loc,
|
||||||
|
unsigned index,
|
||||||
// input automaton for statistics
|
// input automaton for statistics
|
||||||
const spot::const_parsed_aut_ptr& haut,
|
const spot::const_parsed_aut_ptr& haut,
|
||||||
const char* csv_prefix,
|
const char* csv_prefix,
|
||||||
|
|
@ -622,7 +629,8 @@ automaton_printer::print(const spot::twa_graph_ptr& aut,
|
||||||
if (opt_name)
|
if (opt_name)
|
||||||
{
|
{
|
||||||
name.str("");
|
name.str("");
|
||||||
namer.print(haut, aut, f, filename, loc, ptimer, csv_prefix, csv_suffix);
|
namer.print(haut, aut, f, filename, loc, index,
|
||||||
|
ptimer, csv_prefix, csv_suffix);
|
||||||
aut->set_named_prop("automaton-name", new std::string(name.str()));
|
aut->set_named_prop("automaton-name", new std::string(name.str()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -630,8 +638,8 @@ automaton_printer::print(const spot::twa_graph_ptr& aut,
|
||||||
if (opt_output)
|
if (opt_output)
|
||||||
{
|
{
|
||||||
outputname.str("");
|
outputname.str("");
|
||||||
outputnamer.print(haut, aut, f, filename, loc, ptimer,
|
outputnamer.print(haut, aut, f, filename, loc, index,
|
||||||
csv_prefix, csv_suffix);
|
ptimer, csv_prefix, csv_suffix);
|
||||||
std::string fname = outputname.str();
|
std::string fname = outputname.str();
|
||||||
auto [it, b] = outputfiles.try_emplace(fname, nullptr);
|
auto [it, b] = outputfiles.try_emplace(fname, nullptr);
|
||||||
if (b)
|
if (b)
|
||||||
|
|
@ -660,8 +668,8 @@ automaton_printer::print(const spot::twa_graph_ptr& aut,
|
||||||
break;
|
break;
|
||||||
case Stats:
|
case Stats:
|
||||||
statistics.set_output(*out);
|
statistics.set_output(*out);
|
||||||
statistics.print(haut, aut, f, filename, loc, ptimer,
|
statistics.print(haut, aut, f, filename, loc, index,
|
||||||
csv_prefix, csv_suffix) << '\n';
|
ptimer, csv_prefix, csv_suffix) << '\n';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
flush_cout();
|
flush_cout();
|
||||||
|
|
|
||||||
|
|
@ -133,10 +133,10 @@ public:
|
||||||
void print(std::ostream& os, const char* pos) const override;
|
void print(std::ostream& os, const char* pos) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// \brief prints various statistics about a TGBA
|
/// \brief prints various statistics about a TwA
|
||||||
///
|
///
|
||||||
/// This object can be configured to display various statistics
|
/// This object can be configured to display various statistics
|
||||||
/// about a TGBA. Some %-sequence of characters are interpreted in
|
/// about a TwA. Some %-sequence of characters are interpreted in
|
||||||
/// the format string, and replaced by the corresponding statistics.
|
/// the format string, and replaced by the corresponding statistics.
|
||||||
class hoa_stat_printer: protected spot::stat_printer
|
class hoa_stat_printer: protected spot::stat_printer
|
||||||
{
|
{
|
||||||
|
|
@ -153,10 +153,12 @@ public:
|
||||||
/// to be output.
|
/// to be output.
|
||||||
std::ostream&
|
std::ostream&
|
||||||
print(const spot::const_parsed_aut_ptr& haut,
|
print(const spot::const_parsed_aut_ptr& haut,
|
||||||
const spot::const_twa_graph_ptr& aut,
|
const spot::const_twa_graph_ptr& aut,
|
||||||
spot::formula f,
|
spot::formula f,
|
||||||
const char* filename, int loc, const spot::process_timer& ptimer,
|
const char* filename, int loc,
|
||||||
const char* csv_prefix, const char* csv_suffix);
|
unsigned index,
|
||||||
|
const spot::process_timer& ptimer,
|
||||||
|
const char* csv_prefix, const char* csv_suffix);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
spot::printable_value<const char*> filename_;
|
spot::printable_value<const char*> filename_;
|
||||||
|
|
@ -165,6 +167,7 @@ private:
|
||||||
spot::printable_value<std::string> aut_name_;
|
spot::printable_value<std::string> aut_name_;
|
||||||
spot::printable_value<std::string> aut_word_;
|
spot::printable_value<std::string> aut_word_;
|
||||||
spot::printable_value<std::string> haut_word_;
|
spot::printable_value<std::string> haut_word_;
|
||||||
|
spot::printable_value<unsigned> index_;
|
||||||
spot::printable_acc_cond haut_gen_acc_;
|
spot::printable_acc_cond haut_gen_acc_;
|
||||||
spot::printable_size haut_states_;
|
spot::printable_size haut_states_;
|
||||||
spot::printable_size haut_edges_;
|
spot::printable_size haut_edges_;
|
||||||
|
|
@ -206,6 +209,8 @@ public:
|
||||||
// Input location for errors and statistics.
|
// Input location for errors and statistics.
|
||||||
const char* filename = nullptr,
|
const char* filename = nullptr,
|
||||||
int loc = -1,
|
int loc = -1,
|
||||||
|
// serial numbner
|
||||||
|
unsigned index = 0,
|
||||||
// Time and input automaton for statistics
|
// Time and input automaton for statistics
|
||||||
const spot::const_parsed_aut_ptr& haut = nullptr,
|
const spot::const_parsed_aut_ptr& haut = nullptr,
|
||||||
const char* csv_prefix = nullptr,
|
const char* csv_prefix = nullptr,
|
||||||
|
|
|
||||||
|
|
@ -160,6 +160,7 @@ namespace
|
||||||
spot::formula f;
|
spot::formula f;
|
||||||
const char* filename;
|
const char* filename;
|
||||||
const char* line;
|
const char* line;
|
||||||
|
unsigned index;
|
||||||
const char* prefix;
|
const char* prefix;
|
||||||
const char* suffix;
|
const char* suffix;
|
||||||
};
|
};
|
||||||
|
|
@ -237,6 +238,7 @@ namespace
|
||||||
declare('R', &timer_);
|
declare('R', &timer_);
|
||||||
declare('r', &timer_);
|
declare('r', &timer_);
|
||||||
declare('L', &line_);
|
declare('L', &line_);
|
||||||
|
declare('l', &index_);
|
||||||
declare('s', &size_);
|
declare('s', &size_);
|
||||||
declare('h', &class_);
|
declare('h', &class_);
|
||||||
declare('n', &nesting_);
|
declare('n', &nesting_);
|
||||||
|
|
@ -248,7 +250,8 @@ namespace
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream&
|
std::ostream&
|
||||||
print(const formula_with_location& fl, spot::process_timer* ptimer)
|
print(const formula_with_location& fl,
|
||||||
|
spot::process_timer* ptimer)
|
||||||
{
|
{
|
||||||
if (has('R') || has('r'))
|
if (has('R') || has('r'))
|
||||||
timer_ = *ptimer;
|
timer_ = *ptimer;
|
||||||
|
|
@ -256,6 +259,7 @@ namespace
|
||||||
fl_ = &fl;
|
fl_ = &fl;
|
||||||
filename_ = fl.filename ? fl.filename : "";
|
filename_ = fl.filename ? fl.filename : "";
|
||||||
line_ = fl.line;
|
line_ = fl.line;
|
||||||
|
index_ = fl.index;
|
||||||
prefix_ = fl.prefix ? fl.prefix : "";
|
prefix_ = fl.prefix ? fl.prefix : "";
|
||||||
suffix_ = fl.suffix ? fl.suffix : "";
|
suffix_ = fl.suffix ? fl.suffix : "";
|
||||||
auto f = fl_.val()->f;
|
auto f = fl_.val()->f;
|
||||||
|
|
@ -288,6 +292,7 @@ namespace
|
||||||
printable_timer timer_;
|
printable_timer timer_;
|
||||||
spot::printable_value<const char*> filename_;
|
spot::printable_value<const char*> filename_;
|
||||||
spot::printable_value<const char*> line_;
|
spot::printable_value<const char*> line_;
|
||||||
|
spot::printable_value<unsigned> index_;
|
||||||
spot::printable_value<const char*> prefix_;
|
spot::printable_value<const char*> prefix_;
|
||||||
spot::printable_value<const char*> suffix_;
|
spot::printable_value<const char*> suffix_;
|
||||||
spot::printable_value<int> size_;
|
spot::printable_value<int> size_;
|
||||||
|
|
@ -356,6 +361,7 @@ static void
|
||||||
output_formula(std::ostream& out,
|
output_formula(std::ostream& out,
|
||||||
spot::formula f, spot::process_timer* ptimer,
|
spot::formula f, spot::process_timer* ptimer,
|
||||||
const char* filename, const char* linenum,
|
const char* filename, const char* linenum,
|
||||||
|
unsigned index,
|
||||||
const char* prefix, const char* suffix)
|
const char* prefix, const char* suffix)
|
||||||
{
|
{
|
||||||
if (!format)
|
if (!format)
|
||||||
|
|
@ -391,7 +397,8 @@ output_formula(std::ostream& out,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
formula_with_location fl = { f, filename, linenum, prefix, suffix };
|
formula_with_location fl = { f, filename, linenum,
|
||||||
|
index, prefix, suffix };
|
||||||
format->print(fl, ptimer);
|
format->print(fl, ptimer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -399,6 +406,7 @@ output_formula(std::ostream& out,
|
||||||
void
|
void
|
||||||
output_formula_checked(spot::formula f, spot::process_timer* ptimer,
|
output_formula_checked(spot::formula f, spot::process_timer* ptimer,
|
||||||
const char* filename, const char* linenum,
|
const char* filename, const char* linenum,
|
||||||
|
unsigned index,
|
||||||
const char* prefix, const char* suffix)
|
const char* prefix, const char* suffix)
|
||||||
{
|
{
|
||||||
if (output_format == count_output)
|
if (output_format == count_output)
|
||||||
|
|
@ -414,7 +422,8 @@ output_formula_checked(spot::formula f, spot::process_timer* ptimer,
|
||||||
if (outputnamer)
|
if (outputnamer)
|
||||||
{
|
{
|
||||||
outputname.str("");
|
outputname.str("");
|
||||||
formula_with_location fl = { f, filename, linenum, prefix, suffix };
|
formula_with_location fl = { f, filename, linenum,
|
||||||
|
index, prefix, suffix };
|
||||||
outputnamer->print(fl, ptimer);
|
outputnamer->print(fl, ptimer);
|
||||||
std::string fname = outputname.str();
|
std::string fname = outputname.str();
|
||||||
auto [it, b] = outputfiles.try_emplace(fname, nullptr);
|
auto [it, b] = outputfiles.try_emplace(fname, nullptr);
|
||||||
|
|
@ -422,7 +431,7 @@ output_formula_checked(spot::formula f, spot::process_timer* ptimer,
|
||||||
it->second.reset(new output_file(fname.c_str()));
|
it->second.reset(new output_file(fname.c_str()));
|
||||||
out = &it->second->ostream();
|
out = &it->second->ostream();
|
||||||
}
|
}
|
||||||
output_formula(*out, f, ptimer, filename, linenum, prefix, suffix);
|
output_formula(*out, f, ptimer, filename, linenum, index, prefix, suffix);
|
||||||
*out << output_terminator;
|
*out << output_terminator;
|
||||||
// Make sure we abort if we can't write to std::cout anymore
|
// Make sure we abort if we can't write to std::cout anymore
|
||||||
// (like disk full or broken pipe with SIGPIPE ignored).
|
// (like disk full or broken pipe with SIGPIPE ignored).
|
||||||
|
|
@ -432,10 +441,12 @@ output_formula_checked(spot::formula f, spot::process_timer* ptimer,
|
||||||
void output_formula_checked(spot::formula f,
|
void output_formula_checked(spot::formula f,
|
||||||
spot::process_timer* ptimer,
|
spot::process_timer* ptimer,
|
||||||
const char* filename, int linenum,
|
const char* filename, int linenum,
|
||||||
|
unsigned index,
|
||||||
const char* prefix,
|
const char* prefix,
|
||||||
const char* suffix)
|
const char* suffix)
|
||||||
{
|
{
|
||||||
output_formula_checked(f, ptimer, filename,
|
output_formula_checked(f, ptimer, filename,
|
||||||
std::to_string(linenum).c_str(),
|
std::to_string(linenum).c_str(),
|
||||||
|
index,
|
||||||
prefix, suffix);
|
prefix, suffix);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2012-2018 Laboratoire de Recherche et Développement
|
// Copyright (C) 2012-2018, 2023 Laboratoire de Recherche et Développement
|
||||||
// de l'Epita (LRDE).
|
// de l'Epita (LRDE).
|
||||||
//
|
//
|
||||||
// This file is part of Spot, a model checking library.
|
// This file is part of Spot, a model checking library.
|
||||||
|
|
@ -81,11 +81,13 @@ void output_formula_checked(spot::formula f,
|
||||||
spot::process_timer* ptimer = nullptr,
|
spot::process_timer* ptimer = nullptr,
|
||||||
const char* filename = nullptr,
|
const char* filename = nullptr,
|
||||||
const char* linenum = nullptr,
|
const char* linenum = nullptr,
|
||||||
|
unsigned output_index = 0U,
|
||||||
const char* prefix = nullptr,
|
const char* prefix = nullptr,
|
||||||
const char* suffix = nullptr);
|
const char* suffix = nullptr);
|
||||||
|
|
||||||
void output_formula_checked(spot::formula f,
|
void output_formula_checked(spot::formula f,
|
||||||
spot::process_timer* ptimer,
|
spot::process_timer* ptimer,
|
||||||
const char* filename, int linenum,
|
const char* filename, int linenum,
|
||||||
|
unsigned output_index,
|
||||||
const char* prefix = nullptr,
|
const char* prefix = nullptr,
|
||||||
const char* suffix = nullptr);
|
const char* suffix = nullptr);
|
||||||
|
|
|
||||||
|
|
@ -129,7 +129,9 @@ namespace
|
||||||
timer.start();
|
timer.start();
|
||||||
auto aut = post.run(haut->aut, nullptr);
|
auto aut = post.run(haut->aut, nullptr);
|
||||||
timer.stop();
|
timer.stop();
|
||||||
printer.print(aut, timer, nullptr, haut->filename.c_str(), -1, haut);
|
static unsigned index = 0;
|
||||||
|
printer.print(aut, timer, nullptr, haut->filename.c_str(), -1,
|
||||||
|
index++, haut);
|
||||||
flush_cout();
|
flush_cout();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -122,7 +122,8 @@ output_pattern(gen::aut_pattern_id pattern, int n)
|
||||||
twa_graph_ptr aut = spot::gen::aut_pattern(pattern, n);
|
twa_graph_ptr aut = spot::gen::aut_pattern(pattern, n);
|
||||||
timer.stop();
|
timer.stop();
|
||||||
automaton_printer printer;
|
automaton_printer printer;
|
||||||
printer.print(aut, timer, nullptr, aut_pattern_name(pattern), n);
|
static unsigned serial = 0;
|
||||||
|
printer.print(aut, timer, nullptr, aut_pattern_name(pattern), n, serial++);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
||||||
|
|
@ -192,6 +192,8 @@ static const argp_option options[] =
|
||||||
"the formula (in the selected syntax)", 0 },
|
"the formula (in the selected syntax)", 0 },
|
||||||
{ "%F", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
{ "%F", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||||
"the name of the pattern", 0 },
|
"the name of the pattern", 0 },
|
||||||
|
{ "%l", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||||
|
"serial number of the output formula (0-based)", 0 },
|
||||||
{ "%L", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
{ "%L", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||||
"the argument of the pattern", 0 },
|
"the argument of the pattern", 0 },
|
||||||
{ "%%", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
{ "%%", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||||
|
|
@ -287,6 +289,8 @@ parse_opt(int key, char* arg, struct argp_state*)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static unsigned output_count = 0U;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
output_pattern(gen::ltl_pattern_id pattern, int n, int n2)
|
output_pattern(gen::ltl_pattern_id pattern, int n, int n2)
|
||||||
{
|
{
|
||||||
|
|
@ -303,14 +307,14 @@ output_pattern(gen::ltl_pattern_id pattern, int n, int n2)
|
||||||
if (opt_positive || !opt_negative)
|
if (opt_positive || !opt_negative)
|
||||||
{
|
{
|
||||||
output_formula_checked(f, nullptr, gen::ltl_pattern_name(pattern),
|
output_formula_checked(f, nullptr, gen::ltl_pattern_name(pattern),
|
||||||
args.c_str());
|
args.c_str(), output_count++);
|
||||||
}
|
}
|
||||||
if (opt_negative)
|
if (opt_negative)
|
||||||
{
|
{
|
||||||
std::string tmp = "!";
|
std::string tmp = "!";
|
||||||
tmp += gen::ltl_pattern_name(pattern);
|
tmp += gen::ltl_pattern_name(pattern);
|
||||||
output_formula_checked(formula::Not(f), nullptr, tmp.c_str(),
|
output_formula_checked(formula::Not(f), nullptr, tmp.c_str(),
|
||||||
args.c_str());
|
args.c_str(), output_count++);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -155,8 +155,9 @@ namespace
|
||||||
auto aut = trans.run(&f);
|
auto aut = trans.run(&f);
|
||||||
timer.stop();
|
timer.stop();
|
||||||
|
|
||||||
printer.print(aut, timer, f, filename, linenum, nullptr,
|
static unsigned index = 0;
|
||||||
prefix, suffix);
|
printer.print(aut, timer, f, filename, linenum, index++,
|
||||||
|
nullptr, prefix, suffix);
|
||||||
// If we keep simplification caches around, atomic propositions
|
// If we keep simplification caches around, atomic propositions
|
||||||
// will still be defined, and one translation may influence the
|
// will still be defined, and one translation may influence the
|
||||||
// variable order of the next one.
|
// variable order of the next one.
|
||||||
|
|
|
||||||
|
|
@ -360,8 +360,7 @@ namespace
|
||||||
const char* csv_prefix, const char* csv_suffix)
|
const char* csv_prefix, const char* csv_suffix)
|
||||||
{
|
{
|
||||||
static long int output_count = 0;
|
static long int output_count = 0;
|
||||||
++output_count;
|
printer.print(aut, ptimer, f, filename, loc, output_count++, nullptr,
|
||||||
printer.print(aut, ptimer, f, filename, loc, nullptr,
|
|
||||||
csv_prefix, csv_suffix);
|
csv_prefix, csv_suffix);
|
||||||
if (opt_max_count >= 0 && output_count >= opt_max_count)
|
if (opt_max_count >= 0 && output_count >= opt_max_count)
|
||||||
abort_run = true;
|
abort_run = true;
|
||||||
|
|
@ -420,8 +419,8 @@ namespace
|
||||||
aut = post.run(aut, f);
|
aut = post.run(aut, f);
|
||||||
if (best_type)
|
if (best_type)
|
||||||
{
|
{
|
||||||
best_printer.print(nullptr, aut, f, filename, linenum, timer,
|
best_printer.print(nullptr, aut, f, filename, linenum, 0,
|
||||||
prefix, suffix);
|
timer, prefix, suffix);
|
||||||
std::string aut_stats = best_stream.str();
|
std::string aut_stats = best_stream.str();
|
||||||
if (!best_aut ||
|
if (!best_aut ||
|
||||||
(strverscmp(best_stats.c_str(), aut_stats.c_str())
|
(strverscmp(best_stats.c_str(), aut_stats.c_str())
|
||||||
|
|
|
||||||
|
|
@ -254,6 +254,8 @@ static const argp_option options[] =
|
||||||
"the formula (in the selected syntax)", 0 },
|
"the formula (in the selected syntax)", 0 },
|
||||||
{ "%F", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
{ "%F", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||||
"the name of the input file", 0 },
|
"the name of the input file", 0 },
|
||||||
|
{ "%l", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||||
|
"the serial number of the output formula", 0 },
|
||||||
{ "%L", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
{ "%L", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||||
"the original line number in the input file", 0 },
|
"the original line number in the input file", 0 },
|
||||||
{ "%r", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
{ "%r", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||||
|
|
@ -852,7 +854,8 @@ namespace
|
||||||
std::to_string(linenum).c_str()) << ")\n";
|
std::to_string(linenum).c_str()) << ")\n";
|
||||||
}
|
}
|
||||||
one_match = true;
|
one_match = true;
|
||||||
output_formula_checked(f, &timer, filename, linenum, prefix, suffix);
|
output_formula_checked(f, &timer, filename, linenum,
|
||||||
|
match_count, prefix, suffix);
|
||||||
++match_count;
|
++match_count;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2014-2019, 2022 Laboratoire de Recherche et
|
// Copyright (C) 2014-2019, 2022, 2023 Laboratoire de Recherche et
|
||||||
// Développement de l'Epita (LRDE).
|
// Développement de l'Epita (LRDE).
|
||||||
//
|
//
|
||||||
// This file is part of Spot, a model checking library.
|
// This file is part of Spot, a model checking library.
|
||||||
|
|
@ -87,6 +87,8 @@ static const argp_option options[] = {
|
||||||
"the formula (in the selected syntax)", 0 },
|
"the formula (in the selected syntax)", 0 },
|
||||||
{ "%F", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
{ "%F", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||||
"the name of the input file", 0 },
|
"the name of the input file", 0 },
|
||||||
|
{ "%l", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||||
|
"the serial number of the output formula (0-based)", 0 },
|
||||||
{ "%L", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
{ "%L", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||||
"the original line number in the input file", 0 },
|
"the original line number in the input file", 0 },
|
||||||
{ "%<", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
{ "%<", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||||
|
|
@ -112,6 +114,8 @@ static const argp_child children[] = {
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
static unsigned output_count = 0;
|
||||||
|
|
||||||
class mutate_processor final: public job_processor
|
class mutate_processor final: public job_processor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
@ -122,7 +126,8 @@ namespace
|
||||||
auto mutations =
|
auto mutations =
|
||||||
spot::mutate(f, mut_opts, max_output, mutation_nb, opt_sort);
|
spot::mutate(f, mut_opts, max_output, mutation_nb, opt_sort);
|
||||||
for (auto g: mutations)
|
for (auto g: mutations)
|
||||||
output_formula_checked(g, nullptr, filename, linenum, prefix, suffix);
|
output_formula_checked(g, nullptr, filename, linenum,
|
||||||
|
output_count++, prefix, suffix);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2012-2016, 2018-2020, 2022 Laboratoire de Recherche
|
// Copyright (C) 2012-2016, 2018-2020, 2022, 2023 Laboratoire de Recherche
|
||||||
// et Développement de l'Epita (LRDE).
|
// et Développement de l'Epita (LRDE).
|
||||||
//
|
//
|
||||||
// This file is part of Spot, a model checking library.
|
// This file is part of Spot, a model checking library.
|
||||||
|
|
@ -406,7 +406,8 @@ main(int argc, char** argv)
|
||||||
timer.stop();
|
timer.stop();
|
||||||
|
|
||||||
printer.print(aut, timer, nullptr,
|
printer.print(aut, timer, nullptr,
|
||||||
opt_seed_str, automaton_num, nullptr);
|
opt_seed_str, automaton_num,
|
||||||
|
automaton_num, nullptr);
|
||||||
|
|
||||||
++automaton_num;
|
++automaton_num;
|
||||||
if (opt_automata > 0 && automaton_num >= opt_automata)
|
if (opt_automata > 0 && automaton_num >= opt_automata)
|
||||||
|
|
|
||||||
|
|
@ -115,8 +115,10 @@ static const argp_option options[] =
|
||||||
"the following interpreted sequences:", -19 },
|
"the following interpreted sequences:", -19 },
|
||||||
{ "%f", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
{ "%f", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||||
"the formula (in the selected syntax)", 0 },
|
"the formula (in the selected syntax)", 0 },
|
||||||
|
{ "%l", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||||
|
"the (serial) number of the formula (0-based)", 0 },
|
||||||
{ "%L", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
{ "%L", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||||
"the (serial) number of the formula", 0 },
|
"the (serial) number of the formula (1-based)", 0 },
|
||||||
{ "%%", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
{ "%%", 0, nullptr, OPTION_DOC | OPTION_NO_USAGE,
|
||||||
"a single %", 0 },
|
"a single %", 0 },
|
||||||
COMMON_LTL_OUTPUT_SPECS,
|
COMMON_LTL_OUTPUT_SPECS,
|
||||||
|
|
@ -305,9 +307,9 @@ main(int argc, char** argv)
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int count = 0;
|
||||||
while (opt_formulas < 0 || opt_formulas--)
|
while (opt_formulas < 0 || opt_formulas--)
|
||||||
{
|
{
|
||||||
static int count = 0;
|
|
||||||
spot::formula f = rg.next();
|
spot::formula f = rg.next();
|
||||||
if (!f)
|
if (!f)
|
||||||
{
|
{
|
||||||
|
|
@ -316,7 +318,8 @@ main(int argc, char** argv)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
output_formula_checked(f, nullptr, nullptr, ++count);
|
output_formula_checked(f, nullptr, nullptr, count + 1, count);
|
||||||
|
++count;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
flush_cout();
|
flush_cout();
|
||||||
|
|
|
||||||
|
|
@ -725,7 +725,8 @@ randaut --help | sed -n '/ sequences:/,/^$/p' | sed '1d;$d'
|
||||||
(iw) inherently weak. Use uppercase letters to
|
(iw) inherently weak. Use uppercase letters to
|
||||||
negate them.
|
negate them.
|
||||||
%d 1 if the output is deterministic, 0 otherwise
|
%d 1 if the output is deterministic, 0 otherwise
|
||||||
%e number of reachable edges
|
%e, %[LETTER]e number of edges (add one LETTER to select (r)
|
||||||
|
reachable [default], (u) unreachable, (a) all).
|
||||||
%F seed number
|
%F seed number
|
||||||
%g, %[LETTERS]g acceptance condition (in HOA syntax); add brackets
|
%g, %[LETTERS]g acceptance condition (in HOA syntax); add brackets
|
||||||
to print an acceptance name instead and LETTERS to
|
to print an acceptance name instead and LETTERS to
|
||||||
|
|
@ -740,6 +741,7 @@ randaut --help | sed -n '/ sequences:/,/^$/p' | sed '1d;$d'
|
||||||
%[opt]h to specify additional options as in
|
%[opt]h to specify additional options as in
|
||||||
--hoa=opt)
|
--hoa=opt)
|
||||||
%L automaton number
|
%L automaton number
|
||||||
|
%l serial number of the output automaton (0-based)
|
||||||
%m name of the automaton
|
%m name of the automaton
|
||||||
%n number of nondeterministic states in output
|
%n number of nondeterministic states in output
|
||||||
%p 1 if the output is complete, 0 otherwise
|
%p 1 if the output is complete, 0 otherwise
|
||||||
|
|
@ -749,8 +751,11 @@ randaut --help | sed -n '/ sequences:/,/^$/p' | sed '1d;$d'
|
||||||
LETTERS to restrict to(u) user time, (s) system
|
LETTERS to restrict to(u) user time, (s) system
|
||||||
time, (p) parent process, or (c) children
|
time, (p) parent process, or (c) children
|
||||||
processes.
|
processes.
|
||||||
%s number of reachable states
|
%s, %[LETTER]s number of states (add one LETTER to select (r)
|
||||||
%t number of reachable transitions
|
reachable [default], (u) unreachable, (a) all).
|
||||||
|
%t, %[LETTER]t number of transitions (add one LETTER to select
|
||||||
|
(r) reachable [default], (u) unreachable, (a)
|
||||||
|
all).
|
||||||
%u, %[e]u number of states (or [e]dges) with universal
|
%u, %[e]u number of states (or [e]dges) with universal
|
||||||
branching
|
branching
|
||||||
%u, %[LETTER]u 1 if the automaton contains some universal
|
%u, %[LETTER]u 1 if the automaton contains some universal
|
||||||
|
|
@ -996,6 +1001,14 @@ randaut -D -n 20 -Q2 1 -o '>>out-det%d.hoa'
|
||||||
|
|
||||||
(You need the quotes so that the shell does not interpret =>>=.)
|
(You need the quotes so that the shell does not interpret =>>=.)
|
||||||
|
|
||||||
|
The =%l= sequence is a number that is incremented for each output
|
||||||
|
automaton. For instance if =input.hoa= contains multiple automata,
|
||||||
|
you can separate them into separate files with:
|
||||||
|
|
||||||
|
#+BEGIN_SRC sh :exports code
|
||||||
|
autilt input.hoa -o output-%l.hoa
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
#+BEGIN_SRC sh :results silent :exports results
|
#+BEGIN_SRC sh :results silent :exports results
|
||||||
rm -f out-det0.hoa out-det1.hoa
|
rm -f out-det0.hoa out-det1.hoa
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
|
||||||
|
|
@ -230,6 +230,7 @@ TESTS_twa = \
|
||||||
core/cube.test \
|
core/cube.test \
|
||||||
core/alternating.test \
|
core/alternating.test \
|
||||||
core/gamehoa.test \
|
core/gamehoa.test \
|
||||||
|
core/serial.test \
|
||||||
core/ltlcross3.test \
|
core/ltlcross3.test \
|
||||||
core/ltlcross5.test \
|
core/ltlcross5.test \
|
||||||
core/taatgba.test \
|
core/taatgba.test \
|
||||||
|
|
|
||||||
71
tests/core/serial.test
Executable file
71
tests/core/serial.test
Executable file
|
|
@ -0,0 +1,71 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright (C) 2023 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/>.
|
||||||
|
|
||||||
|
. ./defs
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# all tools should be able to use %l as serial number for their output
|
||||||
|
|
||||||
|
# Make sure serial numbers count the output automata
|
||||||
|
randaut -n10 --name='aut %l' 2 |
|
||||||
|
autfilt -N3..5 --name='%M/out %l' |
|
||||||
|
autfilt --stats=%M >out
|
||||||
|
cat >exp <<EOF
|
||||||
|
aut 2/out 0
|
||||||
|
aut 3/out 1
|
||||||
|
aut 4/out 2
|
||||||
|
EOF
|
||||||
|
diff out exp
|
||||||
|
|
||||||
|
# Create different files
|
||||||
|
randaut -n3 2 -oaut-%l.hoa
|
||||||
|
test -f aut-0.hoa
|
||||||
|
test -f aut-1.hoa
|
||||||
|
test -f aut-2.hoa
|
||||||
|
|
||||||
|
# Split an output
|
||||||
|
cat aut-0.hoa aut-1.hoa aut-2.hoa > aut.hoa
|
||||||
|
rm aut-?.hoa
|
||||||
|
autfilt aut.hoa -o aut-%l.hoa
|
||||||
|
|
||||||
|
# check serial output in various tools
|
||||||
|
genaut --m-nba=2..3 --name='%F=%L/%l' | autfilt --stats=%M >out
|
||||||
|
genltl --and-f=2..3 --stats=%F=%L/%l >> out
|
||||||
|
ltl2tgba a b --name=%f/%l | autfilt --stats=%M >> out
|
||||||
|
ltldo -f a -f b ltl2tgba --name=%f/%l | autfilt --stats=%M >> out
|
||||||
|
genltl --or-g=2..5 --stats=%L,%l,%f |
|
||||||
|
ltlfilt -F -/3 -N 2..3 --stats='%<,%l' >>out
|
||||||
|
randltl -n10 3 --stats=%l,%f |
|
||||||
|
ltlfilt -F -/2 -N 2..3 --stats='%<,%l' >> out
|
||||||
|
cat >exp<<EOF
|
||||||
|
m-nba=2/0
|
||||||
|
m-nba=3/1
|
||||||
|
and-f=2/0
|
||||||
|
and-f=3/1
|
||||||
|
a/0
|
||||||
|
b/1
|
||||||
|
a/0
|
||||||
|
b/1
|
||||||
|
3,1,0
|
||||||
|
4,2,1
|
||||||
|
1,0
|
||||||
|
2,1
|
||||||
|
EOF
|
||||||
|
diff -u out exp
|
||||||
Loading…
Add table
Add a link
Reference in a new issue