ltlfilt: add a --exclusive-ap option
* src/ltlvisit/exclusive.cc, src/ltlvisit/exclusive.hh: New files. * src/ltlvisit/Makefile.am: Add them. * src/bin/ltlfilt.cc: Implement the --exclusive-ap option. * NEWS: Mention it. * src/ltltest/exclusive.test: New file. * src/ltltest/Makefile.am: Add it.
This commit is contained in:
parent
57cd9f2d2c
commit
544c533ed3
7 changed files with 307 additions and 18 deletions
|
|
@ -1,6 +1,6 @@
|
|||
## -*- coding: utf-8 -*-
|
||||
## Copyright (C) 2010, 2011, 2012, 2013, 2014 Laboratoire de Recherche
|
||||
## et Developpement de l'Epita (LRDE).
|
||||
## Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015 Laboratoire de
|
||||
## Recherche et Developpement de l'Epita (LRDE).
|
||||
## Copyright (C) 2004, 2005, 2006 Laboratoire d'Informatique de Paris
|
||||
## 6 (LIP6), département Systèmes Répartis Coopératifs (SRC),
|
||||
## Université Pierre et Marie Curie.
|
||||
|
|
@ -31,6 +31,7 @@ ltlvisit_HEADERS = \
|
|||
clone.hh \
|
||||
dotty.hh \
|
||||
dump.hh \
|
||||
exclusive.hh \
|
||||
lbt.hh \
|
||||
length.hh \
|
||||
lunabbrev.hh \
|
||||
|
|
@ -54,6 +55,7 @@ libltlvisit_la_SOURCES = \
|
|||
clone.cc \
|
||||
dotty.cc \
|
||||
dump.cc \
|
||||
exclusive.cc \
|
||||
lbt.cc \
|
||||
length.cc \
|
||||
lunabbrev.cc \
|
||||
|
|
|
|||
161
src/ltlvisit/exclusive.cc
Normal file
161
src/ltlvisit/exclusive.cc
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2015 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 "exclusive.hh"
|
||||
#include "ltlenv/defaultenv.hh"
|
||||
#include "ltlast/multop.hh"
|
||||
#include "ltlast/unop.hh"
|
||||
#include "ltlast/constant.hh"
|
||||
#include "misc/casts.hh"
|
||||
#include "apcollect.hh"
|
||||
|
||||
namespace spot
|
||||
{
|
||||
exclusive_ap::~exclusive_ap()
|
||||
{
|
||||
for (auto& g: groups)
|
||||
for (auto ap: g)
|
||||
ap->destroy();
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
static const std::vector<const spot::ltl::atomic_prop*>
|
||||
split_aps(const char* arg)
|
||||
{
|
||||
auto& env = spot::ltl::default_environment::instance();
|
||||
std::vector<const spot::ltl::atomic_prop*> group;
|
||||
auto start = arg;
|
||||
while (*start)
|
||||
{
|
||||
while (*start == ' ' || *start == '\t')
|
||||
++start;
|
||||
if (!*start)
|
||||
break;
|
||||
if (*start == ',')
|
||||
{
|
||||
std::string s = "unexpected ',' in ";
|
||||
s += arg;
|
||||
throw std::invalid_argument(s);
|
||||
}
|
||||
if (*start == '"')
|
||||
{
|
||||
++start;
|
||||
auto end = start;
|
||||
while (*end && *end != '"')
|
||||
{
|
||||
if (*end == '\\')
|
||||
++end;
|
||||
++end;
|
||||
}
|
||||
if (!*end)
|
||||
{
|
||||
std::string s = "missing closing '\"' in ";
|
||||
s += arg;
|
||||
throw std::invalid_argument(s);
|
||||
}
|
||||
std::string ap(start, end - start);
|
||||
auto* t = env.require(ap);
|
||||
group.push_back(down_cast<const spot::ltl::atomic_prop*>(t));
|
||||
do
|
||||
++end;
|
||||
while (*end == ' ' || *end == '\t');
|
||||
if (*end && *end != ',')
|
||||
{
|
||||
std::string s = "unexpected character '";
|
||||
s += *end;
|
||||
s += "' in ";
|
||||
s += arg;
|
||||
throw std::invalid_argument(s);
|
||||
}
|
||||
if (*end == ',')
|
||||
++end;
|
||||
start = end;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto end = start;
|
||||
while (*end && *end != ',')
|
||||
++end;
|
||||
auto rend = end;
|
||||
while (rend > start && (rend[-1] == ' ' || rend[-1] == '\t'))
|
||||
--rend;
|
||||
std::string ap(start, rend - start);
|
||||
auto* t = env.require(ap);
|
||||
group.push_back(down_cast<const spot::ltl::atomic_prop*>(t));
|
||||
if (*end == ',')
|
||||
start = end + 1;
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
return group;
|
||||
}
|
||||
}
|
||||
|
||||
void exclusive_ap::add_group(const char* ap_csv)
|
||||
{
|
||||
add_group(split_aps(ap_csv));
|
||||
}
|
||||
|
||||
void exclusive_ap::add_group(std::vector<const ltl::atomic_prop*> ap)
|
||||
{
|
||||
groups.push_back(ap);
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
const ltl::formula*
|
||||
nand(const ltl::formula* lhs, const ltl::formula* rhs)
|
||||
{
|
||||
auto f = ltl::multop::instance(ltl::multop::And,
|
||||
lhs->clone(), rhs->clone());
|
||||
return ltl::unop::instance(ltl::unop::Not, f);
|
||||
}
|
||||
}
|
||||
|
||||
const ltl::formula*
|
||||
exclusive_ap::constrain(const ltl::formula* f) const
|
||||
{
|
||||
spot::ltl::atomic_prop_set* s = atomic_prop_collect(f);
|
||||
|
||||
std::vector<const ltl::atomic_prop*> group;
|
||||
ltl::multop::vec* v = new ltl::multop::vec;
|
||||
|
||||
for (auto& g: groups)
|
||||
{
|
||||
group.clear();
|
||||
|
||||
for (auto ap: g)
|
||||
if (s->find(ap) != s->end())
|
||||
group.push_back(ap);
|
||||
|
||||
unsigned s = group.size();
|
||||
for (unsigned j = 0; j < s; ++j)
|
||||
for (unsigned k = j + 1; k < s; ++k)
|
||||
v->push_back(nand(group[j], group[k]));
|
||||
};
|
||||
|
||||
delete s;
|
||||
|
||||
auto* c = ltl::unop::instance(ltl::unop::G,
|
||||
ltl::multop::instance(ltl::multop::And, v));
|
||||
return ltl::multop::instance(ltl::multop::And, f->clone(), c);
|
||||
}
|
||||
}
|
||||
45
src/ltlvisit/exclusive.hh
Normal file
45
src/ltlvisit/exclusive.hh
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2015 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/>.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include "ltlast/atomic_prop.hh"
|
||||
#include "ltlast/formula.hh"
|
||||
|
||||
namespace spot
|
||||
{
|
||||
class SPOT_API exclusive_ap
|
||||
{
|
||||
std::vector<std::vector<const ltl::atomic_prop*>> groups;
|
||||
public:
|
||||
~exclusive_ap();
|
||||
#ifndef SWIG
|
||||
void add_group(std::vector<const ltl::atomic_prop*> ap);
|
||||
#endif
|
||||
void add_group(const char* ap_csv);
|
||||
|
||||
bool empty() const
|
||||
{
|
||||
return groups.empty();
|
||||
}
|
||||
|
||||
const ltl::formula* constrain(const ltl::formula* f) const;
|
||||
};
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue