contains: fix the semantics
spot::contains(a, b) should test a⊇b. It was testing a⊆b instead. * NEWS: Mention the bug. * spot/twaalgos/contains.cc, spot/twaalgos/contains.hh: Fix the code and documentation. * tests/python/contains.ipynb: Adjust description and expected results. * python/spot/__init__.py: Also swap the argument of language_containment_checker.contains() * bin/autfilt.cc: Adjust usage.
This commit is contained in:
parent
126d392355
commit
701a3b1c6a
6 changed files with 27 additions and 50 deletions
5
NEWS
5
NEWS
|
|
@ -16,6 +16,11 @@ New in spot 2.6.0.dev (not yet released)
|
|||
set. (This combinations of options is not available from
|
||||
command-line tools.)
|
||||
|
||||
- The spot::contains(a, b) function introduced in 2.6 was testing
|
||||
a⊆b instead of a⊇b as one would expect. Infortunately the
|
||||
documentation was also matching the code, so this is a backward
|
||||
incompatible change.
|
||||
|
||||
|
||||
New in spot 2.6 (2018-07-04)
|
||||
|
||||
|
|
|
|||
|
|
@ -1411,7 +1411,7 @@ namespace
|
|||
matched &= !aut->intersects(opt->included_in);
|
||||
if (opt->equivalent_pos)
|
||||
matched &= !aut->intersects(opt->equivalent_neg)
|
||||
&& spot::contains(opt->equivalent_pos, aut);
|
||||
&& spot::contains(aut, opt->equivalent_pos);
|
||||
|
||||
if (matched && !opt->acc_words.empty())
|
||||
for (auto& word_aut: opt->acc_words)
|
||||
|
|
|
|||
|
|
@ -1039,7 +1039,7 @@ def bdd_to_formula(b, dic=_bdd_dict):
|
|||
|
||||
def language_containment_checker(dic=_bdd_dict):
|
||||
from spot.impl import language_containment_checker as c
|
||||
c.contains = c.contained
|
||||
c.contains = lambda this, a, b: c.contained(this, b, a)
|
||||
c.are_equivalent = c.equal
|
||||
return c(dic)
|
||||
|
||||
|
|
|
|||
|
|
@ -49,25 +49,25 @@ namespace spot
|
|||
|
||||
bool contains(const_twa_graph_ptr left, const_twa_graph_ptr right)
|
||||
{
|
||||
return !left->intersects(dualize(ensure_deterministic(right)));
|
||||
return !right->intersects(dualize(ensure_deterministic(left)));
|
||||
}
|
||||
|
||||
bool contains(const_twa_graph_ptr left, formula right)
|
||||
{
|
||||
return !left->intersects(translate(formula::Not(right), left->get_dict()));
|
||||
auto right_aut = translate(right, left->get_dict());
|
||||
return !right_aut->intersects(dualize(ensure_deterministic(left)));
|
||||
}
|
||||
|
||||
bool contains(formula left, const_twa_graph_ptr right)
|
||||
{
|
||||
auto left_aut = translate(left, right->get_dict());
|
||||
return !left_aut->intersects(dualize(ensure_deterministic(right)));
|
||||
return !right->intersects(translate(formula::Not(left), right->get_dict()));
|
||||
}
|
||||
|
||||
bool contains(formula left, formula right)
|
||||
{
|
||||
auto dict = make_bdd_dict();
|
||||
auto left_aut = translate(left, dict);
|
||||
return !left_aut->intersects(translate(formula::Not(right), dict));
|
||||
auto right_aut = translate(right, dict);
|
||||
return !right_aut->intersects(translate(formula::Not(left), dict));
|
||||
}
|
||||
|
||||
bool are_equivalent(const_twa_graph_ptr left, const_twa_graph_ptr right)
|
||||
|
|
|
|||
|
|
@ -28,14 +28,14 @@
|
|||
namespace spot
|
||||
{
|
||||
/// \ingroup containment
|
||||
/// \brief Test if the language of \a left is included in that of \a right.
|
||||
/// \brief Test if the language of \a right is included in that of \a left.
|
||||
///
|
||||
/// Both arguments can be either formulas or automata. Formulas
|
||||
/// will be converted into automata.
|
||||
///
|
||||
/// The inclusion check if performed by ensuring that the automaton
|
||||
/// associated to \a left does not intersect the automaton
|
||||
/// associated to the complement of \a right. It helps if \a right
|
||||
/// associated to \a right does not intersect the automaton
|
||||
/// associated to the complement of \a left. It helps if \a left
|
||||
/// is a deterministic automaton or a formula (because in both cases
|
||||
/// complementation is easier).
|
||||
/// @{
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
"source": [
|
||||
"# Containement checks\n",
|
||||
"\n",
|
||||
"The `spot.contains()` function checks whether the language of its left argument is included in the language of its right argument. The arguments may mix automata and formulas; the latter can be given as strings."
|
||||
"The `spot.contains()` function checks whether the language of its right argument is included in the language of its left argument. The arguments may mix automata and formulas; the latter can be given as strings."
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
@ -38,7 +38,7 @@
|
|||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"(False, True)"
|
||||
"(True, False)"
|
||||
]
|
||||
},
|
||||
"execution_count": 3,
|
||||
|
|
@ -58,7 +58,7 @@
|
|||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"(False, True)"
|
||||
"(True, False)"
|
||||
]
|
||||
},
|
||||
"execution_count": 4,
|
||||
|
|
@ -78,7 +78,7 @@
|
|||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"(False, True)"
|
||||
"(True, False)"
|
||||
]
|
||||
},
|
||||
"execution_count": 5,
|
||||
|
|
@ -98,7 +98,7 @@
|
|||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"(False, True)"
|
||||
"(True, False)"
|
||||
]
|
||||
},
|
||||
"execution_count": 6,
|
||||
|
|
@ -118,7 +118,7 @@
|
|||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"(False, True)"
|
||||
"(True, False)"
|
||||
]
|
||||
},
|
||||
"execution_count": 7,
|
||||
|
|
@ -145,7 +145,7 @@
|
|||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"(False, True)"
|
||||
"(True, False)"
|
||||
]
|
||||
},
|
||||
"execution_count": 8,
|
||||
|
|
@ -165,7 +165,7 @@
|
|||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"(False, True)"
|
||||
"(True, False)"
|
||||
]
|
||||
},
|
||||
"execution_count": 9,
|
||||
|
|
@ -272,7 +272,7 @@
|
|||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"(False, True)"
|
||||
"(True, False)"
|
||||
]
|
||||
},
|
||||
"execution_count": 14,
|
||||
|
|
@ -344,7 +344,7 @@
|
|||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 34,
|
||||
"execution_count": 17,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
|
|
@ -360,7 +360,7 @@
|
|||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 35,
|
||||
"execution_count": 18,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
|
|
@ -484,34 +484,6 @@
|
|||
"source": [
|
||||
"show_one_difference(aut_f, aut_g)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 36,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"ename": "NameError",
|
||||
"evalue": "name 'run' is not defined",
|
||||
"output_type": "error",
|
||||
"traceback": [
|
||||
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
|
||||
"\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)",
|
||||
"\u001b[0;32m<ipython-input-36-d7d1b4bd9ffe>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mrun\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_aut\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
|
||||
"\u001b[0;31mNameError\u001b[0m: name 'run' is not defined"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"run.get_aut()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue