acc: add a maybe_accepting() method

* spot/twa/acc.cc, spot/twa/acc.hh: Implement the new method, and
use it to implement inf_accepting().
* tests/python/accparse2.py: Add some tests.
This commit is contained in:
Alexandre Duret-Lutz 2017-05-30 18:04:57 +02:00
parent f7d14ab526
commit 78add1d44b
3 changed files with 54 additions and 13 deletions

View file

@ -215,39 +215,52 @@ namespace spot
return false; return false;
} }
static bool static trival
inf_eval(acc_cond::mark_t inf, const acc_cond::acc_word* pos) partial_eval(acc_cond::mark_t infinitely_often,
acc_cond::mark_t always_present,
const acc_cond::acc_word* pos)
{ {
switch (pos->sub.op) switch (pos->sub.op)
{ {
case acc_cond::acc_op::And: case acc_cond::acc_op::And:
{ {
auto sub = pos - pos->sub.size; auto sub = pos - pos->sub.size;
trival res = true;
while (sub < pos) while (sub < pos)
{ {
--pos; --pos;
if (!inf_eval(inf, pos)) res = res &&
return false; partial_eval(infinitely_often, always_present, pos);
if (res.is_false())
return res;
pos -= pos->sub.size; pos -= pos->sub.size;
} }
return true; return res;
} }
case acc_cond::acc_op::Or: case acc_cond::acc_op::Or:
{ {
auto sub = pos - pos->sub.size; auto sub = pos - pos->sub.size;
trival res = false;
while (sub < pos) while (sub < pos)
{ {
--pos; --pos;
if (inf_eval(inf, pos)) res = res ||
return true; partial_eval(infinitely_often, always_present, pos);
if (res.is_true())
return res;
pos -= pos->sub.size; pos -= pos->sub.size;
} }
return false; return res;
} }
case acc_cond::acc_op::Inf: case acc_cond::acc_op::Inf:
return (pos[-1].mark & inf) == pos[-1].mark; return (pos[-1].mark & infinitely_often) == pos[-1].mark;
case acc_cond::acc_op::Fin: case acc_cond::acc_op::Fin:
return true; if (pos[-1].mark & always_present)
return false;
else if (pos[-1].mark & infinitely_often)
return trival::maybe();
else
return true;
case acc_cond::acc_op::FinNeg: case acc_cond::acc_op::FinNeg:
case acc_cond::acc_op::InfNeg: case acc_cond::acc_op::InfNeg:
SPOT_UNREACHABLE(); SPOT_UNREACHABLE();
@ -310,13 +323,21 @@ namespace spot
return eval(inf, &back()); return eval(inf, &back());
} }
bool acc_cond::acc_code::inf_satisfiable(mark_t inf) const trival acc_cond::acc_code::maybe_accepting(mark_t infinitely_often,
mark_t always_present) const
{ {
if (empty()) if (empty())
return true; return true;
return inf_eval(inf, &back()); return partial_eval(infinitely_often | always_present,
always_present, &back());
} }
bool acc_cond::acc_code::inf_satisfiable(mark_t inf) const
{
return !maybe_accepting(inf, 0U).is_false();
}
acc_cond::mark_t acc_cond::accepting_sets(mark_t inf) const acc_cond::mark_t acc_cond::accepting_sets(mark_t inf) const
{ {
if (uses_fin_acceptance()) if (uses_fin_acceptance())

View file

@ -24,6 +24,7 @@
#include <sstream> #include <sstream>
#include <vector> #include <vector>
#include <spot/tl/defaultenv.hh> #include <spot/tl/defaultenv.hh>
#include <spot/misc/trival.hh>
#include <iostream> #include <iostream>
namespace spot namespace spot
@ -888,6 +889,10 @@ namespace spot
bool inf_satisfiable(mark_t inf) const; bool inf_satisfiable(mark_t inf) const;
trival maybe_accepting(mark_t infinitely_often,
mark_t always_present) const;
// Remove all the acceptance sets in rem. // Remove all the acceptance sets in rem.
// //
// If MISSING is set, the acceptance sets are assumed to be // If MISSING is set, the acceptance sets are assumed to be
@ -1238,6 +1243,11 @@ namespace spot
return code_.inf_satisfiable(inf); return code_.inf_satisfiable(inf);
} }
trival maybe_accepting(mark_t infinitely_often, mark_t always_present) const
{
return code_.maybe_accepting(infinitely_often, always_present);
}
mark_t accepting_sets(mark_t inf) const; mark_t accepting_sets(mark_t inf) const;
std::ostream& format(std::ostream& os, mark_t m) const std::ostream& format(std::ostream& os, mark_t m) const

View file

@ -1,5 +1,5 @@
# -*- mode: python; coding: utf-8 -*- # -*- mode: python; coding: utf-8 -*-
# Copyright (C) 2015 Laboratoire de Recherche et Développement # Copyright (C) 2015, 2017 Laboratoire de Recherche et Développement
# de l'Epita # de l'Epita
# #
# This file is part of Spot, a model checking library. # This file is part of Spot, a model checking library.
@ -31,6 +31,16 @@ a.set_acceptance('Inf(4) | (Fin(3)&Inf(2)) | (Fin(3)&Fin(1)&Inf(0))')
assert(a.is_parity()[0] == False) assert(a.is_parity()[0] == False)
assert(a.is_parity(True) == [True, True, False]) assert(a.is_parity(True) == [True, True, False])
assert a.maybe_accepting([1, 2, 3], [0, 4]).is_true()
assert a.maybe_accepting([0], []).is_true()
assert a.maybe_accepting([0], [3]).is_false()
assert a.maybe_accepting([0, 3], []).is_maybe()
assert a.maybe_accepting([2, 3], [3]).is_false()
assert a.maybe_accepting([2, 3], []).is_maybe()
assert a.maybe_accepting([2], []).is_true()
assert a.maybe_accepting([0, 1], []).is_maybe()
assert a.maybe_accepting([0, 1], [1]).is_false()
a = spot.acc_cond(0) a = spot.acc_cond(0)
a.set_acceptance('all') a.set_acceptance('all')
assert(a.is_rabin() == -1) assert(a.is_rabin() == -1)