implement SVA's first_match operator

* NEWS, doc/tl/tl.tex, doc/tl/tl.bib: Document it.
* spot/parsetl/parsetl.yy, spot/parsetl/scantl.ll: Parse it.
* spot/tl/formula.cc, spot/tl/formula.hh, spot/tl/dot.cc,
spot/tl/mutation.cc, spot/tl/print.cc, spot/tl/randomltl.cc,
spot/twaalgos/ltl2tgba_fm.cc: Adjust to support first_match.
* spot/tl/mark.cc, spot/tl/simplify.cc, spot/tl/snf.cc,
spot/tl/unabbrev.cc, spot/twa/formula2bdd.cc,
spot/twaalgos/ltl2taa.cc: Ignore it.
* tests/core/acc_word.test, tests/core/randpsl.test: Add more tests.
* tests/core/rand.test, tests/core/unambig.test,
tests/python/randltl.ipynb: Adjust.
* tests/python/formulas.ipynb: Show first_match.
This commit is contained in:
Alexandre Duret-Lutz 2019-05-06 14:59:05 +02:00
parent caf1eaa4ce
commit 6fac026454
24 changed files with 359 additions and 162 deletions

View file

@ -121,6 +121,7 @@ namespace spot
case op::AndNLM:
case op::AndRat:
case op::OrRat:
case op::first_match:
SPOT_UNIMPLEMENTED();
case op::U:

View file

@ -867,6 +867,35 @@ namespace spot
}
return res;
}
case op::first_match:
{
assert(f.size() == 1);
assert(!f.accepts_eword());
// Build deterministic successors, and
// rewrite each destination D as first_match(D).
// This will handle the semantic of the operator automatically,
// since first_match(D) = [*0] if D accepts [*0].
bdd res_ndet = recurse(f[0]);
bdd res_det = bddfalse;
bdd var_set = bdd_existcomp(bdd_support(res_ndet), dict_.var_set);
bdd all_props = bdd_existcomp(res_ndet, dict_.var_set);
while (all_props != bddfalse)
{
bdd label = bdd_satoneset(all_props, var_set, bddtrue);
all_props -= label;
formula dest =
dict_.bdd_to_sere(bdd_appex(res_ndet, label, bddop_and,
dict_.var_set));
dest = formula::first_match(dest);
if (to_concat_)
dest = formula::Concat({dest, to_concat_});
if (!dest.is_ff())
res_det |= label
& bdd_ithvar(dict_.register_next_variable(dest));
}
return res_det;
}
}
SPOT_UNREACHABLE();
}
@ -1311,6 +1340,7 @@ namespace spot
}
case op::Star:
case op::FStar:
case op::first_match:
SPOT_UNREACHABLE(); // Not an LTL operator
// r(f1 logical-op f2) = r(f1) logical-op r(f2)
case op::Xor: