genltl: add support for --sejk-f=n,m
Together with the previous patch, this Fixes #353. Implementing this required to extend our interface two support two-parameter patterns. * spot/gen/formulas.cc, spot/gen/formulas.hh: Implement it. * bin/genltl.cc: Add --sejk-f. * bin/common_output.cc, bin/common_output.hh: Adjust to handle "line numbers" that are not integers (e.g., "3,2"), since those are used to display pattern parameters. * bin/ltlfilt.cc: Adjust. * python/spot/gen.i: Add support for two-parameters patterns. * tests/core/genltl.test, tests/python/gen.ipynb: Augment. * NEWS: Mention it.
This commit is contained in:
parent
c76df95c69
commit
939f63eec9
10 changed files with 462 additions and 53 deletions
|
|
@ -78,20 +78,21 @@ const struct argp output_argp = { options, parse_opt_output,
|
|||
static
|
||||
void
|
||||
report_not_ltl(spot::formula f,
|
||||
const char* filename, int linenum, const char* syn)
|
||||
const char* filename, const char* linenum, const char* syn)
|
||||
{
|
||||
std::string s = spot::str_psl(f);
|
||||
static const char msg[] =
|
||||
"formula '%s' cannot be written %s's syntax because it is not LTL";
|
||||
if (filename)
|
||||
error_at_line(2, 0, filename, linenum, msg, s.c_str(), syn);
|
||||
error_at_line(2, 0, filename, atoi(linenum), msg, s.c_str(), syn);
|
||||
else
|
||||
error(2, 0, msg, s.c_str(), syn);
|
||||
}
|
||||
|
||||
std::ostream&
|
||||
stream_formula(std::ostream& out,
|
||||
spot::formula f, const char* filename, int linenum)
|
||||
spot::formula f, const char* filename,
|
||||
const char* linenum)
|
||||
{
|
||||
switch (output_format)
|
||||
{
|
||||
|
|
@ -132,7 +133,8 @@ stream_formula(std::ostream& out,
|
|||
static void
|
||||
stream_escapable_formula(std::ostream& os,
|
||||
spot::formula f,
|
||||
const char* filename, int linenum)
|
||||
const char* filename,
|
||||
const char* linenum)
|
||||
{
|
||||
if (escape_csv)
|
||||
{
|
||||
|
|
@ -155,7 +157,7 @@ namespace
|
|||
{
|
||||
spot::formula f;
|
||||
const char* filename;
|
||||
int line;
|
||||
const char* line;
|
||||
const char* prefix;
|
||||
const char* suffix;
|
||||
};
|
||||
|
|
@ -283,7 +285,7 @@ namespace
|
|||
printable_formula_with_location fl_;
|
||||
printable_timer timer_;
|
||||
spot::printable_value<const char*> filename_;
|
||||
spot::printable_value<int> line_;
|
||||
spot::printable_value<const char*> line_;
|
||||
spot::printable_value<const char*> prefix_;
|
||||
spot::printable_value<const char*> suffix_;
|
||||
spot::printable_value<int> size_;
|
||||
|
|
@ -348,9 +350,9 @@ parse_opt_output(int key, char* arg, struct argp_state*)
|
|||
|
||||
static void
|
||||
output_formula(std::ostream& out,
|
||||
spot::formula f, spot::process_timer* ptimer = nullptr,
|
||||
const char* filename = nullptr, int linenum = 0,
|
||||
const char* prefix = nullptr, const char* suffix = nullptr)
|
||||
spot::formula f, spot::process_timer* ptimer,
|
||||
const char* filename, const char* linenum,
|
||||
const char* prefix, const char* suffix)
|
||||
{
|
||||
if (!format)
|
||||
{
|
||||
|
|
@ -392,7 +394,7 @@ output_formula(std::ostream& out,
|
|||
|
||||
void
|
||||
output_formula_checked(spot::formula f, spot::process_timer* ptimer,
|
||||
const char* filename, int linenum,
|
||||
const char* filename, const char* linenum,
|
||||
const char* prefix, const char* suffix)
|
||||
{
|
||||
if (output_format == count_output)
|
||||
|
|
@ -422,3 +424,14 @@ output_formula_checked(spot::formula f, spot::process_timer* ptimer,
|
|||
// (like disk full or broken pipe with SIGPIPE ignored).
|
||||
check_cout();
|
||||
}
|
||||
|
||||
void output_formula_checked(spot::formula f,
|
||||
spot::process_timer* ptimer,
|
||||
const char* filename, int linenum,
|
||||
const char* prefix,
|
||||
const char* suffix)
|
||||
{
|
||||
output_formula_checked(f, ptimer, filename,
|
||||
std::to_string(linenum).c_str(),
|
||||
prefix, suffix);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,10 +75,17 @@ int parse_opt_output(int key, char* arg, struct argp_state* state);
|
|||
// Low-level output
|
||||
std::ostream&
|
||||
stream_formula(std::ostream& out,
|
||||
spot::formula f, const char* filename, int linenum);
|
||||
spot::formula f, const char* filename, const char* linenum);
|
||||
|
||||
void output_formula_checked(spot::formula f,
|
||||
spot::process_timer* ptimer = nullptr,
|
||||
const char* filename = nullptr, int linenum = 0,
|
||||
const char* filename = nullptr,
|
||||
const char* linenum = nullptr,
|
||||
const char* prefix = nullptr,
|
||||
const char* suffix = nullptr);
|
||||
|
||||
void output_formula_checked(spot::formula f,
|
||||
spot::process_timer* ptimer,
|
||||
const char* filename, int linenum,
|
||||
const char* prefix = nullptr,
|
||||
const char* suffix = nullptr);
|
||||
|
|
|
|||
|
|
@ -141,6 +141,8 @@ static const argp_option options[] =
|
|||
{ "sb-patterns", gen::LTL_SB_PATTERNS, "RANGE", OPTION_ARG_OPTIONAL,
|
||||
"Somenzi and Bloem [CAV'00] patterns "
|
||||
"(range should be included in 1..27)", 0 },
|
||||
{ "sejk-f", gen::LTL_SEJK_F, "RANGE[,RANGE]", 0,
|
||||
"f(0,j)=(GFa0 U X^j(b)), f(i,j)=(GFai U G(f(i-1,j)))", 0 },
|
||||
{ "sejk-j", gen::LTL_SEJK_J, "RANGE", 0,
|
||||
"(GFa1&...&GFan) -> (GFb1&...&GFbn)", 0 },
|
||||
{ "sejk-k", gen::LTL_SEJK_K, "RANGE", 0,
|
||||
|
|
@ -192,6 +194,7 @@ struct job
|
|||
{
|
||||
gen::ltl_pattern_id pattern;
|
||||
struct range range;
|
||||
struct range range2;
|
||||
};
|
||||
|
||||
typedef std::vector<job> jobs_t;
|
||||
|
|
@ -211,9 +214,28 @@ enqueue_job(int pattern, const char* range_str = nullptr)
|
|||
{
|
||||
job j;
|
||||
j.pattern = static_cast<gen::ltl_pattern_id>(pattern);
|
||||
j.range2.min = -1;
|
||||
j.range2.max = -1;
|
||||
if (range_str)
|
||||
{
|
||||
j.range = parse_range(range_str);
|
||||
if (gen::ltl_pattern_argc(j.pattern) == 2)
|
||||
{
|
||||
const char* comma = strchr(range_str, ',');
|
||||
if (!comma)
|
||||
{
|
||||
j.range2 = j.range = parse_range(range_str);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string range1(range_str, comma);
|
||||
j.range = parse_range(range1.c_str());
|
||||
j.range2 = parse_range(comma + 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
j.range = parse_range(range_str);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -251,24 +273,29 @@ parse_opt(int key, char* arg, struct argp_state*)
|
|||
|
||||
|
||||
static void
|
||||
output_pattern(gen::ltl_pattern_id pattern, int n)
|
||||
output_pattern(gen::ltl_pattern_id pattern, int n, int n2)
|
||||
{
|
||||
formula f = gen::ltl_pattern(pattern, n);
|
||||
formula f = gen::ltl_pattern(pattern, n, n2);
|
||||
|
||||
// Make sure we use only "p42"-style of atomic propositions
|
||||
// in lbt's output.
|
||||
if (output_format == lbt_output && !f.has_lbt_atomic_props())
|
||||
f = relabel(f, Pnn);
|
||||
|
||||
std::string args = std::to_string(n);
|
||||
if (n2 >= 0)
|
||||
args = args + ',' + std::to_string(n2);
|
||||
if (opt_positive || !opt_negative)
|
||||
{
|
||||
output_formula_checked(f, nullptr, gen::ltl_pattern_name(pattern), n);
|
||||
output_formula_checked(f, nullptr, gen::ltl_pattern_name(pattern),
|
||||
args.c_str());
|
||||
}
|
||||
if (opt_negative)
|
||||
{
|
||||
std::string tmp = "!";
|
||||
tmp += gen::ltl_pattern_name(pattern);
|
||||
output_formula_checked(formula::Not(f), nullptr, tmp.c_str(), n);
|
||||
output_formula_checked(formula::Not(f), nullptr, tmp.c_str(),
|
||||
args.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -281,7 +308,15 @@ run_jobs()
|
|||
int n = j.range.min;
|
||||
for (;;)
|
||||
{
|
||||
output_pattern(j.pattern, n);
|
||||
int inc2 = (j.range2.max < j.range2.min) ? -1 : 1;
|
||||
int n2 = j.range2.min;
|
||||
for (;;)
|
||||
{
|
||||
output_pattern(j.pattern, n, n2);
|
||||
if (n2 == j.range2.max)
|
||||
break;
|
||||
n2 += inc2;
|
||||
}
|
||||
if (n == j.range.max)
|
||||
break;
|
||||
n += inc;
|
||||
|
|
|
|||
|
|
@ -781,7 +781,8 @@ namespace
|
|||
for (auto& p: m)
|
||||
stream_formula(opt->output_define->ostream()
|
||||
<< "#define " << p.first << " (",
|
||||
p.second, filename, linenum) << ")\n";
|
||||
p.second, filename,
|
||||
std::to_string(linenum).c_str()) << ")\n";
|
||||
}
|
||||
one_match = true;
|
||||
output_formula_checked(f, &timer, filename, linenum, prefix, suffix);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue