common_trans: allow rewriting operators
Part of #168. * spot/misc/formater.cc: Adjust to support bracketed options. * bin/common_trans.hh, bin/common_trans.cc: Use that to support rewriting operators. * doc/org/ltlcross.org, tests/core/ltldo.test: Add some examples. * NEWS: Mention it.
This commit is contained in:
parent
925785e85f
commit
d9174593c8
6 changed files with 207 additions and 80 deletions
14
NEWS
14
NEWS
|
|
@ -20,6 +20,20 @@ New in spot 2.0a (not yet released)
|
||||||
These differ from --ap=RANGE that only consider *declared* atomic
|
These differ from --ap=RANGE that only consider *declared* atomic
|
||||||
propositions, regardless of whether they are actually used.
|
propositions, regardless of whether they are actually used.
|
||||||
|
|
||||||
|
* ltlcross and ltldo have a new syntax to specify that an input
|
||||||
|
formula should be written in some given syntax after rewriting
|
||||||
|
some operators away. For instance the defaults arguments passed
|
||||||
|
to ltl2dstar have been changed from
|
||||||
|
--output-format=hoa %L %O
|
||||||
|
into
|
||||||
|
--output-format=hoa %[WM]L %O
|
||||||
|
where [WM] specifies that operators W and M should be rewritten
|
||||||
|
away. As a consequence running
|
||||||
|
ltldo ltl2dstar -f 'a M b'
|
||||||
|
will now work and call ltl2dstar on the equivalent formula
|
||||||
|
'b U (a & b)' instead. The operators that can be listed between
|
||||||
|
brackets are the same as those of ltlfilt --unabbreviate option.
|
||||||
|
|
||||||
Library:
|
Library:
|
||||||
|
|
||||||
* The print_hoa() function will now output version 1.1 of the HOA
|
* The print_hoa() function will now output version 1.1 of the HOA
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
|
|
||||||
#include <spot/tl/print.hh>
|
#include <spot/tl/print.hh>
|
||||||
|
#include <spot/tl/unabbrev.hh>
|
||||||
#include "common_conv.hh"
|
#include "common_conv.hh"
|
||||||
#include <spot/misc/escape.hh>
|
#include <spot/misc/escape.hh>
|
||||||
|
|
||||||
|
|
@ -41,11 +42,11 @@ static struct shorthands_t
|
||||||
shorthands[] = {
|
shorthands[] = {
|
||||||
{ "lbt", " <%L>%O" },
|
{ "lbt", " <%L>%O" },
|
||||||
{ "ltl2ba", " -f %s>%O" },
|
{ "ltl2ba", " -f %s>%O" },
|
||||||
{ "ltl2dstar", " --output-format=hoa %L %O"},
|
{ "ltl2dstar", " --output-format=hoa %[MW]L %O"},
|
||||||
{ "ltl2tgba", " -H %f>%O" },
|
{ "ltl2tgba", " -H %f>%O" },
|
||||||
{ "ltl3ba", " -f %s>%O" },
|
{ "ltl3ba", " -f %s>%O" },
|
||||||
{ "ltl3dra", " -f %s>%O" },
|
{ "ltl3dra", " -f %s>%O" },
|
||||||
{ "modella", " %L %O" },
|
{ "modella", " %[MWei^]L %O" },
|
||||||
{ "spin", " -f %s>%O" },
|
{ "spin", " -f %s>%O" },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -63,7 +64,7 @@ static void show_shorthands()
|
||||||
"matching those prefixes. So for instance\n"
|
"matching those prefixes. So for instance\n"
|
||||||
" '{DRA} ~/mytools/ltl2dstar-0.5.2'\n"
|
" '{DRA} ~/mytools/ltl2dstar-0.5.2'\n"
|
||||||
"will changed into\n"
|
"will changed into\n"
|
||||||
" '{DRA} ~/mytools/ltl2dstar-0.5.2 --output-format=hoa %L %O'\n");
|
" '{DRA} ~/mytools/ltl2dstar-0.5.2 --output-format=hoa %[MR]L %O'\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -153,6 +154,58 @@ quoted_string::print(std::ostream& os, const char*) const
|
||||||
spot::quote_shell_string(os, val().c_str());
|
spot::quote_shell_string(os, val().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void quoted_formula::print(std::ostream& os, const char* pos) const
|
||||||
|
{
|
||||||
|
spot::formula f = val_;
|
||||||
|
if (*pos == '[')
|
||||||
|
{
|
||||||
|
++pos;
|
||||||
|
auto end = strchr(pos, ']');
|
||||||
|
auto arg = strndup(pos, end - pos);
|
||||||
|
f = spot::unabbreviate(f, arg);
|
||||||
|
free(arg);
|
||||||
|
pos = end + 1;
|
||||||
|
}
|
||||||
|
std::ostringstream ss;
|
||||||
|
std::ostream* out = &ss;
|
||||||
|
bool quoted = true;
|
||||||
|
switch (*pos)
|
||||||
|
{
|
||||||
|
case 'F':
|
||||||
|
case 'S':
|
||||||
|
case 'L':
|
||||||
|
case 'W':
|
||||||
|
out = &os;
|
||||||
|
quoted = false;
|
||||||
|
}
|
||||||
|
switch (*pos)
|
||||||
|
{
|
||||||
|
case 'f':
|
||||||
|
case 'F':
|
||||||
|
print_psl(*out, f, true);
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
case 'S':
|
||||||
|
print_spin_ltl(*out, f, true);
|
||||||
|
break;
|
||||||
|
case 'l':
|
||||||
|
case 'L':
|
||||||
|
print_lbt_ltl(*out, f);
|
||||||
|
break;
|
||||||
|
case 'w':
|
||||||
|
case 'W':
|
||||||
|
print_wring_ltl(*out, f);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (quoted)
|
||||||
|
{
|
||||||
|
std::string s = ss.str();
|
||||||
|
spot::quote_shell_string(os, s.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
printable_result_filename::printable_result_filename()
|
printable_result_filename::printable_result_filename()
|
||||||
{
|
{
|
||||||
val_ = nullptr;
|
val_ = nullptr;
|
||||||
|
|
@ -184,19 +237,42 @@ printable_result_filename::print(std::ostream& os, const char*) const
|
||||||
spot::quote_shell_string(os, val()->name());
|
spot::quote_shell_string(os, val()->name());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
filed_formula::print(std::ostream& os, const char* pos) const
|
||||||
|
{
|
||||||
|
std::ostringstream ss;
|
||||||
|
f_.print(ss, pos);
|
||||||
|
os << '\'' << string_to_tmp(ss.str(), serial_) << '\'';
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string
|
||||||
|
filed_formula::string_to_tmp(const std::string str, unsigned n) const
|
||||||
|
{
|
||||||
|
char prefix[30];
|
||||||
|
snprintf(prefix, sizeof prefix, "lcr-i%u-", n);
|
||||||
|
spot::open_temporary_file* tmpfile = spot::create_open_tmpfile(prefix);
|
||||||
|
std::string tmpname = tmpfile->name();
|
||||||
|
int fd = tmpfile->fd();
|
||||||
|
ssize_t s = str.size();
|
||||||
|
if (write(fd, str.c_str(), s) != s
|
||||||
|
|| write(fd, "\n", 1) != 1)
|
||||||
|
error(2, errno, "failed to write into %s", tmpname.c_str());
|
||||||
|
tmpfile->close();
|
||||||
|
return tmpname;
|
||||||
|
}
|
||||||
|
|
||||||
translator_runner::translator_runner(spot::bdd_dict_ptr dict,
|
translator_runner::translator_runner(spot::bdd_dict_ptr dict,
|
||||||
bool no_output_allowed)
|
bool no_output_allowed)
|
||||||
: dict(dict)
|
: dict(dict)
|
||||||
{
|
{
|
||||||
declare('f', &string_ltl_spot);
|
declare('f', <l_formula);
|
||||||
declare('s', &string_ltl_spin);
|
declare('s', <l_formula);
|
||||||
declare('l', &string_ltl_lbt);
|
declare('l', <l_formula);
|
||||||
declare('w', &string_ltl_wring);
|
declare('w', <l_formula);
|
||||||
declare('F', &filename_ltl_spot);
|
declare('F', &filename_formula);
|
||||||
declare('S', &filename_ltl_spin);
|
declare('S', &filename_formula);
|
||||||
declare('L', &filename_ltl_lbt);
|
declare('L', &filename_formula);
|
||||||
declare('W', &filename_ltl_wring);
|
declare('W', &filename_formula);
|
||||||
declare('D', &output);
|
declare('D', &output);
|
||||||
declare('H', &output);
|
declare('H', &output);
|
||||||
declare('N', &output);
|
declare('N', &output);
|
||||||
|
|
@ -229,61 +305,29 @@ translator_runner::translator_runner(spot::bdd_dict_ptr dict,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
std::string
|
||||||
translator_runner::string_to_tmp(std::string& str, unsigned n,
|
|
||||||
std::string& tmpname)
|
|
||||||
{
|
|
||||||
char prefix[30];
|
|
||||||
snprintf(prefix, sizeof prefix, "lcr-i%u-", n);
|
|
||||||
spot::open_temporary_file* tmpfile = spot::create_open_tmpfile(prefix);
|
|
||||||
tmpname = tmpfile->name();
|
|
||||||
int fd = tmpfile->fd();
|
|
||||||
ssize_t s = str.size();
|
|
||||||
if (write(fd, str.c_str(), s) != s
|
|
||||||
|| write(fd, "\n", 1) != 1)
|
|
||||||
error(2, errno, "failed to write into %s", tmpname.c_str());
|
|
||||||
tmpfile->close();
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string&
|
|
||||||
translator_runner::formula() const
|
translator_runner::formula() const
|
||||||
{
|
{
|
||||||
// Pick the most readable format we have...
|
// Pick the most readable format we have...
|
||||||
if (!string_ltl_spot.val().empty())
|
if (has('f') || has('F'))
|
||||||
return string_ltl_spot;
|
return spot::str_psl(ltl_formula, true);
|
||||||
if (!string_ltl_spin.val().empty())
|
if (has('s') || has('S'))
|
||||||
return string_ltl_spin;
|
return spot::str_spin_ltl(ltl_formula, true);
|
||||||
if (!string_ltl_wring.val().empty())
|
if (has('l') || has('L'))
|
||||||
return string_ltl_wring;
|
return spot::str_lbt_ltl(ltl_formula);
|
||||||
if (!string_ltl_lbt.val().empty())
|
if (has('w') || has('W'))
|
||||||
return string_ltl_lbt;
|
return spot::str_wring_ltl(ltl_formula);
|
||||||
SPOT_UNREACHABLE();
|
SPOT_UNREACHABLE();
|
||||||
return string_ltl_spot;
|
return spot::str_psl(ltl_formula, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
translator_runner::round_formula(spot::formula f, unsigned serial)
|
translator_runner::round_formula(spot::formula f, unsigned serial)
|
||||||
{
|
{
|
||||||
if (has('f') || has('F'))
|
ltl_formula = f;
|
||||||
string_ltl_spot = spot::str_psl(f, true);
|
filename_formula.new_round(serial);
|
||||||
if (has('s') || has('S'))
|
|
||||||
string_ltl_spin = spot::str_spin_ltl(f, true);
|
|
||||||
if (has('l') || has('L'))
|
|
||||||
string_ltl_lbt = spot::str_lbt_ltl(f);
|
|
||||||
if (has('w') || has('W'))
|
|
||||||
string_ltl_wring = spot::str_wring_ltl(f);
|
|
||||||
if (has('F'))
|
|
||||||
string_to_tmp(string_ltl_spot, serial, filename_ltl_spot);
|
|
||||||
if (has('S'))
|
|
||||||
string_to_tmp(string_ltl_spin, serial, filename_ltl_spin);
|
|
||||||
if (has('L'))
|
|
||||||
string_to_tmp(string_ltl_lbt, serial, filename_ltl_lbt);
|
|
||||||
if (has('W'))
|
|
||||||
string_to_tmp(string_ltl_wring, serial, filename_ltl_wring);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
volatile bool timed_out = false;
|
volatile bool timed_out = false;
|
||||||
unsigned timeout_count = 0;
|
unsigned timeout_count = 0;
|
||||||
|
|
||||||
|
|
@ -407,6 +451,10 @@ static const argp_option options[] =
|
||||||
"If either %l, %L, or %T are used, any input formula that does "
|
"If either %l, %L, or %T are used, any input formula that does "
|
||||||
"not use LBT-style atomic propositions (i.e. p0, p1, ...) will be "
|
"not use LBT-style atomic propositions (i.e. p0, p1, ...) will be "
|
||||||
"relabeled automatically.\n"
|
"relabeled automatically.\n"
|
||||||
|
"The sequences %f,%s,%l,%w,%F,%S,%L,%W can optionally be \"infixed\""
|
||||||
|
" by a bracketed sequence of operators to unabbreviate before outputing"
|
||||||
|
" the formula. For instance %[MW]f will rewrite operators M and W"
|
||||||
|
" before outputing it.\n"
|
||||||
"Furthermore, if COMMANDFMT has the form \"{NAME}CMD\", then only CMD "
|
"Furthermore, if COMMANDFMT has the form \"{NAME}CMD\", then only CMD "
|
||||||
"will be passed to the shell, and NAME will be used to name the tool "
|
"will be passed to the shell, and NAME will be used to name the tool "
|
||||||
"in the output.", 4 },
|
"in the output.", 4 },
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,31 @@ struct quoted_string final: public spot::printable_value<std::string>
|
||||||
void print(std::ostream& os, const char* pos) const override;
|
void print(std::ostream& os, const char* pos) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct quoted_formula final: public spot::printable_value<spot::formula>
|
||||||
|
{
|
||||||
|
using spot::printable_value<spot::formula>::operator=;
|
||||||
|
void print(std::ostream& os, const char* pos) const override;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct filed_formula final: public spot::printable
|
||||||
|
{
|
||||||
|
filed_formula(const quoted_formula& ltl) : f_(ltl)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void print(std::ostream& os, const char* pos) const override;
|
||||||
|
|
||||||
|
void new_round(unsigned serial)
|
||||||
|
{
|
||||||
|
serial_ = serial;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const quoted_formula& f_;
|
||||||
|
unsigned serial_;
|
||||||
|
std::string string_to_tmp(const std::string str, unsigned n) const;
|
||||||
|
};
|
||||||
|
|
||||||
struct printable_result_filename final:
|
struct printable_result_filename final:
|
||||||
public spot::printable_value<spot::temporary_file*>
|
public spot::printable_value<spot::temporary_file*>
|
||||||
{
|
{
|
||||||
|
|
@ -75,14 +100,8 @@ class translator_runner: protected spot::formater
|
||||||
protected:
|
protected:
|
||||||
spot::bdd_dict_ptr dict;
|
spot::bdd_dict_ptr dict;
|
||||||
// Round-specific variables
|
// Round-specific variables
|
||||||
quoted_string string_ltl_spot;
|
quoted_formula ltl_formula;
|
||||||
quoted_string string_ltl_spin;
|
filed_formula filename_formula = ltl_formula;
|
||||||
quoted_string string_ltl_lbt;
|
|
||||||
quoted_string string_ltl_wring;
|
|
||||||
quoted_string filename_ltl_spot;
|
|
||||||
quoted_string filename_ltl_spin;
|
|
||||||
quoted_string filename_ltl_lbt;
|
|
||||||
quoted_string filename_ltl_wring;
|
|
||||||
// Run-specific variables
|
// Run-specific variables
|
||||||
printable_result_filename output;
|
printable_result_filename output;
|
||||||
public:
|
public:
|
||||||
|
|
@ -92,8 +111,7 @@ public:
|
||||||
// whether we accept the absence of output
|
// whether we accept the absence of output
|
||||||
// specifier
|
// specifier
|
||||||
bool no_output_allowed = false);
|
bool no_output_allowed = false);
|
||||||
void string_to_tmp(std::string& str, unsigned n, std::string& tmpname);
|
std::string formula() const;
|
||||||
const std::string& formula() const;
|
|
||||||
void round_formula(spot::formula f, unsigned serial);
|
void round_formula(spot::formula f, unsigned serial);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -98,6 +98,14 @@ Performing sanity checks and gathering statistics...
|
||||||
No problem detected.
|
No problem detected.
|
||||||
#+end_example
|
#+end_example
|
||||||
|
|
||||||
|
To handle tools that do not support some LTL operators, the character
|
||||||
|
sequences ~%f~, ~%s~, ~%l~, ~%w~, ~%F~, ~%S~, ~%L~, and ~%W~ can be
|
||||||
|
"infixed" by a bracketed list of operators to rewrite away. For
|
||||||
|
instance if a tool reads LTL formulas from a file in LBT's syntax, but
|
||||||
|
does not support operators ~M~ (strong until) and ~W~ (weak until),
|
||||||
|
use ~%[WM]L~ instead of just ~%L~; this way operators ~W~ and ~M~ will
|
||||||
|
be rewritten using the other supported operators.
|
||||||
|
|
||||||
=ltlcross= can only read four kinds of output:
|
=ltlcross= can only read four kinds of output:
|
||||||
- Never claims (only if they are restricted to representing an
|
- Never claims (only if they are restricted to representing an
|
||||||
automaton using =if=, =goto=, and =skip= statements) such as those
|
automaton using =if=, =goto=, and =skip= statements) such as those
|
||||||
|
|
@ -125,7 +133,7 @@ tools:
|
||||||
- '=ltl2ba -f %s >%O='
|
- '=ltl2ba -f %s >%O='
|
||||||
- '=ltl3ba -M0 -f %s >%O=' (less deterministic output, can be smaller)
|
- '=ltl3ba -M0 -f %s >%O=' (less deterministic output, can be smaller)
|
||||||
- '=ltl3ba -M1 -f %s >%O=' (more deterministic output)
|
- '=ltl3ba -M1 -f %s >%O=' (more deterministic output)
|
||||||
- '=modella -r12 -g -e %L %O='
|
- '=modella -r12 -g -e %[MWei^]L %O='
|
||||||
- '=/path/to/script4lbtt.py %L %O=' (script supplied by [[http://web.archive.org/web/20070214050826/http://estragon.ti.informatik.uni-kiel.de/~fritz/][ltl2nba]] for
|
- '=/path/to/script4lbtt.py %L %O=' (script supplied by [[http://web.archive.org/web/20070214050826/http://estragon.ti.informatik.uni-kiel.de/~fritz/][ltl2nba]] for
|
||||||
its interface with LBTT)
|
its interface with LBTT)
|
||||||
- '=ltl2tgba -s %f >%O=' (smaller output, Büchi automaton)
|
- '=ltl2tgba -s %f >%O=' (smaller output, Büchi automaton)
|
||||||
|
|
@ -134,22 +142,22 @@ tools:
|
||||||
- '=ltl2tgba -H -D %f >%O=' (more deterministic output, TGBA)
|
- '=ltl2tgba -H -D %f >%O=' (more deterministic output, TGBA)
|
||||||
- '=lbt <%L >%O='
|
- '=lbt <%L >%O='
|
||||||
- '~ltl2dstar --ltl2nba=spin:path/to/ltl2tgba@-sD
|
- '~ltl2dstar --ltl2nba=spin:path/to/ltl2tgba@-sD
|
||||||
--output-format=hoa %L %O~' deterministic Rabin output in HOA, as
|
--output-format=hoa %[MW]L %O~' deterministic Rabin output in HOA, as
|
||||||
supported since version 0.5.2 of =ltl2dstar=.
|
supported since version 0.5.2 of =ltl2dstar=.
|
||||||
- '~ltl2dstar --ltl2nba=spin:path/to/ltl2tgba@-sD --automata=streett
|
- '~ltl2dstar --ltl2nba=spin:path/to/ltl2tgba@-sD --automata=streett
|
||||||
--output-format=hoa %L %O~' deterministic Streett output in HOA,
|
--output-format=hoa %[MW]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 %O=' (Rabin
|
- '=ltl2dstar --ltl2nba=spin:path/to/ltl2tgba@-sD %[MW]L %O=' (Rabin
|
||||||
output in DSTAR format, as supported in older versions of
|
output in DSTAR format, as supported in older versions of
|
||||||
=ltl2dstar=.
|
=ltl2dstar=.
|
||||||
- '=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
|
||||||
=ltlcross= would provide)
|
=ltlcross= would provide)
|
||||||
- '=java -jar Rabinizer.jar -ltl2dstar %F %O; mv %O.dst %O=' (Rabinizer
|
- '=java -jar Rabinizer.jar -ltl2dstar %[MW]F %O; mv %O.dst %O=' (Rabinizer
|
||||||
uses the last =%O= argument as a prefix to which it always append =.dst=,
|
uses the last =%O= argument as a prefix to which it always append =.dst=,
|
||||||
so we have to rename =%O.dst= as =%O= so that =ltlcross= can find the file)
|
so we have to rename =%O.dst= as =%O= so that =ltlcross= can find the file)
|
||||||
- '~java -jar rabinizer3.1.jar -in=formula -silent -out=std -format=hoa -auto=tr %f >%O~'
|
- '~java -jar rabinizer3.1.jar -in=formula -silent -out=std -format=hoa -auto=tr %[MWR]f >%O~'
|
||||||
(rabinizer 3.1 can output automata in the HOA format)
|
(rabinizer 3.1 can output automata in the HOA format)
|
||||||
- '=ltl3dra -f %s >%O=' (The HOA format is the default for =ltl2dra=.)
|
- '=ltl3dra -f %s >%O=' (The HOA format is the default for =ltl2dra=.)
|
||||||
|
|
||||||
|
|
@ -167,18 +175,18 @@ the following words, then the string on the right is appended.
|
||||||
|
|
||||||
lbt <%L>%O
|
lbt <%L>%O
|
||||||
ltl2ba -f %s>%O
|
ltl2ba -f %s>%O
|
||||||
ltl2dstar --output-format=hoa %L %O
|
ltl2dstar --output-format=hoa %[MW]L %O
|
||||||
ltl2tgba -H %f>%O
|
ltl2tgba -H %f>%O
|
||||||
ltl3ba -f %s>%O
|
ltl3ba -f %s>%O
|
||||||
ltl3dra -f %f>%O
|
ltl3dra -f %s>%O
|
||||||
modella %L %O
|
modella %[MWei^]L %O
|
||||||
spin -f %s>%O
|
spin -f %s>%O
|
||||||
|
|
||||||
Any {name} and directory component is skipped for the purpose of
|
Any {name} and directory component is skipped for the purpose of
|
||||||
matching those prefixes. So for instance
|
matching those prefixes. So for instance
|
||||||
'{DRA} ~/mytools/ltl2dstar-0.5.2'
|
'{DRA} ~/mytools/ltl2dstar-0.5.2'
|
||||||
will changed into
|
will changed into
|
||||||
'{DRA} ~/mytools/ltl2dstar-0.5.2 --output-format=hoa %L %O'
|
'{DRA} ~/mytools/ltl2dstar-0.5.2 --output-format=hoa %[MR]L %O'
|
||||||
#+end_example
|
#+end_example
|
||||||
|
|
||||||
What this implies is that running =ltlcross ltl2ba ltl3ba ...= is
|
What this implies is that running =ltlcross ltl2ba ltl3ba ...= is
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2012, 2013 Laboratoire de Recherche et Développement
|
// Copyright (C) 2012, 2013, 2016 Laboratoire de Recherche et
|
||||||
// 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.
|
||||||
//
|
//
|
||||||
|
|
@ -20,9 +20,18 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include <spot/misc/formater.hh>
|
#include <spot/misc/formater.hh>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
namespace spot
|
namespace spot
|
||||||
{
|
{
|
||||||
|
static void unclosed_bracket(const char* s)
|
||||||
|
{
|
||||||
|
std::ostringstream ss;
|
||||||
|
ss << '\'' << s << "' has unclosed bracket";
|
||||||
|
throw std::runtime_error(ss.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
formater::scan(const char* fmt, std::vector<bool>& has) const
|
formater::scan(const char* fmt, std::vector<bool>& has) const
|
||||||
{
|
{
|
||||||
|
|
@ -30,6 +39,19 @@ namespace spot
|
||||||
if (*pos == '%')
|
if (*pos == '%')
|
||||||
{
|
{
|
||||||
char c = *++pos;
|
char c = *++pos;
|
||||||
|
// %[...]c
|
||||||
|
const char* mark = pos;
|
||||||
|
if (c == '[')
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
++pos;
|
||||||
|
if (SPOT_UNLIKELY(!*pos))
|
||||||
|
unclosed_bracket(mark - 1);
|
||||||
|
}
|
||||||
|
while (*pos != ']');
|
||||||
|
c = *++pos;
|
||||||
|
}
|
||||||
has[c] = true;
|
has[c] = true;
|
||||||
if (!c)
|
if (!c)
|
||||||
break;
|
break;
|
||||||
|
|
@ -53,9 +75,25 @@ namespace spot
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char c = *++pos;
|
char c = *++pos;
|
||||||
|
const char* next = pos;
|
||||||
|
// in case we have %[...]X... , we want to pass
|
||||||
|
// [...]X... to the printer, and continue after the X once
|
||||||
|
// that is done.
|
||||||
|
if (c == '[')
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
++next;
|
||||||
|
if (SPOT_UNLIKELY(*next == 0))
|
||||||
|
unclosed_bracket(pos - 1);
|
||||||
|
}
|
||||||
|
while (*next != ']');
|
||||||
|
c = *++next;
|
||||||
|
}
|
||||||
call_[c]->print(*output_, pos);
|
call_[c]->print(*output_, pos);
|
||||||
if (!c)
|
if (!c)
|
||||||
break;
|
break;
|
||||||
|
pos = next;
|
||||||
}
|
}
|
||||||
return *output_;
|
return *output_;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,10 +25,11 @@ ltldo=ltldo
|
||||||
ltl2tgba=ltl2tgba
|
ltl2tgba=ltl2tgba
|
||||||
genltl=genltl
|
genltl=genltl
|
||||||
|
|
||||||
run 0 $ltldo -f a -f 'a&b' -t 'echo %f,%s' >output
|
run 0 $ltldo -f a -f 'a&b' -f 'a -> b' -t 'echo %f,%s,%[ei]w' >output
|
||||||
cat >expected <<EOF
|
cat >expected <<EOF
|
||||||
a,a
|
a,a,a=1
|
||||||
(a) & (b),(a) && (b)
|
(a) & (b),(a) && (b),(a=1) * (b=1)
|
||||||
|
(a) -> (b),(a) -> (b),(a=0) + (b=1)
|
||||||
EOF
|
EOF
|
||||||
diff output expected
|
diff output expected
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue