Hi Reuben,
Thank you for the report. Using the Python code at the end of this
mail (you can copy and paste it on
http://spot-sandbox.lrde.epita.fr/
if you do not have built the Python bindings), I have be able to
reproduce your issue, and even reduce the automata by a few states. I
agree this looks very bogus: flipping the use_simulation flags should
not change the result. The two deterministic automata produced are
quite different (6 single-state SCCs vs. 1 five-state SCC) so I hope
the bug will be easy to find. I'll try to have a look at it when I'm
more rested (I know how this option is supposed to work, but I'm not
very familiar with the implementation).
In the meantime, I suspect it is safer to disable this use_simulation
flag in your code. Also the Python code belows includes a few
suggestions you might want to transpose in C++:
- use remove_fin() instead of to_generalize_buchi(): removing Fin
acceptance is the first step of to_generalized_buchi(), but it is
enough to call an emptiness check,
- prefer otf_product() to std::make_shared<twa_product>() -- but
that's cosmetics,
- use product->is_empty() (or product->accepting_word() if you do need
to compute a word), this will create couvreur99_check and run it for
you, but in the future it may also select more efficient emptiness
checks depending on the strength of the automaton to check.
I'm also curious if you have any feedback about how difficult the move
from 1.2.4 to 2.1 was.
#!/usr/bin/python3
import spot
a = spot.automaton("""
HOA: v1
States: 5
Start: 4
AP: 3 "p_0" "p_1" "p_2"
Acceptance: 1 Inf(0)
--BODY--
State: 0
[0&!1&2] 1
[!0&!1&2] 2
State: 1 {0}
[0&!1&2] 1
State: 2 {0}
[!0&!1&2] 2
State: 3 {0}
[0&1&!2] 0
[!0&1&!2] 3
State: 4
[!0&1&!2] 3
--END--
""")
b = spot.automaton("""
HOA: v1
States: 8
Start: 0
AP: 3 "p_0" "p_1" "p_2"
Acceptance: 1 Inf(0)
--BODY--
State: 0
[t] 0
[!0&!1&2] 1
[!0&1&!2] 4
[!0&1&!2] 5
[!0&1&!2] 6
State: 1 {0}
[!0&!1&2] 1
State: 2
[0&!1&2] 7
State: 3
[!0&!1&2] 1
State: 4
[0&1&!2] 2
State: 5
[0&1&!2] 3
State: 6 {0}
[!0&1&!2] 6
State: 7 {0}
[0&!1&2] 7
--END--
""");
print("use_simulation=True")
b1 = spot.tgba_determinize(b, False, True, True, True)
b1 = spot.remove_fin(spot.dtwa_complement(b1))
print(spot.otf_product(a, b1).accepting_word())
print("\nuse_simulation=False")
b2 = spot.tgba_determinize(b, False, True, False, True)
b2 = spot.remove_fin(spot.dtwa_complement(b2))
print(spot.otf_product(a, b2).accepting_word())
--
Alexandre Duret-Lutz