Commit 4993e807 authored by Alexandre Duret-Lutz's avatar Alexandre Duret-Lutz

acc: simplify interface using operators

* spot/twa/acc.hh, spot/twa/acc.cc: Here.  Also remove
some redundant functions.
* spot/parseaut/parseaut.yy, spot/priv/accmap.hh, spot/tests/acc.cc,
spot/tests/twagraph.cc, spot/twa/taatgba.hh, spot/twa/twaproduct.cc,
spot/twaalgos/dtwasat.cc, spot/twaalgos/hoa.cc, spot/twaalgos/lbtt.cc,
spot/twaalgos/ltl2tgba_fm.cc, spot/twaalgos/product.cc,
spot/twaalgos/remfin.cc, spot/twaalgos/simulation.cc,
spot/twaalgos/tau03opt.cc, spot/twaalgos/weight.cc,
spot/twaalgos/weight.hh: Adjust.
* NEWS: Mention the changes.
parent c39d35d0
......@@ -33,6 +33,21 @@ New in spot 1.99.6a (not yet released)
instead of just weak SCCs. This gets rid of some corner cases
that used to require ad hoc handling.
* acc_cond::acc_code's methods append_or(), append_and(), and
shift_left() have been replaced by operators |=, &=, <<=, and for
completeness the operators |, &, and << have been added.
* Several methods have been removed from the acc_cond class because
they were simply redundant with the methods of acc_cond::mark_t,
and more complex to use.
acc_cond::marks(...) -> use acc_cond::mark_t(...) directly
acc_cond::sets(m) -> use m.sets()
acc_cond::has(m, u) -> use m.has(u) directly
acc_cond::cup(l, r) -> use l | r
acc_cond::cap(l, r) -> use l & r
acc_cond::set_minus(l, r) -> use l - r
Python:
* Iterating over the transitions leaving a state (the
......
......@@ -786,13 +786,13 @@ acceptance-cond: IDENTIFIER '(' acc-set ')'
}
| acceptance-cond '&' acceptance-cond
{
$3->append_and(std::move(*$1));
*$3 &= std::move(*$1);
$$ = $3;
delete $1;
}
| acceptance-cond '|' acceptance-cond
{
$3->append_or(std::move(*$1));
*$3 |= std::move(*$1);
$$ = $3;
delete $1;
}
......@@ -1804,7 +1804,7 @@ fix_acceptance_aux(spot::acc_cond& acc,
while (sub < pos)
{
--pos;
c.append_and(fix_acceptance_aux(acc, in, pos, onlyneg, both, base));
c &= fix_acceptance_aux(acc, in, pos, onlyneg, both, base);
pos -= in[pos].size;
}
return c;
......@@ -1818,7 +1818,7 @@ fix_acceptance_aux(spot::acc_cond& acc,
while (sub < pos)
{
--pos;
c.append_or(fix_acceptance_aux(acc, in, pos, onlyneg, both, base));
c |= fix_acceptance_aux(acc, in, pos, onlyneg, both, base);
pos -= in[pos].size;
}
return c;
......@@ -1839,7 +1839,7 @@ fix_acceptance_aux(spot::acc_cond& acc,
++base;
}
if (tmp)
c.append_or(acc.fin(tmp));
c |= acc.fin(tmp);
return c;
}
case spot::acc_cond::acc_op::InfNeg:
......@@ -1854,7 +1854,7 @@ fix_acceptance_aux(spot::acc_cond& acc,
++base;
}
if (tmp)
c.append_and(acc.inf(tmp));
c &= acc.inf(tmp);
return c;
}
}
......@@ -1886,7 +1886,7 @@ static void fix_acceptance(result_& r)
unsigned base = 0;
if (both)
{
auto v = acc.sets(both);
auto v = both.sets();
auto vs = v.size();
base = acc.add_sets(vs);
for (auto& t: r.h->aut->edge_vector())
......
......@@ -64,7 +64,7 @@ namespace spot
auto p = map_.find(name);
if (p == map_.end())
return std::make_pair(false, 0U);
return std::make_pair(true, aut_->acc().marks({p->second}));
return std::make_pair(true, acc_cond::mark_t({p->second}));
}
};
......@@ -83,7 +83,7 @@ namespace spot
std::pair<bool, acc_cond::mark_t> lookup(unsigned n)
{
if (n < aut_->acc().num_sets())
return std::make_pair(true, aut_->acc().marks({n}));
return std::make_pair(true, acc_cond::mark_t({n}));
else
return std::make_pair(false, 0U);
}
......@@ -109,7 +109,7 @@ namespace spot
return std::make_pair(true, p->second);
if (used_ < aut_->acc().num_sets())
{
auto res = aut_->acc().marks({used_++});
auto res = acc_cond::mark_t({used_++});
map_[n] = res;
return std::make_pair(true, res);
}
......
......@@ -59,9 +59,9 @@ int main()
ac.set_generalized_buchi();
std::cout << ac.get_acceptance() << '\n';
auto m1 = ac.marks({0, 2});
auto m2 = ac.marks({0, 3});
auto m3 = ac.marks({2, 1});
auto m1 = spot::acc_cond::mark_t({0, 2});
auto m2 = spot::acc_cond::mark_t({0, 3});
auto m3 = spot::acc_cond::mark_t({2, 1});
check(ac, m1);
check(ac, m2);
......@@ -128,23 +128,23 @@ int main()
auto code1 = ac.inf({0, 1, 3});
std::cout << code1.size() << ' ' << code1 << ' ' << code1.is_dnf() << '\n';
code1.append_or(ac.fin({2}));
code1 |= ac.fin({2});
std::cout << code1.size() << ' ' << code1 << ' ' << code1.is_dnf() << '\n';
code1.append_or(ac.fin({0}));
code1 |= ac.fin({0});
std::cout << code1.size() << ' ' << code1 << ' ' << code1.is_dnf() << '\n';
code1.append_or(ac.fin({}));
code1 |= ac.fin({});
std::cout << code1.size() << ' ' << code1 << ' ' << code1.is_dnf() << '\n';
code1.append_and(ac.inf({}));
code1 &= ac.inf({});
std::cout << code1.size() << ' ' << code1 << ' ' << code1.is_dnf() << '\n';
auto code2 = code1;
code1.append_and(ac.fin({0, 1}));
code1 &= ac.fin({0, 1});
std::cout << code1.size() << ' ' << code1 << ' ' << code1.is_dnf() << '\n';
code1.append_and(ac.fin({}));
code1 &= ac.fin({});
std::cout << code1.size() << ' ' << code1 << ' ' << code1.is_dnf() << '\n';
code2.append_or(ac.fin({0, 1}));
code2 |= ac.fin({0, 1});
std::cout << code2.size() << ' ' << code2 << ' ' << code2.is_dnf() << '\n';
auto code3 = ac.inf({0, 1});
code3.append_and(ac.fin({2, 3}));
code3 &= ac.fin({2, 3});
std::cout << code3.size() << ' ' << code3 << ' ' << code3.is_dnf() << '\n';
// code3 == (Fin(2)|Fin(3)) & (Inf(0)&Inf(1))
......
......@@ -41,9 +41,9 @@ static void f1()
tg->new_edge(s1, s2, p1, 0U);
tg->new_edge(s1, s3, p2, tg->acc().mark(1));
tg->new_edge(s2, s3, p1 & p2, tg->acc().mark(0));
tg->new_edge(s3, s1, p1 | p2, tg->acc().marks({0, 1}));
tg->new_edge(s3, s1, p1 | p2, spot::acc_cond::mark_t({0, 1}));
tg->new_edge(s3, s2, p1 >> p2, 0U);
tg->new_edge(s3, s3, bddtrue, tg->acc().marks({0, 1}));
tg->new_edge(s3, s3, bddtrue, spot::acc_cond::mark_t({0, 1}));
spot::print_dot(std::cout, tg);
......@@ -63,7 +63,7 @@ static void f1()
spot::print_dot(std::cout, tg);
}
auto all = tg->acc().marks({0, 1});
spot::acc_cond::mark_t all({0, 1});
tg->new_edge(s3, s1, p1 | p2, all);
tg->new_edge(s3, s2, p1 >> p2, 0U);
tg->new_edge(s3, s1, bddtrue, all);
......
......@@ -538,9 +538,9 @@ namespace spot
for (int i = start; i != end; i += inc)
{
if ((i & 1) == odd)
res.append_or(inf({(unsigned)i}));
res |= inf({(unsigned)i});
else
res.append_and(fin({(unsigned)i}));
res &= fin({(unsigned)i});
}
return res;
}
......@@ -577,9 +577,9 @@ namespace spot
int p2 = mrand(s);
if (drand() < 0.5)
codes[p2].append_or(std::move(codes.back()));
codes[p2] |= std::move(codes.back());
else
codes[p2].append_and(std::move(codes.back()));
codes[p2] &= std::move(codes.back());
codes.pop_back();
}
......@@ -765,8 +765,7 @@ namespace spot
// The strange order here make sure we can smaller set
// numbers at the end of the acceptance code, i.e., at
// the front of the output.
auto a = fin(s);
a.append_and(std::move(c));
auto a = fin(s) & std::move(c);
std::swap(a, c);
}
else // Positive variable? -> Inf
......@@ -775,9 +774,9 @@ namespace spot
cube = h;
}
}
c.append_and(inf(i));
c &= inf(i);
// See comment above for the order.
c.append_or(std::move(rescode));
c |= std::move(rescode);
std::swap(c, rescode);
}
......@@ -838,8 +837,7 @@ namespace spot
// The strange order here make sure we can smaller set
// numbers at the end of the acceptance code, i.e., at
// the front of the output.
auto a = inf(s);
a.append_or(std::move(c));
auto a = inf(s) | std::move(c);
std::swap(a, c);
}
else // Positive variable? -> Fin
......@@ -848,9 +846,9 @@ namespace spot
cube = h;
}
}
c.append_or(fin(m));
c |= fin(m);
// See comment above for the order.
c.append_and(std::move(rescode));
c &= std::move(rescode);
std::swap(c, rescode);
}
return rescode;
......@@ -1069,8 +1067,7 @@ namespace spot
auto res = acc_cond::acc_code::f();
do
{
auto tmp = complement_rec(pos);
tmp.append_or(std::move(res));
auto tmp = complement_rec(pos) | std::move(res);
std::swap(tmp, res);
pos -= pos->size + 1;
}
......@@ -1083,8 +1080,7 @@ namespace spot
auto res = acc_cond::acc_code::t();
do
{
auto tmp = complement_rec(pos);
tmp.append_and(std::move(res));
auto tmp = complement_rec(pos) & std::move(res);
std::swap(tmp, res);
pos -= pos->size + 1;
}
......@@ -1128,8 +1124,7 @@ namespace spot
auto res = acc_cond::acc_code::t();
do
{
auto tmp = strip_rec(pos, rem, missing);
tmp.append_and(std::move(res));
auto tmp = strip_rec(pos, rem, missing) & std::move(res);
std::swap(tmp, res);
pos -= pos->size + 1;
}
......@@ -1142,8 +1137,7 @@ namespace spot
auto res = acc_cond::acc_code::f();
do
{
auto tmp = strip_rec(pos, rem, missing);
tmp.append_or(std::move(res));
auto tmp = strip_rec(pos, rem, missing) | std::move(res);
std::swap(tmp, res);
pos -= pos->size + 1;
}
......@@ -1313,7 +1307,7 @@ namespace spot
// Prepend instead of append, to preserve the input order.
auto tmp = parse_term(input);
std::swap(tmp, res);
res.append_or(std::move(tmp));
res |= std::move(tmp);
}
return res;
}
......@@ -1477,7 +1471,7 @@ namespace spot
// Prepend instead of append, to preserve the input order.
auto tmp = parse_term(input);
std::swap(tmp, res);
res.append_and(std::move(tmp));
res &= std::move(tmp);
}
return res;
}
......
......@@ -512,9 +512,7 @@ namespace spot
acc_cond::acc_code res = f();
while (n > 0)
{
acc_cond::acc_code pair = inf({2*n - 1});
pair.append_and(fin({2*n - 2}));
res.append_or(std::move(pair));
res |= inf({2*n - 1}) & fin({2*n - 2});
--n;
}
return res;
......@@ -526,9 +524,7 @@ namespace spot
acc_cond::acc_code res = t();
while (n > 0)
{
acc_cond::acc_code pair = inf({2*n - 1});
pair.append_or(fin({2*n - 2}));
res.append_and(std::move(pair));
res &= inf({2*n - 1}) | fin({2*n - 2});
--n;
}
return res;
......@@ -545,9 +541,9 @@ namespace spot
acc_cond::mark_t m = 0U;
for (unsigned ni = *i; ni > 0; --ni)
m.set(n++);
pair.append_and(inf(m));
pair &= inf(m);
std::swap(pair, res);
res.append_or(std::move(pair));
res |= std::move(pair);
}
return res;
}
......@@ -559,15 +555,15 @@ namespace spot
// acceptance formula.
static acc_code random(unsigned n, double reuse = 0.0);
void append_and(acc_code&& r)
acc_code& operator&=(acc_code&& r)
{
if (is_tt() || r.is_ff())
{
*this = std::move(r);
return;
return *this;
}
if (is_ff() || r.is_tt())
return;
return *this;
unsigned s = size() - 1;
unsigned rs = r.size() - 1;
// We want to group all Inf(x) operators:
......@@ -576,7 +572,7 @@ namespace spot
|| ((*this)[s].op == acc_op::InfNeg && r[rs].op == acc_op::InfNeg))
{
(*this)[s - 1].mark |= r[rs - 1].mark;
return;
return *this;
}
// In the more complex scenarios, left and right may both
......@@ -648,17 +644,18 @@ namespace spot
w.op = acc_op::And;
w.size = size();
push_back(w);
return *this;
}
void append_and(const acc_code& r)
acc_code& operator&=(const acc_code& r)
{
if (is_tt() || r.is_ff())
{
*this = r;
return;
return *this;
}
if (is_ff() || r.is_tt())
return;
return *this;
unsigned s = size() - 1;
unsigned rs = r.size() - 1;
// Inf(a) & Inf(b) = Inf(a & b)
......@@ -666,7 +663,7 @@ namespace spot
|| ((*this)[s].op == acc_op::InfNeg && r[rs].op == acc_op::InfNeg))
{
(*this)[s - 1].mark |= r[rs - 1].mark;
return;
return *this;
}
// In the more complex scenarios, left and right may both
......@@ -738,16 +735,31 @@ namespace spot
w.op = acc_op::And;
w.size = size();
push_back(w);
return *this;
}
void append_or(acc_code&& r)
acc_code operator&(acc_code&& r)
{
acc_code res = *this;
res &= r;
return res;
}
acc_code operator&(const acc_code& r)
{
acc_code res = *this;
res &= r;
return res;
}
acc_code& operator|=(acc_code&& r)
{
if (is_tt() || r.is_ff())
return;
return *this;
if (is_ff() || r.is_tt())
{
*this = std::move(r);
return;
return *this;
}
unsigned s = size() - 1;
unsigned rs = r.size() - 1;
......@@ -756,7 +768,7 @@ namespace spot
|| ((*this)[s].op == acc_op::FinNeg && r[rs].op == acc_op::FinNeg))
{
(*this)[s - 1].mark |= r[rs - 1].mark;
return;
return *this;
}
if ((*this)[s].op == acc_op::Or)
pop_back();
......@@ -767,12 +779,32 @@ namespace spot
w.op = acc_op::Or;
w.size = size();
push_back(w);
return *this;
}
void shift_left(unsigned sets)
acc_code& operator|=(const acc_code& r)
{
return *this |= acc_code(r);
}
acc_code operator|(acc_code&& r)
{
acc_code res = *this;
res |= r;
return res;
}
acc_code operator|(const acc_code& r)
{
acc_code res = *this;
res |= r;
return res;
}
acc_code& operator<<=(unsigned sets)
{
if (empty())
return;
return *this;
unsigned pos = size();
do
{
......@@ -792,6 +824,14 @@ namespace spot
}
}
while (pos > 0);
return *this;
}
acc_code operator<<(unsigned sets) const
{
acc_code res = *this;
res <<= sets;
return res;
}
bool is_dnf() const;
......@@ -854,8 +894,8 @@ namespace spot
friend std::ostream& operator<<(std::ostream& os, const acc_code& code);
};
acc_cond(unsigned n_sets = 0)
: num_(0U), all_(0U)
acc_cond(unsigned n_sets = 0, acc_code code = {})
: num_(0U), all_(0U), code_(code)
{
add_sets(n_sets);
}
......@@ -970,7 +1010,7 @@ namespace spot
acc_code inf(std::initializer_list<unsigned> vals) const
{
return inf(marks(vals.begin(), vals.end()));
return inf(mark_t(vals.begin(), vals.end()));
}
acc_code inf_neg(mark_t mark) const
......@@ -980,7 +1020,7 @@ namespace spot
acc_code inf_neg(std::initializer_list<unsigned> vals) const
{
return inf_neg(marks(vals.begin(), vals.end()));
return inf_neg(mark_t(vals.begin(), vals.end()));
}
acc_code fin(mark_t mark) const
......@@ -990,7 +1030,7 @@ namespace spot
acc_code fin(std::initializer_list<unsigned> vals) const
{
return fin(marks(vals.begin(), vals.end()));
return fin(mark_t(vals.begin(), vals.end()));
}
acc_code fin_neg(mark_t mark) const
......@@ -1000,7 +1040,7 @@ namespace spot
acc_code fin_neg(std::initializer_list<unsigned> vals) const
{
return fin_neg(marks(vals.begin(), vals.end()));
return fin_neg(mark_t(vals.begin(), vals.end()));
}
unsigned add_sets(unsigned num)
......@@ -1025,44 +1065,6 @@ namespace spot
return mark_(u);
}
template<class iterator>
mark_t marks(const iterator& begin, const iterator& end) const
{
return mark_t(begin, end);
}
mark_t marks(std::initializer_list<unsigned> vals) const
{
return marks(vals.begin(), vals.end());
}
// FIXME: Return some iterable object without building a vector.
std::vector<unsigned> sets(mark_t m) const
{
return m.sets();
}
// whether m contains u
bool has(mark_t m, unsigned u) const
{
return m.has(u);
}
mark_t cup(mark_t l, mark_t r) const
{
return l | r;
}
mark_t cap(mark_t l, mark_t r) const
{
return l & r;
}
mark_t set_minus(mark_t l, mark_t r) const
{
return l - r;
}
mark_t join(const acc_cond& la, mark_t lm,
const acc_cond& ra, mark_t rm) const
{
......
......@@ -196,7 +196,7 @@ namespace spot
{
auto p = acc_map_.emplace(f, 0);
if (p.second)
p.first->second = acc_.marks({acc_.add_set()});
p.first->second = acc_cond::mark_t({acc_.add_set()});
t->acceptance_conditions |= p.first->second;
}
......
......@@ -312,9 +312,8 @@ namespace spot
assert(num_sets() == 0);
auto left_num = left->num_sets();
auto right_acc = right->get_acceptance();
right_acc.shift_left(left_num);
right_acc.append_and(left->get_acceptance());
auto right_acc = right->get_acceptance() << left_num;
right_acc &= left->get_acceptance();
set_acceptance(left_num + right->num_sets(), right_acc);
}
......
......@@ -996,7 +996,7 @@ namespace spot
ta(q2, l,
d.cacc.mark(m), q3);
int tai = d.transaccid[ta];
if (d.cacc.has(biga, m))
if (biga.has(m))
tai = -tai;
out << tai << ' ';
}
......
......@@ -70,16 +70,14 @@ namespace spot
}
std::ostream&
emit_acc(std::ostream& os,
const const_twa_graph_ptr& aut,
acc_cond::mark_t b)
emit_acc(std::ostream& os, acc_cond::mark_t b)
{
// FIXME: We could use a cache for this.
if (b == 0U)
return os;
os << " {";
bool notfirst = false;
for (auto v: aut->acc().sets(b))