add support for the "terminal" property

* src/twa/twa.hh: Store the terminal property.
* src/twaalgos/hoa.cc, src/parseaut/parseaut.yy: Add I/O for "terminal".
* src/twaalgos/ltl2tgba_fm.cc, src/twaalgos/minimize.cc: Set terminal
as apropriate.
* src/twaalgos/safety.cc: Use it.
* doc/org/tut21.org, doc/org/hoa.org, NEWS: Document it.
* src/tests/complement.test, src/tests/monitor.test,
wrap/python/tests/automata-io.ipynb: Adjust.
This commit is contained in:
Alexandre Duret-Lutz 2015-11-07 13:36:31 +01:00
parent 654888718c
commit 0c5f87b442
12 changed files with 68 additions and 29 deletions

View file

@ -429,17 +429,15 @@ header: format-version header-items
}
if (res.opts.trust_hoa)
{
auto e = res.props.end();
bool si = res.props.find("stutter-invariant") != e;
res.h->aut->prop_stutter_invariant(si);
bool ss = res.props.find("stutter-sensitive") != e;
res.h->aut->prop_stutter_sensitive(ss);
bool iw = res.props.find("inherently-weak") != e;
res.h->aut->prop_inherently_weak(iw);
bool wk = res.props.find("weak") != e;
res.h->aut->prop_weak(wk);
bool un = res.props.find("unambiguous") != e;
res.h->aut->prop_unambiguous(un);
auto& a = res.h->aut;
auto& p = res.props;
auto e = p.end();
a->prop_stutter_invariant(p.find("stutter-invariant") != e);
a->prop_stutter_sensitive(p.find("stutter-sensitive") != e);
a->prop_inherently_weak(p.find("inherently-weak") != e);
a->prop_weak(p.find("weak") != e);
a->prop_terminal(p.find("terminal") != e);
a->prop_unambiguous(p.find("unambiguous") != e);
}
}

View file

@ -78,7 +78,7 @@ AP: 1 "a"
acc-name: co-Buchi
Acceptance: 1 Fin(0)
properties: trans-labels explicit-labels state-acc complete
properties: deterministic weak
properties: deterministic terminal
--BODY--
State: 0
[0] 2

View file

@ -53,7 +53,7 @@ AP: 1 "a"
acc-name: all
Acceptance: 0 t
properties: trans-labels explicit-labels state-acc deterministic
properties: stutter-invariant inherently-weak
properties: stutter-invariant terminal
--BODY--
State: 0
[t] 0

View file

@ -757,6 +757,7 @@ namespace spot
bool state_based_acc:1; // State-based acceptance.
bool inherently_weak:1; // Inherently Weak automaton.
bool weak:1; // Weak automaton.
bool terminal:1; // Terminal automaton.
bool deterministic:1; // Deterministic automaton.
bool unambiguous:1; // Unambiguous automaton.
bool stutter_invariant:1; // Stutter invariant language.
@ -831,6 +832,19 @@ namespace spot
is.inherently_weak = val;
}
bool prop_terminal() const
{
return is.terminal;
}
void prop_terminal(bool val)
{
if (val)
is.inherently_weak = is.weak = is.terminal = true;
else
is.terminal = false;
}
bool prop_weak() const
{
return is.weak;
@ -914,6 +928,7 @@ namespace spot
prop_state_acc(other->prop_state_acc());
if (p.inherently_weak)
{
prop_terminal(other->prop_terminal());
prop_weak(other->prop_weak());
prop_inherently_weak(other->prop_inherently_weak());
}
@ -935,6 +950,7 @@ namespace spot
prop_state_acc(false);
if (!p.inherently_weak)
{
prop_terminal(false);
prop_weak(false);
prop_inherently_weak(false);
}

View file

@ -425,7 +425,9 @@ namespace spot
prop(" stutter-invariant");
if (aut->prop_stutter_sensitive())
prop(" stutter-sensitive");
if (aut->prop_weak())
if (aut->prop_terminal())
prop(" terminal");
if (aut->prop_weak() && (verbose || !aut->prop_terminal()))
prop(" weak");
if (aut->prop_inherently_weak() && (verbose || !aut->prop_weak()))
prop(" inherently-weak");

View file

@ -1972,6 +1972,8 @@ namespace spot
}
bdd all_events = observable_events | unobservable_events;
auto orig_f = f2;
// This is in case the initial state is equivalent to true...
if (symb_merge)
f2 = fc.canonize(f2);
@ -2172,9 +2174,6 @@ namespace spot
}
}
// Set the following to true to preserve state names.
a->release_formula_namer(namer, false);
auto& acc = a->acc();
unsigned ns = a->num_states();
for (unsigned s = 0; s < ns; ++s)
@ -2185,10 +2184,18 @@ namespace spot
a->prop_inherently_weak(f2.is_syntactic_persistence());
a->prop_stutter_invariant(f2.is_syntactic_stutter_invariant());
if (orig_f.is_syntactic_guarantee())
{
a->prop_terminal(true);
assert(a->num_sets() <= 1);
}
// Currently the unambiguous option work only with LTL.
a->prop_unambiguous(f2.is_ltl_formula() && unambiguous);
// Set the following to true to preserve state names.
a->release_formula_namer(namer, false);
if (!simplifier)
// This should not be deleted before we have registered all propositions.
delete s;

View file

@ -584,6 +584,16 @@ namespace spot
res->prop_copy(a, { false, false, false, true });
res->prop_deterministic(true);
res->prop_weak(true);
// If the input was terminal, then the output is also terminal.
// FIXME:
// (1) We should have a specialized version of this function for
// the case where the input is terminal. See issue #120.
// (2) It would be nice to have a more precise detection of
// terminal automata in the output. Calling
// is_guarantee_automaton() seems overkill here. But maybe we can
// add a quick check inside minimize_dfa.
if (a->prop_terminal())
res->prop_terminal(true);
return res;
}

View file

@ -27,6 +27,8 @@ namespace spot
is_guarantee_automaton(const const_twa_graph_ptr& aut,
scc_info* si)
{
if (aut->prop_terminal())
return true;
// Create an scc_info if the user did not give one to us.
bool need_si = !si;
if (need_si)