ltlfilt: add a --save-part-file option
* bin/ltlfilt.cc: Add support for --save-part-file. * NEWS, doc/org/ltlfilt.org: Mention it. * tests/core/ltlfilt.test: Test it.
This commit is contained in:
parent
b1b06ef7bd
commit
00456e5211
4 changed files with 91 additions and 7 deletions
4
NEWS
4
NEWS
|
|
@ -37,6 +37,10 @@ New in spot 2.12.2.dev (not yet released)
|
||||||
be inferred from their name. (This suspports a --part-file option
|
be inferred from their name. (This suspports a --part-file option
|
||||||
as well.)
|
as well.)
|
||||||
|
|
||||||
|
- ltlfilt learned --save-part-file[=FILENAME] option that can be
|
||||||
|
used to create partition files suitable for many synthesis tools
|
||||||
|
(including ltlsynt).
|
||||||
|
|
||||||
- genltl learned --lily-patterns to generate the example LTL
|
- genltl learned --lily-patterns to generate the example LTL
|
||||||
synthesis specifications from Lily 1.0.2. Those come with input
|
synthesis specifications from Lily 1.0.2. Those come with input
|
||||||
and output atomic proposition rewriten in the form "iNN" or "oNN",
|
and output atomic proposition rewriten in the form "iNN" or "oNN",
|
||||||
|
|
|
||||||
|
|
@ -103,6 +103,7 @@ enum {
|
||||||
OPT_REMOVE_WM,
|
OPT_REMOVE_WM,
|
||||||
OPT_REMOVE_X,
|
OPT_REMOVE_X,
|
||||||
OPT_SAFETY,
|
OPT_SAFETY,
|
||||||
|
OPT_SAVE_PART_FILE,
|
||||||
OPT_SIGMA2,
|
OPT_SIGMA2,
|
||||||
OPT_SIZE,
|
OPT_SIZE,
|
||||||
OPT_SIZE_MAX,
|
OPT_SIZE_MAX,
|
||||||
|
|
@ -184,13 +185,18 @@ static const argp_option options[] =
|
||||||
" proposition", 0 },
|
" proposition", 0 },
|
||||||
{ "ins", OPT_INS, "PROPS", 0,
|
{ "ins", OPT_INS, "PROPS", 0,
|
||||||
"comma-separated list of input atomic propositions to use with "
|
"comma-separated list of input atomic propositions to use with "
|
||||||
"--relabel=io, interpreted as a regex if enclosed in slashes", 0 },
|
"--relabel=io or --save-part-file, interpreted as a regex if enclosed "
|
||||||
|
"in slashes", 0 },
|
||||||
{ "outs", OPT_OUTS, "PROPS", 0,
|
{ "outs", OPT_OUTS, "PROPS", 0,
|
||||||
"comma-separated list of output atomic propositions to use with "
|
"comma-separated list of output atomic propositions to use with "
|
||||||
"--relabel=io, interpreted as a regex if enclosed in slashes", 0 },
|
"--relabel=io or --save-part-file, interpreted as a regex if "
|
||||||
|
"enclosed in slashes", 0 },
|
||||||
{ "part-file", OPT_PART_FILE, "FILENAME", 0,
|
{ "part-file", OPT_PART_FILE, "FILENAME", 0,
|
||||||
"file containing the partition of atomic propositions to use with "
|
"file containing the partition of atomic propositions to use with "
|
||||||
"--relabel=io", 0 },
|
"--relabel=io", 0 },
|
||||||
|
{ "save-part-file", OPT_SAVE_PART_FILE, "FILENAME", OPTION_ARG_OPTIONAL,
|
||||||
|
"file containing the partition of atomic propositions, "
|
||||||
|
"readable by --part-file", 0 },
|
||||||
DECLARE_OPT_R,
|
DECLARE_OPT_R,
|
||||||
LEVEL_DOC(4),
|
LEVEL_DOC(4),
|
||||||
/**************************************************/
|
/**************************************************/
|
||||||
|
|
@ -377,6 +383,7 @@ static struct opt_t
|
||||||
{
|
{
|
||||||
spot::bdd_dict_ptr dict = spot::make_bdd_dict();
|
spot::bdd_dict_ptr dict = spot::make_bdd_dict();
|
||||||
spot::exclusive_ap excl_ap;
|
spot::exclusive_ap excl_ap;
|
||||||
|
std::unique_ptr<output_file> output_part = nullptr;
|
||||||
std::unique_ptr<output_file> output_define = nullptr;
|
std::unique_ptr<output_file> output_define = nullptr;
|
||||||
std::unique_ptr<output_file> output_sonf = nullptr;
|
std::unique_ptr<output_file> output_sonf = nullptr;
|
||||||
spot::formula implied_by = nullptr;
|
spot::formula implied_by = nullptr;
|
||||||
|
|
@ -596,6 +603,9 @@ parse_opt(int key, char* arg, struct argp_state*)
|
||||||
case OPT_SAFETY:
|
case OPT_SAFETY:
|
||||||
safety = obligation = true;
|
safety = obligation = true;
|
||||||
break;
|
break;
|
||||||
|
case OPT_SAVE_PART_FILE:
|
||||||
|
opt->output_part.reset(new output_file(arg ? arg : "-"));
|
||||||
|
break;
|
||||||
case OPT_SIZE:
|
case OPT_SIZE:
|
||||||
size = parse_range(arg, 0, std::numeric_limits<int>::max());
|
size = parse_range(arg, 0, std::numeric_limits<int>::max());
|
||||||
break;
|
break;
|
||||||
|
|
@ -954,6 +964,40 @@ namespace
|
||||||
oldname, filename,
|
oldname, filename,
|
||||||
std::to_string(linenum).c_str()) << ")\n";
|
std::to_string(linenum).c_str()) << ")\n";
|
||||||
}
|
}
|
||||||
|
if (opt->output_part
|
||||||
|
&& output_format != count_output
|
||||||
|
&& output_format != quiet_output)
|
||||||
|
{
|
||||||
|
std::vector<spot::formula> ins;
|
||||||
|
std::vector<spot::formula> outs;
|
||||||
|
spot::atomic_prop_set* s = atomic_prop_collect(f);
|
||||||
|
for (spot::formula ap: *s)
|
||||||
|
{
|
||||||
|
spot::formula apo = ap;
|
||||||
|
if (auto it = relmap.find(ap); it != relmap.end())
|
||||||
|
apo = it->second;
|
||||||
|
if (is_output(apo.ap_name(), filename, linenum))
|
||||||
|
outs.push_back(ap);
|
||||||
|
else
|
||||||
|
ins.push_back(ap);
|
||||||
|
}
|
||||||
|
delete s;
|
||||||
|
auto& os = opt->output_part->ostream();
|
||||||
|
if (!ins.empty())
|
||||||
|
{
|
||||||
|
os << ".inputs";
|
||||||
|
for (const auto& ap: ins)
|
||||||
|
os << ' ' << str_psl(ap);
|
||||||
|
os << '\n';
|
||||||
|
}
|
||||||
|
if (!outs.empty())
|
||||||
|
{
|
||||||
|
os << ".outputs";
|
||||||
|
for (const auto& ap: outs)
|
||||||
|
os << ' ' << str_psl(ap);
|
||||||
|
os << '\n';
|
||||||
|
}
|
||||||
|
}
|
||||||
one_match = true;
|
one_match = true;
|
||||||
output_formula_checked(f, &timer, filename, linenum,
|
output_formula_checked(f, &timer, filename, linenum,
|
||||||
match_count, prefix, suffix);
|
match_count, prefix, suffix);
|
||||||
|
|
@ -982,7 +1026,7 @@ main(int argc, char** argv)
|
||||||
if (jobs.empty())
|
if (jobs.empty())
|
||||||
jobs.emplace_back("-", job_type::LTL_FILENAME);
|
jobs.emplace_back("-", job_type::LTL_FILENAME);
|
||||||
|
|
||||||
if (relabeling == IOApRelabeling)
|
if (relabeling == IOApRelabeling || opt->output_part)
|
||||||
process_io_options();
|
process_io_options();
|
||||||
|
|
||||||
if (boolean_to_isop && simplification_level == 0)
|
if (boolean_to_isop && simplification_level == 0)
|
||||||
|
|
|
||||||
|
|
@ -301,14 +301,18 @@ ltldo ltl3ba -f '"proc@loc1" U "proc@loc2"' --spin
|
||||||
This case also relabels the formula before calling =ltl3ba=, and it
|
This case also relabels the formula before calling =ltl3ba=, and it
|
||||||
then renames all the atomic propositions in the output.
|
then renames all the atomic propositions in the output.
|
||||||
|
|
||||||
|
An example showing how to use the =--from-ltlf= option is on [[file:tut12.org][a
|
||||||
|
separate page]].
|
||||||
|
|
||||||
|
* I/O-partitioned formulas
|
||||||
|
|
||||||
A special relabeling mode related to LTL synthesis is =--relabel=io=.
|
A special relabeling mode related to LTL synthesis is =--relabel=io=.
|
||||||
In LTL synthesis (see [[file:ltlsynt.org][=ltlsynt=]]), atomic propositions are partitioned
|
In LTL synthesis (see [[file:ltlsynt.org][=ltlsynt=]]), atomic propositions are partitioned
|
||||||
in two sets: the /input/ propositions represent choices from the
|
in two sets: the /input/ propositions represent choices from the
|
||||||
environment, while /output/ proposition represent choices by the
|
environment, while /output/ propositions represent choices by the
|
||||||
controller to be synthesized. For instance
|
controller to be synthesized. For instance
|
||||||
=G(req -> Fack) & G(go -> Fgrant)=
|
=G(req -> Fack) & G(go -> Fgrant)=
|
||||||
represents could be a specification where =req= and =go= are inputs,
|
could be a specification where =req= and =go= are inputs,
|
||||||
while =ack= and =grant= are outputs. Tool such as =ltlsynt= need
|
while =ack= and =grant= are outputs. Tool such as =ltlsynt= need
|
||||||
to be told using options such as =--ins= or =--outs= which atomic
|
to be told using options such as =--ins= or =--outs= which atomic
|
||||||
propositions are input or output. Often these atomic propositions
|
propositions are input or output. Often these atomic propositions
|
||||||
|
|
@ -331,8 +335,24 @@ when these two options are missing the convention is that anything
|
||||||
starting with =i= is an input, and anything starting with =o= is an
|
starting with =i= is an input, and anything starting with =o= is an
|
||||||
output.
|
output.
|
||||||
|
|
||||||
An example showing how to use the =--from-ltlf= option is on [[file:tut12.org][a
|
=ltlfilt= can also be instructed to create a partition file (usually
|
||||||
separate page]].
|
named =*.part=) that can be used by synthesis tools.
|
||||||
|
|
||||||
|
#+BEGIN_SRC sh
|
||||||
|
ltlfilt -f 'G(req -> Fack) & G(go -> Fgrant)' --relabel=io \
|
||||||
|
--ins=req,go --save-part=out.part
|
||||||
|
#+END_SRC
|
||||||
|
#+RESULTS:
|
||||||
|
: G(i1 -> Fo0) & G(i0 -> Fo1)
|
||||||
|
|
||||||
|
In addition to the relabeling, this also created a file =out.part=
|
||||||
|
containing the following:
|
||||||
|
#+BEGIN_SRC sh :exports results
|
||||||
|
cat out.part
|
||||||
|
#+END_SRC
|
||||||
|
#+RESULTS:
|
||||||
|
: .inputs i0 i1
|
||||||
|
: .outputs o0 o1
|
||||||
|
|
||||||
* Filtering
|
* Filtering
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -872,3 +872,19 @@ diff expected out
|
||||||
# would stick to the rest of the file unless overridden.
|
# would stick to the rest of the file unless overridden.
|
||||||
run 2 ltlfilt -Ffile/1 -Ffile
|
run 2 ltlfilt -Ffile/1 -Ffile
|
||||||
:
|
:
|
||||||
|
|
||||||
|
|
||||||
|
run 0 ltlfilt -f 'i1 U o2 U i3' --save-part=p.part
|
||||||
|
cat > exp.part<<EOF
|
||||||
|
.inputs i1 i3
|
||||||
|
.outputs o2
|
||||||
|
EOF
|
||||||
|
diff exp.part p.part
|
||||||
|
|
||||||
|
run 0 ltlfilt -f 'a U b U c' --ins=a --relabel=io --save-part >out
|
||||||
|
cat > exp<<EOF
|
||||||
|
.inputs i0
|
||||||
|
.outputs o0 o1
|
||||||
|
i0 U (o0 U o1)
|
||||||
|
EOF
|
||||||
|
diff exp out
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue