ltl2tgba_fm: produce unambiguous automata for PSL as well

* src/twaalgos/ltl2tgba_fm.cc: Fix the PSL operators.
* src/tests/unambig.test: Add more tests.
This commit is contained in:
Alexandre Duret-Lutz 2015-05-12 20:18:42 +02:00
parent 778d8fe95b
commit 5d76b9127b
2 changed files with 108 additions and 49 deletions

View file

@ -31,7 +31,8 @@ for f in 'Ga' \
'Ga | FGb' \
'XFGa | GFb | Gc' \
'(Ga -> Gb) W c' \
'F(a & !b & (!c W b))'
'F(a & !b & (!c W b))' \
'G({{1;1}*}<>->a)'
do
$ltl2tgba -UH "$f" | $autfilt -q --is-unambiguous
$ltl2tgba -UH "!($f)" | $autfilt -q --is-unambiguous
@ -39,7 +40,7 @@ do
$ltl2tgba -UH "!($f)" | $autfilt --check | grep unambiguous
done
for f in FGa
for f in FGa '(({p1[*0..1]}[]-> 0) R XFp0)'
do
$ltl2tgba -H "$f" | $autfilt -qv --is-unambiguous
$ltl2tgba -UH "$f" | $autfilt -q --is-unambiguous
@ -86,3 +87,9 @@ EOF
run 1 $autfilt -q --is-unambiguous input
run 0 $autfilt --check input > output
test `grep -c unambiguous output` = 0
# Check 1000 random PSL formulas
../../bin/randltl --psl -n 1000 3 | $ltl2tgba -U -F- -H |
$autfilt -v --is-unamb --stats=%M && exit 1
:

View file

@ -1690,15 +1690,33 @@ namespace spot
const formula* dest2 =
binop::instance(op, dest, node->second()->clone());
bool unamb = dict_.unambiguous;
if (dest2 != constant::false_instance())
{
// If the rhs is Boolean, the
// unambiguous code will produce a more
// deterministic automaton at no additional
// cost. You can test this on
// G({{1;1}*}<>->a)
if (node->second()->is_boolean())
unamb = true;
int x = dict_.register_next_variable(dest2);
dest2->destroy();
res_ |= label & bdd_ithvar(x);
bdd toadd = label & bdd_ithvar(x);
if (dest->accepts_eword() && unamb)
toadd &= neg_of(node->second());
res_ |= toadd;
}
if (dest->accepts_eword())
res_ |= label & f2;
{
bdd toadd = label & f2;
if (unamb)
// Preserve determinism
toadd &= bdd_ithvar(dict_.register_next_variable
(constant::true_instance()));
res_ |= toadd;
}
}
}
else
@ -1739,24 +1757,49 @@ namespace spot
// word should recognize f2, and the automaton for f1
// should be understood as universal.
//
// The crux of this translation (the use of implication,
// and the interpretation as a universal automaton) was
// explained to me (adl) by Felix Klaedtke.
// The crux of this translation (i.e., the
// interpretation of first() as a universal automaton,
// and using implication to encode it) was explained
// to me (adl) by Felix Klaedtke.
bdd f2 = recurse(node->second());
bdd f1 = translate_ratexp(node->first(), dict_);
res_ = bddtrue;
if (exprop_)
{
res_ = bddfalse;
bdd var_set = bdd_existcomp(bdd_support(f1), dict_.var_set);
bdd all_props = bdd_existcomp(f1, dict_.var_set);
bdd missing = !all_props;
while (all_props != bddfalse)
{
bdd label = bdd_satoneset(all_props, var_set, bddtrue);
all_props -= label;
bdd one_prop_set = bddtrue;
if (exprop_)
one_prop_set = bdd_satoneset(all_props, var_set, bddtrue);
all_props -= one_prop_set;
const formula* dest =
dict_.bdd_to_sere(bdd_exist(f1 & label, dict_.var_set));
minato_isop isop(f1 & one_prop_set);
const formula* dest2 =
binop::instance(op, dest, node->second()->clone());
bdd udest =
bdd_ithvar(dict_.register_next_variable(dest2));
if (dest->accepts_eword())
udest &= f2;
dest2->destroy();
res_ |= label & udest;
}
// Make the automaton complete.
res_ |= missing &
// stick X(1) to preserve determinism.
bdd_ithvar(dict_.register_next_variable
(constant::true_instance()));
}
else
{
res_ = bddtrue;
minato_isop isop(f1);
bdd cube;
while ((cube = isop.next()) != bddfalse)
{
@ -1773,7 +1816,6 @@ namespace spot
udest &= f2;
dest2->destroy();
res_ &= bdd_apply(label, udest, bddop_imp);
}
}
@ -2081,7 +2123,16 @@ namespace spot
{
bdd res = bddfalse;
minato_isop isop(t.symbolic);
bdd var_set = bdd_existcomp(bdd_support(t.symbolic), d_.var_set);
bdd all_props = bdd_existcomp(t.symbolic, d_.var_set);
while (all_props != bddfalse)
{
bdd one_prop_set = bddtrue;
if (d_.exprop)
one_prop_set = bdd_satoneset(all_props, var_set, bddtrue);
all_props -= one_prop_set;
minato_isop isop(t.symbolic & one_prop_set);
bdd cube;
while ((cube = isop.next()) != bddfalse)
{
@ -2118,6 +2169,7 @@ namespace spot
dest->destroy();
res |= label & dest_bdd;
}
}
t.symbolic = res;
// std::cerr << "Marking rewriting:" << std::endl;
// trace_ltl_bdd(v_.get_dict(), t.symbolic);