* HACKING: Adjust requirements. g++4.8 is now OK for all our targets. * iface/dve2/dve2.cc, src/dstarparse/dstarparse.yy src/dstarparse/nsa2tgba.cc, src/graph/ngraph.hh, src/ltlast/atomic_prop.cc, src/ltlast/binop.cc, src/ltlast/bunop.cc, src/ltlast/multop.cc, src/ltlast/unop.cc, src/ltlvisit/mark.cc, src/ltlvisit/relabel.cc, src/taalgos/emptinessta.cc, src/taalgos/tgba2ta.cc, src/tgba/tgbaexplicit.hh, src/tgba/tgbagraph.hh, src/tgba/tgbasafracomplement.cc, src/tgba/tgbatba.cc, src/tgbaalgos/cycles.cc, src/tgbaalgos/degen.cc, src/tgbaalgos/dtbasat.cc, src/tgbaalgos/dtgbasat.cc, src/tgbaalgos/emptiness.cc, src/tgbaalgos/gtec/gtec.cc, src/tgbaalgos/ltl2tgba_fm.cc, src/tgbaalgos/magic.cc, src/tgbaalgos/ndfs_result.hxx, src/tgbaalgos/reachiter.cc, src/tgbaalgos/scc.cc, src/tgbaalgos/sccfilter.cc, src/tgbaalgos/se05.cc, src/tgbaalgos/simulation.cc, src/tgbaalgos/tau03.cc, src/tgbaalgos/tau03opt.cc, src/tgbaalgos/weight.cc: Use emplace() instead of insert(make_pair(...)) or insert(...::value_type(...)).
365 lines
7.2 KiB
C++
365 lines
7.2 KiB
C++
// -*- coding: utf-8 -*-
|
|
// Copyright (C) 2010, 2012, 2014 Laboratoire de Recherche et
|
|
// Développement de l'Epita (LRDE).
|
|
//
|
|
// 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 "mark.hh"
|
|
#include "ltlast/allnodes.hh"
|
|
#include <cassert>
|
|
#include <algorithm>
|
|
#include <set>
|
|
#include <vector>
|
|
#include "ltlvisit/tostring.hh"
|
|
#include "misc/casts.hh"
|
|
|
|
namespace spot
|
|
{
|
|
namespace ltl
|
|
{
|
|
namespace
|
|
{
|
|
class simplify_mark_visitor : public visitor
|
|
{
|
|
const formula* result_;
|
|
mark_tools* tools_;
|
|
|
|
public:
|
|
simplify_mark_visitor(mark_tools* t)
|
|
: tools_(t)
|
|
{
|
|
}
|
|
|
|
~simplify_mark_visitor()
|
|
{
|
|
}
|
|
|
|
const formula*
|
|
result()
|
|
{
|
|
return result_;
|
|
}
|
|
|
|
void
|
|
visit(const atomic_prop* ao)
|
|
{
|
|
result_ = ao->clone();
|
|
}
|
|
|
|
void
|
|
visit(const constant* c)
|
|
{
|
|
result_ = c->clone();
|
|
}
|
|
|
|
void
|
|
visit(const bunop* bo)
|
|
{
|
|
result_ = bo->clone();
|
|
}
|
|
|
|
void
|
|
visit(const unop* uo)
|
|
{
|
|
result_ = uo->clone();
|
|
}
|
|
|
|
void
|
|
visit(const multop* mo)
|
|
{
|
|
unsigned mos = mo->size();
|
|
multop::vec* res = new multop::vec;
|
|
switch (mo->op())
|
|
{
|
|
case multop::OrRat:
|
|
case multop::AndNLM:
|
|
case multop::AndRat:
|
|
case multop::Concat:
|
|
case multop::Fusion:
|
|
SPOT_UNIMPLEMENTED();
|
|
case multop::Or:
|
|
for (unsigned i = 0; i < mos; ++i)
|
|
res->push_back(recurse(mo->nth(i)));
|
|
break;
|
|
case multop::And:
|
|
{
|
|
typedef std::set<std::pair<const formula*,
|
|
const formula*> > pset;
|
|
pset empairs;
|
|
typedef std::set<const formula*> sset;
|
|
sset nmset;
|
|
typedef std::vector<const binop*> unbinop;
|
|
unbinop elist;
|
|
typedef std::vector<const unop*> ununop;
|
|
ununop nlist;
|
|
|
|
for (unsigned i = 0; i < mos; ++i)
|
|
{
|
|
const formula* f = mo->nth(i);
|
|
if (const binop* bo = is_binop(f))
|
|
{
|
|
switch (bo->op())
|
|
{
|
|
case binop::EConcatMarked:
|
|
empairs.emplace(bo->first(), bo->second());
|
|
// fall through
|
|
case binop::Xor:
|
|
case binop::Implies:
|
|
case binop::Equiv:
|
|
case binop::U:
|
|
case binop::W:
|
|
case binop::M:
|
|
case binop::R:
|
|
case binop::UConcat:
|
|
res->push_back(recurse(f));
|
|
break;
|
|
case binop::EConcat:
|
|
elist.push_back(bo);
|
|
break;
|
|
}
|
|
}
|
|
if (const unop* uo = is_unop(f))
|
|
{
|
|
switch (uo->op())
|
|
{
|
|
case unop::NegClosureMarked:
|
|
nmset.insert(uo->child());
|
|
// fall through
|
|
case unop::Not:
|
|
case unop::X:
|
|
case unop::F:
|
|
case unop::G:
|
|
case unop::Finish:
|
|
case unop::Closure:
|
|
res->push_back(recurse(f));
|
|
break;
|
|
case unop::NegClosure:
|
|
nlist.push_back(uo);
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
res->push_back(recurse(f));
|
|
}
|
|
}
|
|
// Keep only the non-marked EConcat for which we
|
|
// have not seen a similar EConcatMarked.
|
|
for (unbinop::const_iterator i = elist.begin();
|
|
i != elist.end(); ++i)
|
|
if (empairs.find(std::make_pair((*i)->first(),
|
|
(*i)->second()))
|
|
== empairs.end())
|
|
res->push_back((*i)->clone());
|
|
// Keep only the non-marked NegClosure for which we
|
|
// have not seen a similar NegClosureMarked.
|
|
for (ununop::const_iterator i = nlist.begin();
|
|
i != nlist.end(); ++i)
|
|
if (nmset.find((*i)->child()) == nmset.end())
|
|
res->push_back((*i)->clone());
|
|
}
|
|
}
|
|
result_ = multop::instance(mo->op(), res);
|
|
}
|
|
|
|
void
|
|
visit(const binop* bo)
|
|
{
|
|
result_ = bo->clone();
|
|
}
|
|
|
|
const formula*
|
|
recurse(const formula* f)
|
|
{
|
|
return tools_->simplify_mark(f);
|
|
}
|
|
};
|
|
|
|
|
|
class mark_visitor : public visitor
|
|
{
|
|
const formula* result_;
|
|
mark_tools* tools_;
|
|
|
|
public:
|
|
mark_visitor(mark_tools* t)
|
|
: tools_(t)
|
|
{
|
|
}
|
|
~mark_visitor()
|
|
{
|
|
}
|
|
|
|
const formula*
|
|
result()
|
|
{
|
|
return result_;
|
|
}
|
|
|
|
void
|
|
visit(const atomic_prop* ap)
|
|
{
|
|
result_ = ap->clone();
|
|
}
|
|
|
|
void
|
|
visit(const constant* c)
|
|
{
|
|
result_ = c->clone();
|
|
}
|
|
|
|
void
|
|
visit(const bunop* bo)
|
|
{
|
|
result_ = bo->clone();
|
|
}
|
|
|
|
void
|
|
visit(const unop* uo)
|
|
{
|
|
switch (uo->op())
|
|
{
|
|
case unop::Not:
|
|
case unop::X:
|
|
case unop::F:
|
|
case unop::G:
|
|
case unop::Finish:
|
|
case unop::Closure:
|
|
case unop::NegClosureMarked:
|
|
result_ = uo->clone();
|
|
return;
|
|
case unop::NegClosure:
|
|
result_ = unop::instance(unop::NegClosureMarked,
|
|
uo->child()->clone());
|
|
return;
|
|
}
|
|
SPOT_UNREACHABLE();
|
|
}
|
|
|
|
void
|
|
visit(const multop* mo)
|
|
{
|
|
multop::vec* res = new multop::vec;
|
|
unsigned mos = mo->size();
|
|
for (unsigned i = 0; i < mos; ++i)
|
|
res->push_back(recurse(mo->nth(i)));
|
|
result_ = multop::instance(mo->op(), res);
|
|
}
|
|
|
|
void
|
|
visit(const binop* bo)
|
|
{
|
|
switch (bo->op())
|
|
{
|
|
case binop::Xor:
|
|
case binop::Implies:
|
|
case binop::Equiv:
|
|
SPOT_UNIMPLEMENTED();
|
|
case binop::U:
|
|
case binop::W:
|
|
case binop::M:
|
|
case binop::R:
|
|
case binop::UConcat:
|
|
case binop::EConcatMarked:
|
|
result_ = bo->clone();
|
|
return;
|
|
case binop::EConcat:
|
|
{
|
|
const formula* f1 = bo->first()->clone();
|
|
const formula* f2 = bo->second()->clone();
|
|
result_ = binop::instance(binop::EConcatMarked, f1, f2);
|
|
return;
|
|
}
|
|
}
|
|
SPOT_UNREACHABLE();
|
|
}
|
|
|
|
const formula*
|
|
recurse(const formula* f)
|
|
{
|
|
return tools_->mark_concat_ops(f);
|
|
}
|
|
};
|
|
|
|
}
|
|
|
|
mark_tools::mark_tools()
|
|
: simpvisitor_(new simplify_mark_visitor(this)),
|
|
markvisitor_(new mark_visitor(this))
|
|
{
|
|
}
|
|
|
|
|
|
mark_tools::~mark_tools()
|
|
{
|
|
delete simpvisitor_;
|
|
delete markvisitor_;
|
|
{
|
|
f2f_map::iterator i = simpmark_.begin();
|
|
f2f_map::iterator end = simpmark_.end();
|
|
while (i != end)
|
|
{
|
|
f2f_map::iterator old = i++;
|
|
old->second->destroy();
|
|
old->first->destroy();
|
|
}
|
|
}
|
|
{
|
|
f2f_map::iterator i = markops_.begin();
|
|
f2f_map::iterator end = markops_.end();
|
|
while (i != end)
|
|
{
|
|
f2f_map::iterator old = i++;
|
|
old->second->destroy();
|
|
old->first->destroy();
|
|
}
|
|
}
|
|
}
|
|
|
|
const formula*
|
|
mark_tools::mark_concat_ops(const formula* f)
|
|
{
|
|
f2f_map::iterator i = markops_.find(f);
|
|
if (i != markops_.end())
|
|
return i->second->clone();
|
|
|
|
f->accept(*markvisitor_);
|
|
|
|
const formula* r = down_cast<mark_visitor*>(markvisitor_)->result();
|
|
markops_[f->clone()] = r->clone();
|
|
return r;
|
|
}
|
|
|
|
const formula*
|
|
mark_tools::simplify_mark(const formula* f)
|
|
{
|
|
if (!f->is_marked())
|
|
return f->clone();
|
|
|
|
f2f_map::iterator i = simpmark_.find(f);
|
|
if (i != simpmark_.end())
|
|
return i->second->clone();
|
|
|
|
f->accept(*simpvisitor_);
|
|
|
|
const formula* r =
|
|
down_cast<simplify_mark_visitor*>(simpvisitor_)->result();
|
|
simpmark_[f->clone()] = r->clone();
|
|
return r;
|
|
}
|
|
|
|
}
|
|
}
|