* src/bin/common_finput.cc, src/tgbaalgos/lbtt.cc: Use !empty() instead of size() > 0. * src/bin/ltl2tgta.cc, src/kripke/kripkeexplicit.cc, src/tgbatest/complementation.cc: Avoid useless assignments. * src/bin/ltlcross.cc: Correct mistaken assignment inside assert(). * src/evtgba/symbol.hh, src/tgba/tgbabddcoredata.cc, src/tgba/tgbabddcoredata.hh, src/tgba/tgbasafracomplement.cc (operator=): Do not return a const reference. * src/evtgbatest/ltl2evtgba.cc, src/evtgbatest/product.cc, src/evtgbatest/product.cc: Check indices before using them, not after. * src/kripke/kripkeexplicit.cc, src/kripke/kripkeexplicit.hh, src/tgbatest/randtgba.cc: Pass constant strings by reference. * src/kripke/kripkeprint.cc, src/tgbaalgos/simulation.cc: Remove a useless operation. * src/ltlvisit/simplify.cc: Remove a duplicate condition. * src/misc/formater.hh: Remove unused attribute. * src/misc/modgray.cc: Initialize done_ in the constructor. * src/saba/explicitstateconjunction.cc, src/saba/explicitstateconjunction.hh (operator=): Fix prototype. * src/saba/sabacomplementtgba.cc: Remove unused default constructor. * src/ta/taexplicit.cc, src/ta/taproduct.cc, src/ta/tgtaproduct.cc, src/ta/tgtaproduct.hh, src/taalgos/emptinessta.cc, src/taalgos/minimize.cc, src/taalgos/reachiter.cc, src/taalgos/tgba2ta.cc, src/tgbaalgos/cutscc.cc: Use C++ casts, and ++it instead of it++. * src/taalgos/dotty.cc, src/tgbatest/ltl2tgba.cc: Refine the scope of variables. * src/tgba/tgbakvcomplement.hh (bdd_order): Always initialize bdd_. * src/tgba/tgbasgba.cc, src/tgba/wdbacomp.cc: Use the initialization line to initialize all members.
200 lines
5.7 KiB
C++
200 lines
5.7 KiB
C++
// Copyright (C) 2009, 2011, 2012 Laboratoire de Recherche et
|
|
// Développement de l'Epita (LRDE).
|
|
// Copyright (C) 2003 Laboratoire d'Informatique de Paris 6 (LIP6),
|
|
// département Systèmes Répartis Coopératifs (SRC), Université Pierre
|
|
// et Marie Curie.
|
|
//
|
|
// This file is part of Spot, a model checking library.
|
|
//
|
|
// Spot is free software; you can redistribute it and/or modify it
|
|
// under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation; either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// Spot is distributed in the hope that it will be useful, but WITHOUT
|
|
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
|
// License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
#include <cassert>
|
|
#include "tgbabddcoredata.hh"
|
|
|
|
namespace spot
|
|
{
|
|
tgba_bdd_core_data::tgba_bdd_core_data(bdd_dict* dict)
|
|
: relation(bddtrue),
|
|
acceptance_conditions(bddfalse),
|
|
acceptance_conditions_support(bddtrue),
|
|
all_acceptance_conditions(bddfalse),
|
|
now_set(bddtrue),
|
|
next_set(bddtrue),
|
|
nownext_set(bddtrue),
|
|
notnow_set(bddtrue),
|
|
notnext_set(bddtrue),
|
|
var_set(bddtrue),
|
|
notvar_set(bddtrue),
|
|
varandnext_set(bddtrue),
|
|
acc_set(bddtrue),
|
|
notacc_set(bddtrue),
|
|
negacc_set(bddtrue),
|
|
dict(dict)
|
|
{
|
|
}
|
|
|
|
tgba_bdd_core_data::tgba_bdd_core_data(const tgba_bdd_core_data& copy)
|
|
: relation(copy.relation),
|
|
acceptance_conditions(copy.acceptance_conditions),
|
|
acceptance_conditions_support(copy.acceptance_conditions_support),
|
|
all_acceptance_conditions(copy.all_acceptance_conditions),
|
|
now_set(copy.now_set),
|
|
next_set(copy.next_set),
|
|
nownext_set(copy.nownext_set),
|
|
notnow_set(copy.notnow_set),
|
|
notnext_set(copy.notnext_set),
|
|
var_set(copy.var_set),
|
|
notvar_set(copy.notvar_set),
|
|
varandnext_set(copy.varandnext_set),
|
|
acc_set(copy.acc_set),
|
|
notacc_set(copy.notacc_set),
|
|
negacc_set(copy.negacc_set),
|
|
dict(copy.dict)
|
|
{
|
|
}
|
|
|
|
// Merge two core_data.
|
|
tgba_bdd_core_data::tgba_bdd_core_data(const tgba_bdd_core_data& left,
|
|
const tgba_bdd_core_data& right)
|
|
: relation(left.relation & right.relation),
|
|
acceptance_conditions(left.acceptance_conditions
|
|
| right.acceptance_conditions),
|
|
acceptance_conditions_support(left.acceptance_conditions_support
|
|
& right.acceptance_conditions_support),
|
|
all_acceptance_conditions(left.all_acceptance_conditions
|
|
| right.all_acceptance_conditions),
|
|
now_set(left.now_set & right.now_set),
|
|
next_set(left.next_set & right.next_set),
|
|
nownext_set(left.nownext_set & right.nownext_set),
|
|
notnow_set(left.notnow_set & right.notnow_set),
|
|
notnext_set(left.notnext_set & right.notnext_set),
|
|
var_set(left.var_set & right.var_set),
|
|
notvar_set(left.notvar_set & right.notvar_set),
|
|
varandnext_set(left.varandnext_set & right.varandnext_set),
|
|
acc_set(left.acc_set & right.acc_set),
|
|
notacc_set(left.notacc_set & right.notacc_set),
|
|
negacc_set(left.negacc_set & right.negacc_set),
|
|
dict(left.dict)
|
|
{
|
|
assert(dict == right.dict);
|
|
}
|
|
|
|
tgba_bdd_core_data&
|
|
tgba_bdd_core_data::operator=(const tgba_bdd_core_data& copy)
|
|
{
|
|
if (this != ©)
|
|
{
|
|
this->~tgba_bdd_core_data();
|
|
new (this) tgba_bdd_core_data(copy);
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
void
|
|
tgba_bdd_core_data::declare_now_next(bdd now, bdd next)
|
|
{
|
|
now_set &= now;
|
|
next_set &= next;
|
|
notnext_set &= now;
|
|
notnow_set &= next;
|
|
bdd both = now & next;
|
|
nownext_set &= both;
|
|
notvar_set &= both;
|
|
notacc_set &= both;
|
|
varandnext_set &= next;
|
|
}
|
|
|
|
void
|
|
tgba_bdd_core_data::declare_atomic_prop(bdd var)
|
|
{
|
|
notnow_set &= var;
|
|
notnext_set &= var;
|
|
notacc_set &= var;
|
|
var_set &= var;
|
|
varandnext_set &= var;
|
|
}
|
|
|
|
void
|
|
tgba_bdd_core_data::declare_acceptance_condition(bdd acc)
|
|
{
|
|
notnow_set &= acc;
|
|
notnext_set &= acc;
|
|
notvar_set &= acc;
|
|
acc_set &= acc;
|
|
negacc_set &= !acc;
|
|
}
|
|
|
|
void
|
|
tgba_bdd_core_data::delete_unaccepting_scc(bdd init)
|
|
{
|
|
bdd er = bdd_exist(relation, var_set); /// existsRelation
|
|
bdd s0 = bddfalse;
|
|
bdd s1 = bdd_exist(bdd_exist(init & relation, var_set), now_set);
|
|
s1 = bdd_replace(s1, dict->next_to_now);
|
|
|
|
/// Find all reachable states
|
|
while (s0 != s1)
|
|
{
|
|
s0 = s1;
|
|
/// Compute s1 = succ(s0) | s
|
|
s1 = bdd_replace(bdd_exist(s0 & er, now_set), dict->next_to_now) | s0;
|
|
}
|
|
|
|
/// Find states which can be visited infinitely often while seeing
|
|
/// all acceptance conditions
|
|
s0 = bddfalse;
|
|
while (s0 != s1)
|
|
{
|
|
s0 = s1;
|
|
bdd all = all_acceptance_conditions;
|
|
while (all != bddfalse)
|
|
{
|
|
bdd next = bdd_satone(all);
|
|
all -= next;
|
|
s1 = infinitely_often(s1, next, er);
|
|
}
|
|
}
|
|
|
|
relation = (relation & bdd_replace(s0, dict->now_to_next));
|
|
}
|
|
|
|
bdd
|
|
tgba_bdd_core_data::infinitely_often(bdd s, bdd acc, bdd er)
|
|
{
|
|
bdd ar = acc & (relation & acceptance_conditions); /// accRelation
|
|
bdd s0 = bddfalse;
|
|
bdd s1 = s;
|
|
|
|
while (s0 != s1)
|
|
{
|
|
s0 = s1;
|
|
bdd as = bdd_replace(s0, dict->now_to_next) & ar;
|
|
as = bdd_exist(bdd_exist(as, next_set), var_set) & s0;
|
|
|
|
/// Do predStar
|
|
bdd s0_ = bddfalse;
|
|
bdd s1_ = bdd_exist(as, acc_set);
|
|
while (s0_ != s1_)
|
|
{
|
|
s0_ = s1_;
|
|
/// Compute s1_ = pred(s0_) | s0_
|
|
s1_ = bdd_exist(er & bdd_replace(s0_, dict->now_to_next), next_set);
|
|
s1_ = (s1_ & s0) | s0_;
|
|
}
|
|
s1 = s0_;
|
|
}
|
|
|
|
return s0;
|
|
}
|
|
}
|