spot/src/ltlvisit/mark.cc
Alexandre Duret-Lutz fd5fbda4dd Use emplace() for associative containers.
* 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(...)).
2014-07-31 16:59:47 +02:00

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;
}
}
}