hoa: add support for unlabeled transitions
* src/hoaparse/hoaparse.yy: Here. * src/tgbatest/hoaparse.test: Add tests.
This commit is contained in:
parent
1d962f79ac
commit
69678152b6
2 changed files with 185 additions and 27 deletions
|
|
@ -45,6 +45,8 @@
|
||||||
spot::hoa_aut_ptr h;
|
spot::hoa_aut_ptr h;
|
||||||
spot::ltl::environment* env;
|
spot::ltl::environment* env;
|
||||||
std::vector<int> ap;
|
std::vector<int> ap;
|
||||||
|
std::vector<bdd> guards;
|
||||||
|
std::vector<bdd>::const_iterator cur_guard;
|
||||||
spot::location states_loc;
|
spot::location states_loc;
|
||||||
spot::location ap_loc;
|
spot::location ap_loc;
|
||||||
spot::location state_label_loc;
|
spot::location state_label_loc;
|
||||||
|
|
@ -59,7 +61,6 @@
|
||||||
bdd state_label;
|
bdd state_label;
|
||||||
bdd cur_label;
|
bdd cur_label;
|
||||||
bool has_state_label = false;
|
bool has_state_label = false;
|
||||||
bool has_trans_label = false;
|
|
||||||
bool ignore_more_ap = false; // Set to true after the first "AP:"
|
bool ignore_more_ap = false; // Set to true after the first "AP:"
|
||||||
// line has been read.
|
// line has been read.
|
||||||
bool ignore_acc = false; // Set to true in case of missing
|
bool ignore_acc = false; // Set to true in case of missing
|
||||||
|
|
@ -92,6 +93,8 @@
|
||||||
We must ensure that YYSTYPE is declared (by the above %union)
|
We must ensure that YYSTYPE is declared (by the above %union)
|
||||||
before parsedecl.hh uses it. */
|
before parsedecl.hh uses it. */
|
||||||
#include "parsedecl.hh"
|
#include "parsedecl.hh"
|
||||||
|
|
||||||
|
static void fill_guards(result_& res);
|
||||||
}
|
}
|
||||||
|
|
||||||
%token HOA "HOA:"
|
%token HOA "HOA:"
|
||||||
|
|
@ -446,7 +449,16 @@ state-num: INT
|
||||||
}
|
}
|
||||||
|
|
||||||
states: | states state
|
states: | states state
|
||||||
state: state-name edges
|
state: state-name labeled-edges
|
||||||
|
| state-name unlabeled-edges
|
||||||
|
{
|
||||||
|
if (!res.has_state_label)
|
||||||
|
{
|
||||||
|
if (res.cur_guard != res.guards.end())
|
||||||
|
error(@$, "not enough transitions for this state");
|
||||||
|
res.cur_guard = res.guards.begin();
|
||||||
|
}
|
||||||
|
}
|
||||||
state-name: "State:" state-label_opt state-num string_opt acc-sig_opt
|
state-name: "State:" state-label_opt state-num string_opt acc-sig_opt
|
||||||
{
|
{
|
||||||
res.cur_state = $3;
|
res.cur_state = $3;
|
||||||
|
|
@ -461,19 +473,14 @@ state-label_opt: { res.has_state_label = false; }
|
||||||
| label { res.has_state_label = true;
|
| label { res.has_state_label = true;
|
||||||
res.state_label_loc = @1;
|
res.state_label_loc = @1;
|
||||||
res.state_label = res.cur_label; }
|
res.state_label = res.cur_label; }
|
||||||
trans-label_opt: { res.has_trans_label = false; }
|
trans-label: label
|
||||||
| label
|
|
||||||
{
|
{
|
||||||
if (res.has_state_label)
|
if (res.has_state_label)
|
||||||
{
|
{
|
||||||
error(@1, "cannot label this transition because...");
|
error(@1, "cannot label this transition because...");
|
||||||
error(res.state_label_loc,
|
error(res.state_label_loc,
|
||||||
"... the state is already labeled.");
|
"... the state is already labeled.");
|
||||||
res.has_trans_label = false;
|
res.cur_label = res.state_label;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
res.has_trans_label = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -503,27 +510,72 @@ acc-sets:
|
||||||
else
|
else
|
||||||
$$ = $1 | res.h->aut->acc().mark($2);
|
$$ = $1 | res.h->aut->acc().mark($2);
|
||||||
}
|
}
|
||||||
edges: | edges edge
|
labeled-edges: | labeled-edges labeled-edge
|
||||||
edge: trans-label_opt state-num acc-sig_opt
|
labeled-edge: trans-label state-num acc-sig_opt
|
||||||
{
|
{
|
||||||
bdd cond = bddfalse;
|
res.h->aut->new_transition(res.cur_state, $2,
|
||||||
if (res.has_state_label)
|
res.cur_label, $3 | res.acc_state);
|
||||||
cond = res.state_label;
|
}
|
||||||
else if (res.has_trans_label)
|
| trans-label state-conj-2 acc-sig_opt
|
||||||
cond = res.cur_label;
|
{
|
||||||
else
|
error(@2, "alternation is not yet supported");
|
||||||
error(@$, "unlabeled transitions are not yet supported");
|
YYABORT;
|
||||||
res.h->aut->new_transition(res.cur_state, $2, cond,
|
}
|
||||||
$3 | res.acc_state);
|
|
||||||
}
|
/* We never have zero unlabeled edges, these are considered as zero
|
||||||
| trans-label_opt state-conj-2 acc-sig_opt
|
labeled edges. */
|
||||||
{
|
unlabeled-edges: unlabeled-edge | unlabeled-edges unlabeled-edge
|
||||||
error(@2, "alternation is not yet supported");
|
unlabeled-edge: state-num acc-sig_opt
|
||||||
YYABORT;
|
{
|
||||||
}
|
bdd cond;
|
||||||
|
if (res.has_state_label)
|
||||||
|
{
|
||||||
|
cond = res.state_label;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (res.guards.empty())
|
||||||
|
fill_guards(res);
|
||||||
|
if (res.cur_guard == res.guards.end())
|
||||||
|
{
|
||||||
|
error(@$, "too many transition for this state, "
|
||||||
|
"ignoring this one");
|
||||||
|
cond = bddfalse;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cond = *res.cur_guard++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
res.h->aut->new_transition(res.cur_state, $1,
|
||||||
|
cond, $2 | res.acc_state);
|
||||||
|
}
|
||||||
|
| state-conj-2 acc-sig_opt
|
||||||
|
{
|
||||||
|
error(@1, "alternation is not yet supported");
|
||||||
|
YYABORT;
|
||||||
|
}
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
|
static void fill_guards(result_& r)
|
||||||
|
{
|
||||||
|
spot::bdd_dict_ptr d = r.h->aut->get_dict();
|
||||||
|
unsigned nap = r.ap.size();
|
||||||
|
|
||||||
|
int* vars = new int[nap];
|
||||||
|
for (unsigned i = 0; i < nap; ++i)
|
||||||
|
vars[i] = r.ap[nap - 1 - i];
|
||||||
|
|
||||||
|
// build the 2^nap possible guards
|
||||||
|
r.guards.reserve(1U << nap);
|
||||||
|
for (size_t i = 0; i < (1U << nap); ++i)
|
||||||
|
r.guards.push_back(bdd_ibuildcube(i, nap, vars));
|
||||||
|
r.cur_guard = r.guards.begin();
|
||||||
|
|
||||||
|
delete[] vars;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
hoayy::parser::error(const location_type& location,
|
hoayy::parser::error(const location_type& location,
|
||||||
const std::string& message)
|
const std::string& message)
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,15 @@ expecterr()
|
||||||
diff $1.err $1.exp
|
diff $1.err $1.exp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
expectok()
|
||||||
|
{
|
||||||
|
cat >$1.exp
|
||||||
|
../../bin/autfilt --hoa $1 >$1.out
|
||||||
|
test $? = 0
|
||||||
|
cat $1.out
|
||||||
|
diff $1.out $1.exp
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
cat >input <<EOF
|
cat >input <<EOF
|
||||||
HOA: v1
|
HOA: v1
|
||||||
|
|
@ -175,6 +184,7 @@ input:9.11: number is larger than the count of acceptance sets...
|
||||||
input:5.1-13: ... declared here.
|
input:5.1-13: ... declared here.
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
# Let's have two broken automata in a row...
|
||||||
cat >input <<EOF
|
cat >input <<EOF
|
||||||
HOA: v1
|
HOA: v1
|
||||||
Start: 0
|
Start: 0
|
||||||
|
|
@ -198,3 +208,99 @@ input:5.1-13: ... declared here.
|
||||||
input:12.1-7: unsupported version of the HOA format
|
input:12.1-7: unsupported version of the HOA format
|
||||||
input:12.1-7: missing 'Acceptance:' header
|
input:12.1-7: missing 'Acceptance:' header
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
cat >input<<EOF
|
||||||
|
HOA: v1
|
||||||
|
States: 3
|
||||||
|
Start: 0
|
||||||
|
acc-name: generalized-Buchi 2
|
||||||
|
Acceptance: 2 (Inf(0) & Inf(1))
|
||||||
|
AP: 2 "a" "b"
|
||||||
|
--BODY--
|
||||||
|
State: 0 "foo" { 0 }
|
||||||
|
2 /* !a & !b */
|
||||||
|
0 /* a & !b */
|
||||||
|
1 /* !a & b */
|
||||||
|
1 /* a & b */
|
||||||
|
State: 1 { 1 }
|
||||||
|
1 1 1 1 /* four transitions on one line */
|
||||||
|
State: 2 "sink state" { 0 }
|
||||||
|
2 2 2 2
|
||||||
|
--END--
|
||||||
|
EOF
|
||||||
|
|
||||||
|
expectok input <<EOF
|
||||||
|
HOA: v1
|
||||||
|
States: 3
|
||||||
|
Start: 0
|
||||||
|
AP: 2 "a" "b"
|
||||||
|
acc-name: generalized-Buchi 2
|
||||||
|
Acceptance: 2 Inf(0)&Inf(1)
|
||||||
|
properties: trans-labels explicit-labels state-acc complete deterministic
|
||||||
|
--BODY--
|
||||||
|
State: 0 {0}
|
||||||
|
[!0&!1] 1
|
||||||
|
[0&!1] 0
|
||||||
|
[!0&1] 2
|
||||||
|
[0&1] 2
|
||||||
|
State: 1 {0}
|
||||||
|
[!0&!1] 1
|
||||||
|
[0&!1] 1
|
||||||
|
[!0&1] 1
|
||||||
|
[0&1] 1
|
||||||
|
State: 2 {1}
|
||||||
|
[!0&!1] 2
|
||||||
|
[0&!1] 2
|
||||||
|
[!0&1] 2
|
||||||
|
[0&1] 2
|
||||||
|
--END--
|
||||||
|
EOF
|
||||||
|
|
||||||
|
cat >input<<EOF
|
||||||
|
HOA: v1
|
||||||
|
States: 3
|
||||||
|
Start: 0
|
||||||
|
acc-name: generalized-Buchi 2
|
||||||
|
Acceptance: 2 (Inf(0) & Inf(1))
|
||||||
|
AP: 2 "a" "b"
|
||||||
|
--BODY--
|
||||||
|
State: 0 "foo" { 0 }
|
||||||
|
2 /* !a & !b */
|
||||||
|
0 /* a & !b */
|
||||||
|
1 /* !a & b */
|
||||||
|
/* missing transition */
|
||||||
|
State: 1 { 1 }
|
||||||
|
1 1 1 1 /* four transitions on one line */
|
||||||
|
State: 2 "sink state" { 0 }
|
||||||
|
2 2 2 2
|
||||||
|
--END--
|
||||||
|
EOF
|
||||||
|
|
||||||
|
expecterr input <<EOF
|
||||||
|
input:8.5-11.7: not enough transitions for this state
|
||||||
|
EOF
|
||||||
|
|
||||||
|
cat >input<<EOF
|
||||||
|
HOA: v1
|
||||||
|
States: 3
|
||||||
|
Start: 0
|
||||||
|
acc-name: generalized-Buchi 2
|
||||||
|
Acceptance: 2 (Inf(0) & Inf(1))
|
||||||
|
AP: 2 "a" "b"
|
||||||
|
--BODY--
|
||||||
|
State: 0 "foo" { 0 }
|
||||||
|
2 /* !a & !b */
|
||||||
|
0 /* a & !b */
|
||||||
|
1 /* !a & b */
|
||||||
|
1 /* a & b */
|
||||||
|
2 /* extra transition ! */
|
||||||
|
State: 1 { 1 }
|
||||||
|
1 1 1 1 /* four transitions on one line */
|
||||||
|
State: 2 "sink state" { 0 }
|
||||||
|
2 2 2 2
|
||||||
|
--END--
|
||||||
|
EOF
|
||||||
|
|
||||||
|
expecterr input <<EOF
|
||||||
|
input:13.7: too many transition for this state, ignoring this one
|
||||||
|
EOF
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue