hoaparse: validate use of deterministic and complete

* src/hoaparse/hoaparse.yy: validate deterministic and
complete when parsing HOA.  Also set the deterministic
property on the TGBA.
* src/tgbatest/hoaparse.test: Test errors.
This commit is contained in:
Alexandre Duret-Lutz 2015-01-05 14:59:51 +01:00
parent 578e390d8d
commit 0b8b65f96f
2 changed files with 155 additions and 2 deletions

View file

@ -98,6 +98,10 @@
bool accept_all_needed = false;
bool accept_all_seen = false;
bool aliased_states = false;
bool deterministic = false;
bool complete = false;
std::map<std::string, spot::location> labels;
~result_()
@ -312,6 +316,43 @@ header: format-version header-items
}
}
}
{
unsigned ss = res.start.size();
if (ss > 1)
{
auto det = res.props.find("deterministic");
if (det != res.props.end())
{
error(det->second,
"deterministic automata should have at most "
"one initial state");
}
res.deterministic = false;
}
else
{
// Assume the automaton is deterministic until proven
// wrong.
res.deterministic = true;
}
if (ss < 1)
{
auto complete = res.props.find("complete");
if (complete != res.props.end())
{
error(complete->second,
"complete automata should have at least "
"one initial state");
}
res.complete = false;
}
else
{
// Assume the automaton is complete until proven
// wrong.
res.complete = true;
}
}
}
version: IDENTIFIER
@ -639,6 +680,39 @@ checked-state-num: state-num
}
states: | states state
{
if (res.deterministic || res.complete)
{
bdd available = bddtrue;
bool det = true;
for (auto& t: res.h->aut->out(res.cur_state))
{
if (det && !bdd_implies(t.cond, available))
det = false;
available -= t.cond;
}
if (res.deterministic && !det)
{
res.deterministic = false;
auto p = res.props.find("deterministic");
if (p != res.props.end())
{
error(@2, "automaton is not deterministic...");
error(p->second, "... despite 'property: deterministic'");
}
}
if (res.complete && available != bddfalse)
{
res.complete = false;
auto p = res.props.find("complete");
if (p != res.props.end())
{
error(@2, "automaton is not complete...");
error(p->second, "... despite 'property: complete'");
}
}
}
}
state: state-name labeled-edges
| state-name unlabeled-edges
{
@ -661,6 +735,11 @@ state: state-name labeled-edges
}
}
| error
{
// Assume the worse.
res.deterministic = false;
res.complete = false;
}
state-name: "State:" state-label_opt checked-state-num string_opt acc-sig_opt
{
@ -1066,6 +1145,7 @@ lbtt-header: lbtt-header-states INT_S
lbtt-body: lbtt-states
lbtt-states:
| lbtt-states lbtt-state lbtt-transitions
lbtt-state: STATE_NUM INT lbtt-acc
{
res.cur_state = $1;
@ -1225,6 +1305,12 @@ static void fix_initial_state(result_& r)
}
}
static void fix_properties(result_& r)
{
r.h->aut->prop_deterministic(r.deterministic);
//r.h->aut->prop_complete(r.complete);
}
namespace spot
{
hoa_stream_parser::hoa_stream_parser(const std::string& name)
@ -1272,6 +1358,7 @@ namespace spot
if (r.neg_acc_sets)
fix_acceptance(r);
fix_initial_state(r);
fix_properties(r);
return r.h;
};
}