add a --check=stutter-sensitive-example option

* spot/twaalgos/stutter.cc,
spot/twaalgos/stutter.hh (check_stutter_invariance): Add a
find_counterexamples argument.
* spot/twaalgos/hoa.cc: Output accepted-word and rejected-word examples.
* bin/common_aoutput.cc: Handle --check=stutter-sensitive-example.
* NEWS: Mention it.
* tests/core/stutter-tgba.test: Test it.
* doc/org/concepts.org, doc/org/hoa.org: Document accepted-word and
rejected-word named properties.
* bin/man/spot-x.x: Mention that --check=stutter-sensitive-example
ignores SPOT_STUTTER_CHECK.
This commit is contained in:
Alexandre Duret-Lutz 2019-12-03 17:42:32 +01:00
parent 3be394d2eb
commit 44df3c0837
9 changed files with 187 additions and 15 deletions

View file

@ -599,6 +599,16 @@ namespace spot
os << nl;
}
}
if (auto word = aut->get_named_prop<std::string>("accepted-word"))
{
os << (v1_1 ? "spot." : "spot-") << "accepted-word: \"";
escape_str(os, *word) << '"' << nl;
}
if (auto word = aut->get_named_prop<std::string>("rejected-word"))
{
os << (v1_1 ? "spot." : "spot-") << "rejected-word: \"";
escape_str(os, *word) << '"' << nl;
}
// If we want to output implicit labels, we have to
// fill a vector with all destinations in order.

View file

@ -31,6 +31,7 @@
#include <spot/twaalgos/complement.hh>
#include <spot/twaalgos/remfin.hh>
#include <spot/twaalgos/sccinfo.hh>
#include <spot/twaalgos/word.hh>
#include <spot/twa/twaproduct.hh>
#include <spot/twa/bddprint.hh>
#include <deque>
@ -664,10 +665,11 @@ namespace spot
trival
check_stutter_invariance(twa_graph_ptr aut, formula f,
bool do_not_determinize)
bool do_not_determinize,
bool find_counterexamples)
{
trival is_stut = aut->prop_stutter_invariant();
if (is_stut.is_known())
if (!find_counterexamples && is_stut.is_known())
return is_stut.is_true();
twa_graph_ptr neg = nullptr;
@ -676,7 +678,45 @@ namespace spot
else if (!is_deterministic(aut) && do_not_determinize)
return trival::maybe();
return is_stutter_invariant(aut, std::move(neg));
if (!find_counterexamples)
return is_stutter_invariant(aut, std::move(neg));
// Procedure that may find a counterexample.
if (!neg)
neg = complement(aut);
auto aword = product(closure(aut), closure(neg))->accepting_word();
if (!aword)
{
aut->prop_stutter_invariant(true);
return true;
}
aword->simplify();
aword->use_all_aps(aut->ap_vars());
auto aaut = aword->as_automaton();
twa_word_ptr rword;
if (aaut->intersects(aut))
{
rword = sl2(aaut)->intersecting_word(neg);
rword->simplify();
}
else
{
rword = aword;
aword = sl2(aaut)->intersecting_word(neg);
aword->simplify();
}
std::ostringstream os;
os << *aword;
aut->set_named_prop<std::string>("accepted-word",
new std::string(os.str()));
os.str("");
os << *rword;
aut->set_named_prop<std::string>("rejected-word",
new std::string(os.str()));
aut->prop_stutter_invariant(false);
return false;
}
std::vector<bool>

View file

@ -122,12 +122,19 @@ namespace spot
/// If no complemented automaton could be constructed, the
/// the result will be returned as trival::maybe().
///
/// If \a find_counterexamples is set and the automaton is found to
/// be stutter-sensitive, then two named properties named
/// "accepted-word" and "rejected-word" will be added to the
/// automaton. Those sample words will be stutter-equivalent, and
/// serve as a proof that the property is stutter-sensitive.
///
/// This variant of is_stutter_invariant() is used for the
/// --check=stutter option of command-line tools.
SPOT_API trival
check_stutter_invariance(twa_graph_ptr aut_f,
formula f = nullptr,
bool do_not_determinize = false);
bool do_not_determinize = false,
bool find_counterexamples = false);
///@{