autfilt: add a --remove-ap option
* src/tgbaalgos/remprop.cc, src/tgbaalgos/remprop.hh: New files. * src/tgbaalgos/Makefile.am: Add them. * src/tgbatest/remprop.test: New test. * src/tgbatest/Makefile.am: Add it. * src/bin/autfilt.cc: Implement the option. * doc/org/autfilt.org: Document it.
This commit is contained in:
parent
e592832a3e
commit
4553ac06cf
7 changed files with 497 additions and 32 deletions
|
|
@ -260,8 +260,11 @@ autfilt --help | sed -n '/Transformations:/,/^$/p' | sed '1d;$d'
|
||||||
--product=FILENAME build the product with the automaton in FILENAME
|
--product=FILENAME build the product with the automaton in FILENAME
|
||||||
--randomize[=s|t] randomize states and transitions (specify 's' or
|
--randomize[=s|t] randomize states and transitions (specify 's' or
|
||||||
't' to randomize only states or transitions)
|
't' to randomize only states or transitions)
|
||||||
--remove-fin rewrite the automaton without using Fin acceptance
|
--remove-ap=AP[=0|=1][,AP...]
|
||||||
|
remove atomic propositions either by existential
|
||||||
|
quantification, or by assigning them 0 or 1
|
||||||
|
--remove-fin rewrite the automaton without using Fin
|
||||||
|
acceptance
|
||||||
--state-based-acceptance, --sbacc
|
--state-based-acceptance, --sbacc
|
||||||
define the acceptance using states
|
define the acceptance using states
|
||||||
--strip-acceptance remove the acceptance condition and all acceptance
|
--strip-acceptance remove the acceptance condition and all acceptance
|
||||||
|
|
@ -531,3 +534,117 @@ $txt
|
||||||
|
|
||||||
#+RESULTS:
|
#+RESULTS:
|
||||||
[[file:autfilt-ex5.png]]
|
[[file:autfilt-ex5.png]]
|
||||||
|
|
||||||
|
|
||||||
|
Atomic propositions can be removed from an automaton in three ways:
|
||||||
|
- use ~--remove-ap=a~ to remove =a= by existential quantification, i.e., both =a= and its negation will be replaced by true.
|
||||||
|
This does not remove any transition.
|
||||||
|
- use ~--remove-ap=a=0~ to keep only transitions compatible with =!a= (i.e, transitions requiring =a= will be removed).
|
||||||
|
- use ~--remove-ap=a=1~ to keep only transitions compatible with =a= (i.e, transitions requiring =!a= will be removed).
|
||||||
|
|
||||||
|
Here are the results of these three options on our example:
|
||||||
|
|
||||||
|
#+NAME: autfilt-ex6a
|
||||||
|
#+BEGIN_SRC sh :results verbatim :export code
|
||||||
|
autfilt --remove-ap=a aut-ex1.hoa --dot=.a
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
#+RESULTS: autfilt-ex6a
|
||||||
|
#+begin_example
|
||||||
|
digraph G {
|
||||||
|
rankdir=LR
|
||||||
|
label=<(Fin(<font color="#F17CB0">❶</font>) & Fin(<font color="#B276B2">❸</font>) & Inf(<font color="#5DA5DA">⓿</font>)) | (Inf(<font color="#FAA43A">❷</font>)&Inf(<font color="#B276B2">❸</font>)) | Inf(<font color="#F17CB0">❶</font>)>
|
||||||
|
labelloc="t"
|
||||||
|
fontname="Lato"
|
||||||
|
node [fontname="Lato"]
|
||||||
|
edge [fontname="Lato"]
|
||||||
|
node[style=filled, fillcolor="#ffffa0"]
|
||||||
|
I [label="", style=invis, width=0]
|
||||||
|
I -> 0
|
||||||
|
0 [label="0"]
|
||||||
|
0 -> 0 [label=<1<br/><font color="#B276B2">❸</font>>]
|
||||||
|
0 -> 1 [label=<1<br/><font color="#F17CB0">❶</font><font color="#B276B2">❸</font>>]
|
||||||
|
0 -> 2 [label=<1<br/><font color="#5DA5DA">⓿</font><font color="#B276B2">❸</font>>]
|
||||||
|
1 [label="1"]
|
||||||
|
1 -> 0 [label=<b<br/><font color="#B276B2">❸</font>>]
|
||||||
|
1 -> 1 [label=<b<br/><font color="#5DA5DA">⓿</font><font color="#B276B2">❸</font>>]
|
||||||
|
1 -> 2 [label=<b<br/><font color="#FAA43A">❷</font><font color="#B276B2">❸</font>>]
|
||||||
|
2 [label="2"]
|
||||||
|
2 -> 0 [label=<!b>]
|
||||||
|
2 -> 1 [label=<!b<br/><font color="#5DA5DA">⓿</font>>]
|
||||||
|
2 -> 2 [label=<!b<br/><font color="#5DA5DA">⓿</font>>]
|
||||||
|
}
|
||||||
|
#+end_example
|
||||||
|
|
||||||
|
#+BEGIN_SRC dot :file autfilt-ex6a.png :cmdline -Tpng :var txt=autfilt-ex6a :exports results
|
||||||
|
$txt
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
#+RESULTS:
|
||||||
|
[[file:autfilt-ex6a.png]]
|
||||||
|
|
||||||
|
#+NAME: autfilt-ex6b
|
||||||
|
#+BEGIN_SRC sh :results verbatim :export code
|
||||||
|
autfilt --remove-ap=a=0 aut-ex1.hoa --dot=.a
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
#+RESULTS: autfilt-ex6b
|
||||||
|
#+begin_example
|
||||||
|
digraph G {
|
||||||
|
rankdir=LR
|
||||||
|
label=<(Fin(<font color="#F17CB0">❶</font>) & Fin(<font color="#B276B2">❸</font>) & Inf(<font color="#5DA5DA">⓿</font>)) | (Inf(<font color="#FAA43A">❷</font>)&Inf(<font color="#B276B2">❸</font>)) | Inf(<font color="#F17CB0">❶</font>)>
|
||||||
|
labelloc="t"
|
||||||
|
fontname="Lato"
|
||||||
|
node [fontname="Lato"]
|
||||||
|
edge [fontname="Lato"]
|
||||||
|
node[style=filled, fillcolor="#ffffa0"]
|
||||||
|
I [label="", style=invis, width=0]
|
||||||
|
I -> 0
|
||||||
|
0 [label="0"]
|
||||||
|
0 -> 0 [label=<1<br/><font color="#B276B2">❸</font>>]
|
||||||
|
0 -> 1 [label=<1<br/><font color="#5DA5DA">⓿</font><font color="#B276B2">❸</font>>]
|
||||||
|
1 [label="1"]
|
||||||
|
1 -> 0 [label=<!b>]
|
||||||
|
1 -> 1 [label=<!b<br/><font color="#5DA5DA">⓿</font>>]
|
||||||
|
}
|
||||||
|
#+end_example
|
||||||
|
|
||||||
|
#+BEGIN_SRC dot :file autfilt-ex6b.png :cmdline -Tpng :var txt=autfilt-ex6b :exports results
|
||||||
|
$txt
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
#+RESULTS:
|
||||||
|
[[file:autfilt-ex6b.png]]
|
||||||
|
|
||||||
|
#+NAME: autfilt-ex6c
|
||||||
|
#+BEGIN_SRC sh :results verbatim :export code
|
||||||
|
autfilt --remove-ap=a=1 aut-ex1.hoa --dot=.a
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
#+RESULTS: autfilt-ex6c
|
||||||
|
#+begin_example
|
||||||
|
digraph G {
|
||||||
|
rankdir=LR
|
||||||
|
label=<(Fin(<font color="#F17CB0">❶</font>) & Fin(<font color="#B276B2">❸</font>) & Inf(<font color="#5DA5DA">⓿</font>)) | (Inf(<font color="#FAA43A">❷</font>)&Inf(<font color="#B276B2">❸</font>)) | Inf(<font color="#F17CB0">❶</font>)>
|
||||||
|
labelloc="t"
|
||||||
|
fontname="Lato"
|
||||||
|
node [fontname="Lato"]
|
||||||
|
edge [fontname="Lato"]
|
||||||
|
node[style=filled, fillcolor="#ffffa0"]
|
||||||
|
I [label="", style=invis, width=0]
|
||||||
|
I -> 0
|
||||||
|
0 [label="0"]
|
||||||
|
0 -> 0 [label=<1<br/><font color="#B276B2">❸</font>>]
|
||||||
|
0 -> 1 [label=<1<br/><font color="#F17CB0">❶</font><font color="#B276B2">❸</font>>]
|
||||||
|
1 [label="1"]
|
||||||
|
1 -> 0 [label=<b<br/><font color="#B276B2">❸</font>>]
|
||||||
|
1 -> 1 [label=<b<br/><font color="#5DA5DA">⓿</font><font color="#B276B2">❸</font>>]
|
||||||
|
}
|
||||||
|
#+end_example
|
||||||
|
|
||||||
|
#+BEGIN_SRC dot :file autfilt-ex6c.png :cmdline -Tpng :var txt=autfilt-ex6c :exports results
|
||||||
|
$txt
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
#+RESULTS:
|
||||||
|
[[file:autfilt-ex6c.png]]
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,7 @@
|
||||||
#include "misc/random.hh"
|
#include "misc/random.hh"
|
||||||
#include "hoaparse/public.hh"
|
#include "hoaparse/public.hh"
|
||||||
#include "ltlvisit/exclusive.hh"
|
#include "ltlvisit/exclusive.hh"
|
||||||
|
#include "tgbaalgos/remprop.hh"
|
||||||
#include "tgbaalgos/randomize.hh"
|
#include "tgbaalgos/randomize.hh"
|
||||||
#include "tgbaalgos/are_isomorphic.hh"
|
#include "tgbaalgos/are_isomorphic.hh"
|
||||||
#include "tgbaalgos/canonicalize.hh"
|
#include "tgbaalgos/canonicalize.hh"
|
||||||
|
|
@ -83,6 +84,7 @@ enum {
|
||||||
OPT_MERGE,
|
OPT_MERGE,
|
||||||
OPT_PRODUCT,
|
OPT_PRODUCT,
|
||||||
OPT_RANDOMIZE,
|
OPT_RANDOMIZE,
|
||||||
|
OPT_REM_AP,
|
||||||
OPT_REM_FIN,
|
OPT_REM_FIN,
|
||||||
OPT_SBACC,
|
OPT_SBACC,
|
||||||
OPT_SEED,
|
OPT_SEED,
|
||||||
|
|
@ -145,6 +147,9 @@ static const argp_option options[] =
|
||||||
"ensure two of them may not be true at the same time. Use this option "
|
"ensure two of them may not be true at the same time. Use this option "
|
||||||
"multiple times to declare independent groups of exclusive "
|
"multiple times to declare independent groups of exclusive "
|
||||||
"propositions.", 0 },
|
"propositions.", 0 },
|
||||||
|
{ "remove-ap", OPT_REM_AP, "AP[=0|=1][,AP...]", 0,
|
||||||
|
"remove atomic propositions either by existential quantification, or "
|
||||||
|
"by assigning them 0 or 1", 0 },
|
||||||
/**************************************************/
|
/**************************************************/
|
||||||
{ 0, 0, 0, 0, "Filtering options:", 6 },
|
{ 0, 0, 0, 0, "Filtering options:", 6 },
|
||||||
{ "are-isomorphic", OPT_ARE_ISOMORPHIC, "FILENAME", 0,
|
{ "are-isomorphic", OPT_ARE_ISOMORPHIC, "FILENAME", 0,
|
||||||
|
|
@ -233,6 +238,7 @@ static spot::acc_cond::mark_t opt_mask_acc = 0U;
|
||||||
static std::vector<bool> opt_keep_states = {};
|
static std::vector<bool> opt_keep_states = {};
|
||||||
static unsigned int opt_keep_states_initial = 0;
|
static unsigned int opt_keep_states_initial = 0;
|
||||||
static spot::exclusive_ap excl_ap;
|
static spot::exclusive_ap excl_ap;
|
||||||
|
static spot::remove_ap rem_ap;
|
||||||
|
|
||||||
static int
|
static int
|
||||||
parse_opt(int key, char* arg, struct argp_state*)
|
parse_opt(int key, char* arg, struct argp_state*)
|
||||||
|
|
@ -385,6 +391,9 @@ parse_opt(int key, char* arg, struct argp_state*)
|
||||||
randomize_st = true;
|
randomize_st = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case OPT_REM_AP:
|
||||||
|
rem_ap.add_ap(arg);
|
||||||
|
break;
|
||||||
case OPT_REM_FIN:
|
case OPT_REM_FIN:
|
||||||
opt_rem_fin = true;
|
opt_rem_fin = true;
|
||||||
break;
|
break;
|
||||||
|
|
@ -504,6 +513,9 @@ namespace
|
||||||
if (!excl_ap.empty())
|
if (!excl_ap.empty())
|
||||||
aut = excl_ap.constrain(aut);
|
aut = excl_ap.constrain(aut);
|
||||||
|
|
||||||
|
if (!rem_ap.empty())
|
||||||
|
aut = rem_ap.strip(aut);
|
||||||
|
|
||||||
if (opt_destut)
|
if (opt_destut)
|
||||||
aut = spot::closure(std::move(aut));
|
aut = spot::closure(std::move(aut));
|
||||||
if (opt_instut == 1)
|
if (opt_instut == 1)
|
||||||
|
|
@ -586,38 +598,38 @@ main(int argc, char** argv)
|
||||||
const argp ap = { options, parse_opt, "[FILENAMES...]",
|
const argp ap = { options, parse_opt, "[FILENAMES...]",
|
||||||
argp_program_doc, children, 0, 0 };
|
argp_program_doc, children, 0, 0 };
|
||||||
|
|
||||||
// This will ensure that all objects stored in this struct are
|
|
||||||
// destroyed before global variables.
|
|
||||||
opt_t o;
|
|
||||||
opt = &o;
|
|
||||||
|
|
||||||
// Disable post-processing as much as possible by default.
|
|
||||||
level = spot::postprocessor::Low;
|
|
||||||
pref = spot::postprocessor::Any;
|
|
||||||
if (int err = argp_parse(&ap, argc, argv, ARGP_NO_HELP, 0, 0))
|
|
||||||
exit(err);
|
|
||||||
|
|
||||||
if (jobs.empty())
|
|
||||||
jobs.emplace_back("-", true);
|
|
||||||
|
|
||||||
if (opt->are_isomorphic)
|
|
||||||
{
|
|
||||||
if (opt_merge)
|
|
||||||
opt->are_isomorphic->merge_transitions();
|
|
||||||
opt->isomorphism_checker = std::unique_ptr<spot::isomorphism_checker>
|
|
||||||
(new spot::isomorphism_checker(opt->are_isomorphic));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
spot::srand(opt_seed);
|
|
||||||
|
|
||||||
spot::postprocessor post(&extra_options);
|
|
||||||
post.set_pref(pref | comp);
|
|
||||||
post.set_type(type);
|
|
||||||
post.set_level(level);
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
// This will ensure that all objects stored in this struct are
|
||||||
|
// destroyed before global variables.
|
||||||
|
opt_t o;
|
||||||
|
opt = &o;
|
||||||
|
|
||||||
|
// Disable post-processing as much as possible by default.
|
||||||
|
level = spot::postprocessor::Low;
|
||||||
|
pref = spot::postprocessor::Any;
|
||||||
|
if (int err = argp_parse(&ap, argc, argv, ARGP_NO_HELP, 0, 0))
|
||||||
|
exit(err);
|
||||||
|
|
||||||
|
if (jobs.empty())
|
||||||
|
jobs.emplace_back("-", true);
|
||||||
|
|
||||||
|
if (opt->are_isomorphic)
|
||||||
|
{
|
||||||
|
if (opt_merge)
|
||||||
|
opt->are_isomorphic->merge_transitions();
|
||||||
|
opt->isomorphism_checker = std::unique_ptr<spot::isomorphism_checker>
|
||||||
|
(new spot::isomorphism_checker(opt->are_isomorphic));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
spot::srand(opt_seed);
|
||||||
|
|
||||||
|
spot::postprocessor post(&extra_options);
|
||||||
|
post.set_pref(pref | comp);
|
||||||
|
post.set_type(type);
|
||||||
|
post.set_level(level);
|
||||||
|
|
||||||
hoa_processor processor(post);
|
hoa_processor processor(post);
|
||||||
if (processor.run())
|
if (processor.run())
|
||||||
return 2;
|
return 2;
|
||||||
|
|
@ -626,6 +638,10 @@ main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
error(2, 0, "%s", e.what());
|
error(2, 0, "%s", e.what());
|
||||||
}
|
}
|
||||||
|
catch (const std::invalid_argument& e)
|
||||||
|
{
|
||||||
|
error(2, 0, "%s", e.what());
|
||||||
|
}
|
||||||
|
|
||||||
if (automaton_format == Count)
|
if (automaton_format == Count)
|
||||||
std::cout << match_count << std::endl;
|
std::cout << match_count << std::endl;
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,7 @@ tgbaalgos_HEADERS = \
|
||||||
reducerun.hh \
|
reducerun.hh \
|
||||||
relabel.hh \
|
relabel.hh \
|
||||||
remfin.hh \
|
remfin.hh \
|
||||||
|
remprop.hh \
|
||||||
replayrun.hh \
|
replayrun.hh \
|
||||||
safety.hh \
|
safety.hh \
|
||||||
sbacc.hh \
|
sbacc.hh \
|
||||||
|
|
@ -117,6 +118,7 @@ libtgbaalgos_la_SOURCES = \
|
||||||
reachiter.cc \
|
reachiter.cc \
|
||||||
reducerun.cc \
|
reducerun.cc \
|
||||||
remfin.cc \
|
remfin.cc \
|
||||||
|
remprop.cc \
|
||||||
replayrun.cc \
|
replayrun.cc \
|
||||||
relabel.cc \
|
relabel.cc \
|
||||||
safety.cc \
|
safety.cc \
|
||||||
|
|
|
||||||
188
src/tgbaalgos/remprop.cc
Normal file
188
src/tgbaalgos/remprop.cc
Normal file
|
|
@ -0,0 +1,188 @@
|
||||||
|
// -*- 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 "remprop.hh"
|
||||||
|
#include "ltlenv/defaultenv.hh"
|
||||||
|
#include "tgbaalgos/mask.hh"
|
||||||
|
#include "misc/casts.hh"
|
||||||
|
#include "ltlvisit/tostring.hh"
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
namespace spot
|
||||||
|
{
|
||||||
|
remove_ap::~remove_ap()
|
||||||
|
{
|
||||||
|
for (auto& ap: props_exist)
|
||||||
|
ap->destroy();
|
||||||
|
for (auto& ap: props_pos)
|
||||||
|
ap->destroy();
|
||||||
|
for (auto& ap: props_neg)
|
||||||
|
ap->destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
static
|
||||||
|
void unexpected_char(const char* arg, const char* pos)
|
||||||
|
{
|
||||||
|
std::ostringstream out;
|
||||||
|
out << "unexpected ";
|
||||||
|
if (isprint(*pos))
|
||||||
|
out << '\'' << *pos << '\'';
|
||||||
|
else
|
||||||
|
out << "character";
|
||||||
|
out << " at position " << pos - arg << " in '";
|
||||||
|
out << arg << '\'';
|
||||||
|
throw std::invalid_argument(out.str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void remove_ap::add_ap(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 == ',' || *start == '=')
|
||||||
|
unexpected_char(arg, start);
|
||||||
|
const spot::ltl::atomic_prop* the_ap = nullptr;
|
||||||
|
|
||||||
|
if (*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);
|
||||||
|
the_ap = down_cast<const spot::ltl::atomic_prop*>(t);
|
||||||
|
do
|
||||||
|
++end;
|
||||||
|
while (*end == ' ' || *end == '\t');
|
||||||
|
start = end;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto end = start;
|
||||||
|
while (*end && *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);
|
||||||
|
the_ap = down_cast<const spot::ltl::atomic_prop*>(t);
|
||||||
|
start = end;
|
||||||
|
}
|
||||||
|
if (*start)
|
||||||
|
{
|
||||||
|
if (!(*start == ',' || *start == '='))
|
||||||
|
unexpected_char(arg, start);
|
||||||
|
if (*start == '=')
|
||||||
|
{
|
||||||
|
do
|
||||||
|
++start;
|
||||||
|
while (*start == ' ' || *start == '\t');
|
||||||
|
if (*start == '0')
|
||||||
|
props_neg.insert(the_ap);
|
||||||
|
else if (*start == '1')
|
||||||
|
props_pos.insert(the_ap);
|
||||||
|
else
|
||||||
|
unexpected_char(arg, start);
|
||||||
|
the_ap = nullptr;
|
||||||
|
do
|
||||||
|
++start;
|
||||||
|
while (*start == ' ' || *start == '\t');
|
||||||
|
}
|
||||||
|
if (*start)
|
||||||
|
{
|
||||||
|
if (*start != ',')
|
||||||
|
unexpected_char(arg, start);
|
||||||
|
++start;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (the_ap)
|
||||||
|
props_exist.insert(the_ap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tgba_digraph_ptr remove_ap::strip(const_tgba_digraph_ptr aut) const
|
||||||
|
{
|
||||||
|
bdd restrict = bddtrue;
|
||||||
|
bdd exist = bddtrue;
|
||||||
|
auto d = aut->get_dict();
|
||||||
|
|
||||||
|
tgba_digraph_ptr res = make_tgba_digraph(d);
|
||||||
|
res->copy_ap_of(aut);
|
||||||
|
res->prop_copy(aut, { true, true, false, false });
|
||||||
|
res->copy_acceptance_of(aut);
|
||||||
|
|
||||||
|
for (auto ap: props_exist)
|
||||||
|
{
|
||||||
|
int v = d->has_registered_proposition(ap, aut);
|
||||||
|
if (v >= 0)
|
||||||
|
{
|
||||||
|
exist &= bdd_ithvar(v);
|
||||||
|
d->unregister_variable(v, res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (auto ap: props_pos)
|
||||||
|
{
|
||||||
|
int v = d->has_registered_proposition(ap, aut);
|
||||||
|
if (v >= 0)
|
||||||
|
{
|
||||||
|
restrict &= bdd_ithvar(v);
|
||||||
|
d->unregister_variable(v, res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (auto ap: props_neg)
|
||||||
|
{
|
||||||
|
int v = d->has_registered_proposition(ap, aut);
|
||||||
|
if (v >= 0)
|
||||||
|
{
|
||||||
|
restrict &= bdd_nithvar(v);
|
||||||
|
d->unregister_variable(v, res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
transform_accessible(aut, res, [&](unsigned, bdd& cond,
|
||||||
|
acc_cond::mark_t&, unsigned)
|
||||||
|
{
|
||||||
|
cond = bdd_restrict(bdd_exist(cond, exist),
|
||||||
|
restrict);
|
||||||
|
});
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
44
src/tgbaalgos/remprop.hh
Normal file
44
src/tgbaalgos/remprop.hh
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
// -*- 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 "tgba/tgbagraph.hh"
|
||||||
|
|
||||||
|
namespace spot
|
||||||
|
{
|
||||||
|
class SPOT_API remove_ap
|
||||||
|
{
|
||||||
|
std::set<const ltl::atomic_prop*> props_exist;
|
||||||
|
std::set<const ltl::atomic_prop*> props_pos;
|
||||||
|
std::set<const ltl::atomic_prop*> props_neg;
|
||||||
|
public:
|
||||||
|
~remove_ap();
|
||||||
|
void add_ap(const char* ap_csv);
|
||||||
|
|
||||||
|
bool empty() const
|
||||||
|
{
|
||||||
|
return props_exist.empty() && props_pos.empty() && props_neg.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
tgba_digraph_ptr strip(const_tgba_digraph_ptr aut) const;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -92,6 +92,7 @@ TESTS = \
|
||||||
tripprod.test \
|
tripprod.test \
|
||||||
dupexp.test \
|
dupexp.test \
|
||||||
exclusive.test \
|
exclusive.test \
|
||||||
|
remprop.test \
|
||||||
degendet.test \
|
degendet.test \
|
||||||
degenid.test \
|
degenid.test \
|
||||||
degenlskip.test \
|
degenlskip.test \
|
||||||
|
|
|
||||||
97
src/tgbatest/remprop.test
Executable file
97
src/tgbatest/remprop.test
Executable file
|
|
@ -0,0 +1,97 @@
|
||||||
|
#! /bin/sh
|
||||||
|
# -*- 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/>.
|
||||||
|
|
||||||
|
|
||||||
|
. ./defs || exit 1
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
cat >automaton <<EOF
|
||||||
|
HOA: v1
|
||||||
|
States: 4
|
||||||
|
Start: 0
|
||||||
|
AP: 3 "a" "b" "c"
|
||||||
|
acc-name: Buchi
|
||||||
|
Acceptance: 1 Inf(0)
|
||||||
|
--BODY--
|
||||||
|
State: 0
|
||||||
|
[0] 1
|
||||||
|
State: 1
|
||||||
|
[1] 2
|
||||||
|
[2] 2
|
||||||
|
State: 2 {0}
|
||||||
|
[1] 2
|
||||||
|
[0&1] 1
|
||||||
|
[1&2] 3
|
||||||
|
State: 3
|
||||||
|
[t] 3
|
||||||
|
--END--
|
||||||
|
EOF
|
||||||
|
|
||||||
|
cat >expected <<EOF
|
||||||
|
HOA: v1
|
||||||
|
States: 4
|
||||||
|
Start: 0
|
||||||
|
AP: 1 "c"
|
||||||
|
acc-name: Buchi
|
||||||
|
Acceptance: 1 Inf(0)
|
||||||
|
properties: trans-labels explicit-labels state-acc complete
|
||||||
|
--BODY--
|
||||||
|
State: 0
|
||||||
|
[t] 1
|
||||||
|
State: 1
|
||||||
|
[t] 2
|
||||||
|
[0] 2
|
||||||
|
State: 2 {0}
|
||||||
|
[t] 2
|
||||||
|
[t] 1
|
||||||
|
[0] 3
|
||||||
|
State: 3
|
||||||
|
[t] 3
|
||||||
|
--END--
|
||||||
|
EOF
|
||||||
|
|
||||||
|
run 0 ../../bin/autfilt -H --remove-ap=a,b automaton >out
|
||||||
|
cat out
|
||||||
|
diff out expected
|
||||||
|
|
||||||
|
cat >expected <<EOF
|
||||||
|
HOA: v1
|
||||||
|
States: 3
|
||||||
|
Start: 0
|
||||||
|
AP: 1 "c"
|
||||||
|
acc-name: Buchi
|
||||||
|
Acceptance: 1 Inf(0)
|
||||||
|
properties: trans-labels explicit-labels state-acc deterministic
|
||||||
|
--BODY--
|
||||||
|
State: 0
|
||||||
|
[t] 1
|
||||||
|
State: 1
|
||||||
|
[0] 2
|
||||||
|
State: 2
|
||||||
|
--END--
|
||||||
|
EOF
|
||||||
|
|
||||||
|
run 0 ../../bin/autfilt -H --remove-ap=a=1,b=0 automaton >out
|
||||||
|
cat out
|
||||||
|
diff out expected
|
||||||
|
|
||||||
|
../../bin/autfilt -H --remove-ap=a==1 automaton 2>stderr && exit 1
|
||||||
|
grep "autfilt: unexpected '=' at position 2 in 'a==1'" stderr
|
||||||
Loading…
Add table
Add a link
Reference in a new issue