add intersection checks between words and automata

Several people have asked for a way to check whether a word is
accepted by an automaton, including at least Jonah Romero and Scott
Buckley.  So it's time we have it.

* spot/twa/twa.hh, spot/twa/twa.cc,
spot/twaalgos/word.hh (intersects): Add the new variant.
* spot/twa/fwd.hh: Forward declare twa_word, so that
we can use it in twa.hh.
* spot/twaalgos/forq_contains.cc: Use the new intersection check.
* tests/python/word.ipynb, NEWS: Mention it.
* THANKS: Add Scott Buckley.
This commit is contained in:
Alexandre Duret-Lutz 2024-02-29 16:54:14 +01:00
parent 83cabfa6f9
commit 60f046a574
8 changed files with 78 additions and 12 deletions

View file

@ -36,4 +36,8 @@ namespace spot
class twa_product;
typedef std::shared_ptr<const twa_product> const_twa_product_ptr;
typedef std::shared_ptr<twa_product> twa_product_ptr;
struct twa_word;
typedef std::shared_ptr<const twa_word> const_twa_word_ptr;
typedef std::shared_ptr<twa_word> twa_word_ptr;
}

View file

@ -155,6 +155,12 @@ namespace spot
return !otf_product(self, other)->is_empty();
}
bool
twa::intersects(const_twa_word_ptr w) const
{
return intersects(w->as_automaton());
}
twa_run_ptr
twa::intersecting_run(const_twa_ptr other) const
{

View file

@ -865,6 +865,13 @@ namespace spot
/// this case an explicit product is performed.
virtual bool intersects(const_twa_ptr other) const;
/// \brief Check if this automaton _word intersects a word.
///
/// If the twa_word actually represent a word (i.e., if each
/// Boolean formula that label its steps have a unique satisfying
/// valuation), this is equivalent to a membership test.
virtual bool intersects(const_twa_word_ptr w) const;
/// \brief Return an accepting run recognizing a word accepted by
/// two automata.
///

View file

@ -578,10 +578,8 @@ namespace spot::forq
auto shared_dict = setup.context.A.aut->get_dict();
auto current_word = util::as_twa_word_ptr(shared_dict, word_of_u,
word_of_v);
if (!setup.context.B.aut->intersects(current_word->as_automaton()))
{
return current_word;
}
if (!current_word->intersects(setup.context.B.aut))
return current_word;
}
}
return nullptr;

View file

@ -85,6 +85,16 @@ namespace spot
/// This is useful to evaluate a word on an automaton.
twa_graph_ptr as_automaton() const;
/// \brief Check if a the twa_word intersect another automaton.
///
/// If the twa_word actually represent a word (i.e., if each
/// Boolean formula that label its steps have a unique satisfying
/// valuation), this is equivalent to a membership test.
bool intersects(const_twa_ptr aut) const
{
return as_automaton()->intersects(aut);
}
/// \brief Print a twa_word
///
/// Words are printed as
@ -101,8 +111,6 @@ namespace spot
bdd_dict_ptr dict_;
};
typedef std::shared_ptr<twa_word> twa_word_ptr;
/// \brief Create an empty twa_word
///
/// Note that empty twa_word are invalid and cannot be printed.