* src/misc/optionmap.cc, src/misc/optionmap.hh (option_map): New class.
* src/misc/Makefile.am: Add it. * src/tgbaalgos/emptiness.cc, src/tgbaalgos/emptiness.hh: Add option facilities to the classes emptiness_check and emptiness_result * src/tgbaalgos/magic.cc, src/tgbaalgos/magic.hh, src/tgbaalgos/se05.cc, src/tgbaalgos/se05.hh: Compute optionnaly accepting runs from stack. * src/tgbatest/randtgba.cc: Make this option public.
This commit is contained in:
parent
e812e1926f
commit
661dee8633
13 changed files with 578 additions and 95 deletions
11
ChangeLog
11
ChangeLog
|
|
@ -1,3 +1,14 @@
|
|||
2005-02-07 Denis Poitrenaud <Denis.Poitrenaud@lip6.fr>
|
||||
|
||||
* src/misc/optionmap.cc, src/misc/optionmap.hh (option_map): New class.
|
||||
* src/misc/Makefile.am: Add it.
|
||||
* src/tgbaalgos/emptiness.cc, src/tgbaalgos/emptiness.hh: Add option
|
||||
facilities to the classes emptiness_check and emptiness_result
|
||||
* src/tgbaalgos/magic.cc, src/tgbaalgos/magic.hh,
|
||||
src/tgbaalgos/se05.cc, src/tgbaalgos/se05.hh: Compute optionnaly
|
||||
accepting runs from stack.
|
||||
* src/tgbatest/randtgba.cc: Make this option public.
|
||||
|
||||
2005-02-05 Alexandre Duret-Lutz <adl@src.lip6.fr>
|
||||
|
||||
* src/misc/ltstr.hh: Include <functional>
|
||||
|
|
|
|||
40
INSTALL
40
INSTALL
|
|
@ -1,8 +1,5 @@
|
|||
Installation Instructions
|
||||
*************************
|
||||
|
||||
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004 Free
|
||||
Software Foundation, Inc.
|
||||
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software
|
||||
Foundation, Inc.
|
||||
|
||||
This file is free documentation; the Free Software Foundation gives
|
||||
unlimited permission to copy, distribute and modify it.
|
||||
|
|
@ -70,9 +67,9 @@ The simplest way to compile this package is:
|
|||
Compilers and Options
|
||||
=====================
|
||||
|
||||
Some systems require unusual options for compilation or linking that the
|
||||
`configure' script does not know about. Run `./configure --help' for
|
||||
details on some of the pertinent environment variables.
|
||||
Some systems require unusual options for compilation or linking that
|
||||
the `configure' script does not know about. Run `./configure --help'
|
||||
for details on some of the pertinent environment variables.
|
||||
|
||||
You can give `configure' initial values for configuration parameters
|
||||
by setting variables in the command line or in the environment. Here
|
||||
|
|
@ -105,16 +102,16 @@ Installation Names
|
|||
By default, `make install' will install the package's files in
|
||||
`/usr/local/bin', `/usr/local/man', etc. You can specify an
|
||||
installation prefix other than `/usr/local' by giving `configure' the
|
||||
option `--prefix=PREFIX'.
|
||||
option `--prefix=PATH'.
|
||||
|
||||
You can specify separate installation prefixes for
|
||||
architecture-specific files and architecture-independent files. If you
|
||||
give `configure' the option `--exec-prefix=PREFIX', the package will
|
||||
use PREFIX as the prefix for installing programs and libraries.
|
||||
give `configure' the option `--exec-prefix=PATH', the package will use
|
||||
PATH as the prefix for installing programs and libraries.
|
||||
Documentation and other data files will still use the regular prefix.
|
||||
|
||||
In addition, if you use an unusual directory layout you can give
|
||||
options like `--bindir=DIR' to specify different values for particular
|
||||
options like `--bindir=PATH' to specify different values for particular
|
||||
kinds of files. Run `configure --help' for a list of the directories
|
||||
you can set and what kinds of files go in them.
|
||||
|
||||
|
|
@ -140,11 +137,11 @@ you can use the `configure' options `--x-includes=DIR' and
|
|||
Specifying the System Type
|
||||
==========================
|
||||
|
||||
There may be some features `configure' cannot figure out automatically,
|
||||
but needs to determine by the type of machine the package will run on.
|
||||
Usually, assuming the package is built to be run on the _same_
|
||||
architectures, `configure' can figure that out, but if it prints a
|
||||
message saying it cannot guess the machine type, give it the
|
||||
There may be some features `configure' cannot figure out
|
||||
automatically, but needs to determine by the type of machine the package
|
||||
will run on. Usually, assuming the package is built to be run on the
|
||||
_same_ architectures, `configure' can figure that out, but if it prints
|
||||
a message saying it cannot guess the machine type, give it the
|
||||
`--build=TYPE' option. TYPE can either be a short name for the system
|
||||
type, such as `sun4', or a canonical name which has the form:
|
||||
|
||||
|
|
@ -170,9 +167,9 @@ eventually be run) with `--host=TYPE'.
|
|||
Sharing Defaults
|
||||
================
|
||||
|
||||
If you want to set default values for `configure' scripts to share, you
|
||||
can create a site shell script called `config.site' that gives default
|
||||
values for variables like `CC', `cache_file', and `prefix'.
|
||||
If you want to set default values for `configure' scripts to share,
|
||||
you can create a site shell script called `config.site' that gives
|
||||
default values for variables like `CC', `cache_file', and `prefix'.
|
||||
`configure' looks for `PREFIX/share/config.site' if it exists, then
|
||||
`PREFIX/etc/config.site' if it exists. Or, you can set the
|
||||
`CONFIG_SITE' environment variable to the location of the site script.
|
||||
|
|
@ -195,7 +192,8 @@ overridden in the site shell script).
|
|||
`configure' Invocation
|
||||
======================
|
||||
|
||||
`configure' recognizes the following options to control how it operates.
|
||||
`configure' recognizes the following options to control how it
|
||||
operates.
|
||||
|
||||
`--help'
|
||||
`-h'
|
||||
|
|
|
|||
40
lbtt/INSTALL
40
lbtt/INSTALL
|
|
@ -1,8 +1,5 @@
|
|||
Installation Instructions
|
||||
*************************
|
||||
|
||||
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004 Free
|
||||
Software Foundation, Inc.
|
||||
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software
|
||||
Foundation, Inc.
|
||||
|
||||
This file is free documentation; the Free Software Foundation gives
|
||||
unlimited permission to copy, distribute and modify it.
|
||||
|
|
@ -70,9 +67,9 @@ The simplest way to compile this package is:
|
|||
Compilers and Options
|
||||
=====================
|
||||
|
||||
Some systems require unusual options for compilation or linking that the
|
||||
`configure' script does not know about. Run `./configure --help' for
|
||||
details on some of the pertinent environment variables.
|
||||
Some systems require unusual options for compilation or linking that
|
||||
the `configure' script does not know about. Run `./configure --help'
|
||||
for details on some of the pertinent environment variables.
|
||||
|
||||
You can give `configure' initial values for configuration parameters
|
||||
by setting variables in the command line or in the environment. Here
|
||||
|
|
@ -105,16 +102,16 @@ Installation Names
|
|||
By default, `make install' will install the package's files in
|
||||
`/usr/local/bin', `/usr/local/man', etc. You can specify an
|
||||
installation prefix other than `/usr/local' by giving `configure' the
|
||||
option `--prefix=PREFIX'.
|
||||
option `--prefix=PATH'.
|
||||
|
||||
You can specify separate installation prefixes for
|
||||
architecture-specific files and architecture-independent files. If you
|
||||
give `configure' the option `--exec-prefix=PREFIX', the package will
|
||||
use PREFIX as the prefix for installing programs and libraries.
|
||||
give `configure' the option `--exec-prefix=PATH', the package will use
|
||||
PATH as the prefix for installing programs and libraries.
|
||||
Documentation and other data files will still use the regular prefix.
|
||||
|
||||
In addition, if you use an unusual directory layout you can give
|
||||
options like `--bindir=DIR' to specify different values for particular
|
||||
options like `--bindir=PATH' to specify different values for particular
|
||||
kinds of files. Run `configure --help' for a list of the directories
|
||||
you can set and what kinds of files go in them.
|
||||
|
||||
|
|
@ -140,11 +137,11 @@ you can use the `configure' options `--x-includes=DIR' and
|
|||
Specifying the System Type
|
||||
==========================
|
||||
|
||||
There may be some features `configure' cannot figure out automatically,
|
||||
but needs to determine by the type of machine the package will run on.
|
||||
Usually, assuming the package is built to be run on the _same_
|
||||
architectures, `configure' can figure that out, but if it prints a
|
||||
message saying it cannot guess the machine type, give it the
|
||||
There may be some features `configure' cannot figure out
|
||||
automatically, but needs to determine by the type of machine the package
|
||||
will run on. Usually, assuming the package is built to be run on the
|
||||
_same_ architectures, `configure' can figure that out, but if it prints
|
||||
a message saying it cannot guess the machine type, give it the
|
||||
`--build=TYPE' option. TYPE can either be a short name for the system
|
||||
type, such as `sun4', or a canonical name which has the form:
|
||||
|
||||
|
|
@ -170,9 +167,9 @@ eventually be run) with `--host=TYPE'.
|
|||
Sharing Defaults
|
||||
================
|
||||
|
||||
If you want to set default values for `configure' scripts to share, you
|
||||
can create a site shell script called `config.site' that gives default
|
||||
values for variables like `CC', `cache_file', and `prefix'.
|
||||
If you want to set default values for `configure' scripts to share,
|
||||
you can create a site shell script called `config.site' that gives
|
||||
default values for variables like `CC', `cache_file', and `prefix'.
|
||||
`configure' looks for `PREFIX/share/config.site' if it exists, then
|
||||
`PREFIX/etc/config.site' if it exists. Or, you can set the
|
||||
`CONFIG_SITE' environment variable to the location of the site script.
|
||||
|
|
@ -195,7 +192,8 @@ overridden in the site shell script).
|
|||
`configure' Invocation
|
||||
======================
|
||||
|
||||
`configure' recognizes the following options to control how it operates.
|
||||
`configure' recognizes the following options to control how it
|
||||
operates.
|
||||
|
||||
`--help'
|
||||
`-h'
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ misc_HEADERS = \
|
|||
ltstr.hh \
|
||||
minato.hh \
|
||||
modgray.hh \
|
||||
optionmap.hh \
|
||||
random.hh \
|
||||
timer.hh \
|
||||
version.hh
|
||||
|
|
@ -47,6 +48,7 @@ libmisc_la_SOURCES = \
|
|||
freelist.cc \
|
||||
minato.cc \
|
||||
modgray.cc \
|
||||
optionmap.cc \
|
||||
random.cc \
|
||||
timer.cc \
|
||||
version.cc
|
||||
|
|
|
|||
102
src/misc/optionmap.cc
Normal file
102
src/misc/optionmap.cc
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
// Copyright (C) 2005 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 2 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 Spot; see the file COPYING. If not, write to the Free
|
||||
// Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
// 02111-1307, USA.
|
||||
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include "optionmap.hh"
|
||||
|
||||
namespace spot
|
||||
{
|
||||
namespace {
|
||||
bool
|
||||
to_int(const char* s, int &i)
|
||||
{
|
||||
char* endptr;
|
||||
int res = strtol(s, &endptr, 10);
|
||||
if (*endptr)
|
||||
{
|
||||
std::cerr << "Failed to parse `" << s << "' as an integer."
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
i = res;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
const char* option_map::parse_options(char* options)
|
||||
{
|
||||
char* opt = strtok(options, "\t, ;");
|
||||
while (opt)
|
||||
{
|
||||
char* equal;
|
||||
if ((equal = strchr(opt, '=')) != 0)
|
||||
{
|
||||
*equal = 0;
|
||||
int val;
|
||||
if (!to_int(equal+1, val))
|
||||
return opt;
|
||||
options_[opt] = val;
|
||||
}
|
||||
else
|
||||
// default value if declared
|
||||
options_[opt] = 1;
|
||||
opt = strtok(0, "\t, ;");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int option_map::get(const char* option) const
|
||||
{
|
||||
std::map<std::string, int>::const_iterator it = options_.find(option);
|
||||
if (it == options_.end())
|
||||
// default value if not declared
|
||||
return 0;
|
||||
else
|
||||
return it->second;
|
||||
}
|
||||
|
||||
int option_map::operator[](const char* option) const
|
||||
{
|
||||
return get(option);
|
||||
}
|
||||
|
||||
int option_map::set(const char* option, int val)
|
||||
{
|
||||
int old = get(option);
|
||||
options_[option] = val;
|
||||
return old;
|
||||
}
|
||||
|
||||
int& option_map::operator[](const char* option)
|
||||
{
|
||||
return options_[option];
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const option_map& m)
|
||||
{
|
||||
for (std::map<std::string, int>::const_iterator it = m.options_.begin();
|
||||
it != m.options_.end(); ++it)
|
||||
os << "\"" << it->first << "\" = " << it->second << std::endl;
|
||||
return os;
|
||||
}
|
||||
};
|
||||
74
src/misc/optionmap.hh
Normal file
74
src/misc/optionmap.hh
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
// Copyright (C) 2005 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 2 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 Spot; see the file COPYING. If not, write to the Free
|
||||
// Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
// 02111-1307, USA.
|
||||
|
||||
#ifndef SPOT_MISC_OPTION_MAP_HH
|
||||
# define SPOT_MISC_OPTION_MAP_HH
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <iosfwd>
|
||||
|
||||
namespace spot
|
||||
{
|
||||
/// \brief Manage a map of options.
|
||||
/// \ingroup misc_tools
|
||||
/// Each option is defined by a string and is associated to an integer value.
|
||||
class option_map
|
||||
{
|
||||
public:
|
||||
/// \brief Add the parsed options to the map.
|
||||
///
|
||||
/// \a options are separated by a space, comma, semicolon or tabulation and
|
||||
/// can be optionnaly followed by an integer value (preceded by an equal
|
||||
/// sign). If not specified, the default value is 1.
|
||||
///
|
||||
/// \return A non-null pointer to the option for which an expected integer
|
||||
/// value cannot be parsed.
|
||||
const char* parse_options(char* options);
|
||||
|
||||
/// \brief Get the value of \a option.
|
||||
///
|
||||
/// \return The value associated to \a option if it exists, 0 otherwise.
|
||||
int get(const char* option) const;
|
||||
|
||||
/// \brief Get the value of \a option.
|
||||
///
|
||||
/// \return The value associated to \a option if it exists, 0 otherwise.
|
||||
int operator[](const char* option) const;
|
||||
|
||||
/// \brief Set the value of \a option to \a val.
|
||||
///
|
||||
/// \return The current value associated to \a option if declared,
|
||||
/// 0 otherwise.
|
||||
int set(const char* option, int val);
|
||||
|
||||
/// \brief Get a reference to the current value of \a option.
|
||||
int& operator[](const char* option);
|
||||
|
||||
/// \brief Print the option_map \a m.
|
||||
friend std::ostream& operator<<(std::ostream& os, const option_map& m);
|
||||
|
||||
private:
|
||||
std::map<std::string, int> options_;
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -27,7 +27,6 @@
|
|||
|
||||
namespace spot
|
||||
{
|
||||
|
||||
tgba_run::~tgba_run()
|
||||
{
|
||||
for (steps::const_iterator i = prefix.begin(); i != prefix.end(); ++i)
|
||||
|
|
|
|||
|
|
@ -22,9 +22,11 @@
|
|||
#ifndef SPOT_TGBAALGOS_EMPTINESS_HH
|
||||
# define SPOT_TGBAALGOS_EMPTINESS_HH
|
||||
|
||||
#include <map>
|
||||
#include <list>
|
||||
#include <iosfwd>
|
||||
#include <bdd.h>
|
||||
#include "misc/optionmap.hh"
|
||||
#include "tgba/state.hh"
|
||||
#include "emptiness_stats.hh"
|
||||
|
||||
|
|
@ -74,8 +76,13 @@ namespace spot
|
|||
class emptiness_check_result
|
||||
{
|
||||
public:
|
||||
emptiness_check_result(const tgba* a)
|
||||
: a_(a)
|
||||
emptiness_check_result(const tgba* a, option_map o = option_map())
|
||||
: a_(a), o_(o)
|
||||
{
|
||||
}
|
||||
|
||||
virtual
|
||||
~emptiness_check_result()
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -100,19 +107,43 @@ namespace spot
|
|||
return a_;
|
||||
}
|
||||
|
||||
/// Return the options parametrizing how the accepting run is computed.
|
||||
const option_map&
|
||||
options() const
|
||||
{
|
||||
return o_;
|
||||
}
|
||||
|
||||
/// Modify the options parametrizing how the accepting run is computed.
|
||||
const char*
|
||||
parse_options(char* options)
|
||||
{
|
||||
option_map old(o_);
|
||||
const char* s = o_.parse_options(options);
|
||||
options_updated(old);
|
||||
return s;
|
||||
}
|
||||
|
||||
/// Return statistics, if available.
|
||||
virtual const unsigned_statistics* statistics() const;
|
||||
|
||||
protected:
|
||||
/// React when options are modified.
|
||||
virtual void options_updated(const option_map& old)
|
||||
{
|
||||
(void)old;
|
||||
}
|
||||
|
||||
const tgba* a_; ///< The automaton.
|
||||
option_map o_; ///< The options
|
||||
};
|
||||
|
||||
/// Common interface to emptiness check algorithms.
|
||||
class emptiness_check
|
||||
{
|
||||
public:
|
||||
emptiness_check(const tgba* a)
|
||||
: a_(a)
|
||||
emptiness_check(const tgba* a, option_map o = option_map())
|
||||
: a_(a), o_(o)
|
||||
{
|
||||
}
|
||||
virtual ~emptiness_check();
|
||||
|
|
@ -124,6 +155,23 @@ namespace spot
|
|||
return a_;
|
||||
}
|
||||
|
||||
/// Return the options parametrizing how the emptiness check is realized.
|
||||
const option_map&
|
||||
options() const
|
||||
{
|
||||
return o_;
|
||||
}
|
||||
|
||||
/// Modify the options parametrizing how the accepting run is realized.
|
||||
const char*
|
||||
parse_options(char* options)
|
||||
{
|
||||
option_map old(o_);
|
||||
const char* s = o_.parse_options(options);
|
||||
options_updated(old);
|
||||
return s;
|
||||
}
|
||||
|
||||
/// \brief Check whether the automaton contain an accepting run.
|
||||
///
|
||||
/// Return 0 if the automaton accept no run. Return an instance
|
||||
|
|
@ -142,8 +190,15 @@ namespace spot
|
|||
/// Print statistics, if any.
|
||||
virtual std::ostream& print_stats(std::ostream& os) const;
|
||||
|
||||
/// React when options are modified.
|
||||
virtual void options_updated(const option_map& old)
|
||||
{
|
||||
(void)old;
|
||||
}
|
||||
|
||||
protected:
|
||||
const tgba* a_; ///< The automaton.
|
||||
option_map o_; ///< The options
|
||||
};
|
||||
|
||||
/// @}
|
||||
|
|
|
|||
|
|
@ -53,8 +53,8 @@ namespace spot
|
|||
///
|
||||
/// \pre The automaton \a a must have at most one accepting
|
||||
/// condition (i.e. it is a TBA).
|
||||
magic_search(const tgba *a, size_t size)
|
||||
: emptiness_check(a),
|
||||
magic_search(const tgba *a, size_t size, option_map o = option_map())
|
||||
: emptiness_check(a, o),
|
||||
h(size),
|
||||
all_cond(a->all_acceptance_conditions())
|
||||
{
|
||||
|
|
@ -96,17 +96,17 @@ namespace spot
|
|||
h.add_new_state(s0, BLUE);
|
||||
push(st_blue, s0, bddfalse, bddfalse);
|
||||
if (dfs_blue())
|
||||
return new ndfs_result<magic_search<heap>, heap>(*this);
|
||||
return new magic_search_result(*this, options());
|
||||
}
|
||||
else
|
||||
{
|
||||
h.pop_notify(st_red.front().s);
|
||||
pop(st_red);
|
||||
if (!st_red.empty() && dfs_red())
|
||||
return new ndfs_result<magic_search<heap>, heap>(*this);
|
||||
return new magic_search_result(*this, options());
|
||||
else
|
||||
if (dfs_blue())
|
||||
return new ndfs_result<magic_search<heap>, heap>(*this);
|
||||
return new magic_search_result(*this, options());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -314,6 +314,108 @@ namespace spot
|
|||
return false;
|
||||
}
|
||||
|
||||
class result_from_stack: public emptiness_check_result,
|
||||
public acss_statistics
|
||||
{
|
||||
public:
|
||||
result_from_stack(magic_search& ms)
|
||||
: emptiness_check_result(ms.automaton()), ms_(ms)
|
||||
{
|
||||
}
|
||||
|
||||
virtual tgba_run* accepting_run()
|
||||
{
|
||||
assert(!ms_.st_blue.empty());
|
||||
assert(!ms_.st_red.empty());
|
||||
|
||||
tgba_run* run = new tgba_run;
|
||||
|
||||
typename stack_type::const_reverse_iterator i, j, end;
|
||||
tgba_run::steps* l;
|
||||
|
||||
l = &run->prefix;
|
||||
|
||||
i = ms_.st_blue.rbegin();
|
||||
end = ms_.st_blue.rend(); --end;
|
||||
j = i; ++j;
|
||||
for (; i != end; ++i, ++j)
|
||||
{
|
||||
tgba_run::step s = { i->s->clone(), j->label, j->acc };
|
||||
l->push_back(s);
|
||||
}
|
||||
|
||||
l = &run->cycle;
|
||||
|
||||
j = ms_.st_red.rbegin();
|
||||
tgba_run::step s = { i->s->clone(), j->label, j->acc };
|
||||
l->push_back(s);
|
||||
|
||||
i = j; ++j;
|
||||
end = ms_.st_red.rend(); --end;
|
||||
for (; i != end; ++i, ++j)
|
||||
{
|
||||
tgba_run::step s = { i->s->clone(), j->label, j->acc };
|
||||
l->push_back(s);
|
||||
}
|
||||
|
||||
return run;
|
||||
}
|
||||
|
||||
unsigned acss_states() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
private:
|
||||
magic_search& ms_;
|
||||
};
|
||||
|
||||
# define FROM_STACK "ar:from_stack"
|
||||
|
||||
class magic_search_result: public emptiness_check_result
|
||||
{
|
||||
public:
|
||||
magic_search_result(magic_search& m, option_map o = option_map())
|
||||
: emptiness_check_result(m.automaton(), o), ms(m)
|
||||
{
|
||||
if (options()[FROM_STACK])
|
||||
computer = new result_from_stack(ms);
|
||||
else
|
||||
computer = new ndfs_result<magic_search<heap>, heap>(ms);
|
||||
}
|
||||
|
||||
virtual void options_updated(const option_map& old)
|
||||
{
|
||||
if (old[FROM_STACK] && !options()[FROM_STACK])
|
||||
{
|
||||
delete computer;
|
||||
computer = new ndfs_result<magic_search<heap>, heap>(ms);
|
||||
}
|
||||
else if (!old[FROM_STACK] && options()[FROM_STACK])
|
||||
{
|
||||
delete computer;
|
||||
computer = new result_from_stack(ms);
|
||||
}
|
||||
}
|
||||
|
||||
virtual ~magic_search_result()
|
||||
{
|
||||
delete computer;
|
||||
}
|
||||
|
||||
virtual tgba_run* accepting_run()
|
||||
{
|
||||
return computer->accepting_run();
|
||||
}
|
||||
|
||||
virtual const unsigned_statistics* statistics() const
|
||||
{
|
||||
return computer->statistics();
|
||||
}
|
||||
|
||||
private:
|
||||
emptiness_check_result* computer;
|
||||
magic_search& ms;
|
||||
};
|
||||
};
|
||||
|
||||
class explicit_magic_search_heap
|
||||
|
|
@ -471,15 +573,15 @@ namespace spot
|
|||
|
||||
} // anonymous
|
||||
|
||||
emptiness_check* explicit_magic_search(const tgba *a)
|
||||
emptiness_check* explicit_magic_search(const tgba *a, option_map o)
|
||||
{
|
||||
return new magic_search<explicit_magic_search_heap>(a, 0);
|
||||
return new magic_search<explicit_magic_search_heap>(a, 0, o);
|
||||
}
|
||||
|
||||
emptiness_check* bit_state_hashing_magic_search(
|
||||
const tgba *a, size_t size)
|
||||
emptiness_check* bit_state_hashing_magic_search(const tgba *a, size_t size,
|
||||
option_map o)
|
||||
{
|
||||
return new magic_search<bsh_magic_search_heap>(a, size);
|
||||
return new magic_search<bsh_magic_search_heap>(a, size, o);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
# define SPOT_TGBAALGOS_MAGIC_HH
|
||||
|
||||
#include <cstddef>
|
||||
#include "misc/optionmap.hh"
|
||||
|
||||
namespace spot
|
||||
{
|
||||
|
|
@ -93,7 +94,8 @@ namespace spot
|
|||
/// }
|
||||
/// \endverbatim
|
||||
///
|
||||
emptiness_check* explicit_magic_search(const tgba *a);
|
||||
emptiness_check* explicit_magic_search(const tgba *a,
|
||||
option_map o = option_map());
|
||||
|
||||
/// \brief Returns an emptiness checker on the spot::tgba automaton \a a.
|
||||
///
|
||||
|
|
@ -113,13 +115,17 @@ namespace spot
|
|||
/// }
|
||||
/// \endverbatim
|
||||
///
|
||||
/// Consequently, the detection of an acceptence cycle is not ensured. The
|
||||
/// implemented algorithm is the same as the one of
|
||||
/// Consequently, the detection of an acceptence cycle is not ensured.
|
||||
///
|
||||
/// The size of the heap is limited to \n size bytes.
|
||||
///
|
||||
/// The implemented algorithm is the same as the one of
|
||||
/// spot::explicit_magic_search.
|
||||
///
|
||||
/// \sa spot::explicit_magic_search
|
||||
///
|
||||
emptiness_check* bit_state_hashing_magic_search(const tgba *a, size_t size);
|
||||
emptiness_check* bit_state_hashing_magic_search(const tgba *a, size_t size,
|
||||
option_map o = option_map());
|
||||
|
||||
/// @}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,8 +37,6 @@
|
|||
#include "se05.hh"
|
||||
#include "ndfs_result.hxx"
|
||||
|
||||
/// FIXME: make compiling depedent the taking into account of weights.
|
||||
|
||||
namespace spot
|
||||
{
|
||||
namespace
|
||||
|
|
@ -55,9 +53,8 @@ namespace spot
|
|||
///
|
||||
/// \pre The automaton \a a must have at most one accepting
|
||||
/// condition (i.e. it is a TBA).
|
||||
se05_search(const tgba *a, size_t size)
|
||||
: emptiness_check(a),
|
||||
ec_statistics(),
|
||||
se05_search(const tgba *a, size_t size, option_map o = option_map())
|
||||
: emptiness_check(a, o),
|
||||
h(size),
|
||||
all_cond(a->all_acceptance_conditions())
|
||||
{
|
||||
|
|
@ -99,17 +96,17 @@ namespace spot
|
|||
h.add_new_state(s0, CYAN);
|
||||
push(st_blue, s0, bddfalse, bddfalse);
|
||||
if (dfs_blue())
|
||||
return new ndfs_result<se05_search<heap>, heap>(*this);
|
||||
return new se05_result(*this, options());
|
||||
}
|
||||
else
|
||||
{
|
||||
h.pop_notify(st_red.front().s);
|
||||
pop(st_red);
|
||||
if (!st_red.empty() && dfs_red())
|
||||
return new ndfs_result<se05_search<heap>, heap>(*this);
|
||||
return new se05_result(*this, options());
|
||||
else
|
||||
if (dfs_blue())
|
||||
return new ndfs_result<se05_search<heap>, heap>(*this);
|
||||
return new se05_result(*this, options());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -322,6 +319,114 @@ namespace spot
|
|||
return false;
|
||||
}
|
||||
|
||||
class result_from_stack: public emptiness_check_result,
|
||||
public acss_statistics
|
||||
{
|
||||
public:
|
||||
result_from_stack(se05_search& ms)
|
||||
: emptiness_check_result(ms.automaton()), ms_(ms)
|
||||
{
|
||||
}
|
||||
|
||||
virtual tgba_run* accepting_run()
|
||||
{
|
||||
assert(!ms_.st_blue.empty());
|
||||
assert(!ms_.st_red.empty());
|
||||
|
||||
tgba_run* run = new tgba_run;
|
||||
|
||||
typename stack_type::const_reverse_iterator i, j, end;
|
||||
tgba_run::steps* l;
|
||||
|
||||
const state* target = ms_.st_red.front().s;
|
||||
|
||||
l = &run->prefix;
|
||||
|
||||
i = ms_.st_blue.rbegin();
|
||||
end = ms_.st_blue.rend(); --end;
|
||||
j = i; ++j;
|
||||
for (; i != end; ++i, ++j)
|
||||
{
|
||||
if (l == &run->prefix && i->s->compare(target) == 0)
|
||||
l = &run->cycle;
|
||||
tgba_run::step s = { i->s->clone(), j->label, j->acc };
|
||||
l->push_back(s);
|
||||
}
|
||||
|
||||
if (l == &run->prefix && i->s->compare(target) == 0)
|
||||
l = &run->cycle;
|
||||
assert(l == &run->cycle);
|
||||
|
||||
j = ms_.st_red.rbegin();
|
||||
tgba_run::step s = { i->s->clone(), j->label, j->acc };
|
||||
l->push_back(s);
|
||||
|
||||
i = j; ++j;
|
||||
end = ms_.st_red.rend(); --end;
|
||||
for (; i != end; ++i, ++j)
|
||||
{
|
||||
tgba_run::step s = { i->s->clone(), j->label, j->acc };
|
||||
l->push_back(s);
|
||||
}
|
||||
|
||||
return run;
|
||||
}
|
||||
|
||||
unsigned acss_states() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
private:
|
||||
se05_search& ms_;
|
||||
};
|
||||
|
||||
# define FROM_STACK "ar:from_stack"
|
||||
|
||||
class se05_result: public emptiness_check_result
|
||||
{
|
||||
public:
|
||||
se05_result(se05_search& m, option_map o = option_map())
|
||||
: emptiness_check_result(m.automaton(), o), ms(m)
|
||||
{
|
||||
if (options()[FROM_STACK])
|
||||
computer = new result_from_stack(ms);
|
||||
else
|
||||
computer = new ndfs_result<se05_search<heap>, heap>(ms);
|
||||
}
|
||||
|
||||
virtual void options_updated(const option_map& old)
|
||||
{
|
||||
if (old[FROM_STACK] && !options()[FROM_STACK])
|
||||
{
|
||||
delete computer;
|
||||
computer = new ndfs_result<se05_search<heap>, heap>(ms);
|
||||
}
|
||||
else if (!old[FROM_STACK] && options()[FROM_STACK])
|
||||
{
|
||||
delete computer;
|
||||
computer = new result_from_stack(ms);
|
||||
}
|
||||
}
|
||||
|
||||
virtual ~se05_result()
|
||||
{
|
||||
delete computer;
|
||||
}
|
||||
|
||||
virtual tgba_run* accepting_run()
|
||||
{
|
||||
return computer->accepting_run();
|
||||
}
|
||||
|
||||
virtual const unsigned_statistics* statistics() const
|
||||
{
|
||||
return computer->statistics();
|
||||
}
|
||||
|
||||
private:
|
||||
emptiness_check_result* computer;
|
||||
se05_search& ms;
|
||||
};
|
||||
};
|
||||
|
||||
class explicit_se05_search_heap
|
||||
|
|
@ -559,14 +664,15 @@ namespace spot
|
|||
|
||||
} // anonymous
|
||||
|
||||
emptiness_check* explicit_se05_search(const tgba *a)
|
||||
emptiness_check* explicit_se05_search(const tgba *a, option_map o)
|
||||
{
|
||||
return new se05_search<explicit_se05_search_heap>(a, 0);
|
||||
return new se05_search<explicit_se05_search_heap>(a, 0, o);
|
||||
}
|
||||
|
||||
emptiness_check* bit_state_hashing_se05_search(const tgba *a, size_t size)
|
||||
emptiness_check* bit_state_hashing_se05_search(const tgba *a, size_t size,
|
||||
option_map o)
|
||||
{
|
||||
return new se05_search<bsh_se05_search_heap>(a, size);
|
||||
return new se05_search<bsh_se05_search_heap>(a, size, o);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
# define SPOT_TGBAALGOS_SE05_HH
|
||||
|
||||
#include <cstddef>
|
||||
#include "misc/optionmap.hh"
|
||||
|
||||
namespace spot
|
||||
{
|
||||
|
|
@ -100,8 +101,8 @@ namespace spot
|
|||
///
|
||||
/// \sa spot::explicit_magic_search
|
||||
///
|
||||
emptiness_check* explicit_se05_search(const tgba *a);
|
||||
|
||||
emptiness_check* explicit_se05_search(const tgba *a,
|
||||
option_map o = option_map());
|
||||
/// \brief Returns an emptiness checker on the spot::tgba automaton \a a.
|
||||
///
|
||||
/// \pre The automaton \a a must have at most one accepting condition (i.e.
|
||||
|
|
@ -120,13 +121,17 @@ namespace spot
|
|||
/// }
|
||||
/// \endverbatim
|
||||
///
|
||||
/// Consequently, the detection of an acceptence cycle is not ensured. The
|
||||
/// implemented algorithm is the same as the one of
|
||||
/// Consequently, the detection of an acceptence cycle is not ensured.
|
||||
///
|
||||
/// The size of the heap is limited to \n size bytes.
|
||||
///
|
||||
/// The implemented algorithm is the same as the one of
|
||||
/// spot::explicit_se05_search.
|
||||
///
|
||||
/// \sa spot::explicit_se05_search
|
||||
///
|
||||
emptiness_check* bit_state_hashing_se05_search(const tgba *a, size_t size);
|
||||
emptiness_check* bit_state_hashing_se05_search(const tgba *a, size_t size,
|
||||
option_map o = option_map());
|
||||
|
||||
/// @}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@
|
|||
#include "tgbaalgos/dotty.hh"
|
||||
#include "tgbaparse/public.hh"
|
||||
#include "misc/random.hh"
|
||||
#include "misc/optionmap.hh"
|
||||
#include "tgba/tgbatba.hh"
|
||||
#include "tgba/tgbaproduct.hh"
|
||||
#include "misc/timer.hh"
|
||||
|
|
@ -61,6 +62,7 @@
|
|||
#include "tgbaalgos/tau03opt.hh"
|
||||
#include "tgbaalgos/replayrun.hh"
|
||||
|
||||
spot::option_map options;
|
||||
|
||||
spot::emptiness_check*
|
||||
couvreur99_cons(const spot::tgba* a)
|
||||
|
|
@ -98,16 +100,28 @@ couvreur99_rem_shy_minus_cons(const spot::tgba* a)
|
|||
return new spot::couvreur99_check_shy(a, true, false);
|
||||
}
|
||||
|
||||
spot::emptiness_check*
|
||||
ms_cons(const spot::tgba* a)
|
||||
{
|
||||
return spot::explicit_magic_search(a, options);
|
||||
}
|
||||
|
||||
spot::emptiness_check*
|
||||
se05_cons(const spot::tgba* a)
|
||||
{
|
||||
return spot::explicit_se05_search(a, options);
|
||||
}
|
||||
|
||||
spot::emptiness_check*
|
||||
bsh_ms_cons(const spot::tgba* a)
|
||||
{
|
||||
return spot::bit_state_hashing_magic_search(a, 4096);
|
||||
return spot::bit_state_hashing_magic_search(a, 4096, options);
|
||||
}
|
||||
|
||||
spot::emptiness_check*
|
||||
bsh_se05_cons(const spot::tgba* a)
|
||||
{
|
||||
return spot::bit_state_hashing_se05_search(a, 4096);
|
||||
return spot::bit_state_hashing_se05_search(a, 4096, options);
|
||||
}
|
||||
|
||||
struct ec_algo
|
||||
|
|
@ -127,10 +141,10 @@ ec_algo ec_algos[] =
|
|||
{ "Cou99_rem", couvreur99_rem_cons, 0, -1U, true },
|
||||
{ "Cou99_rem_shy-", couvreur99_rem_shy_minus_cons, 0, -1U, true },
|
||||
{ "Cou99_rem_shy", couvreur99_rem_shy_cons, 0, -1U, true },
|
||||
{ "CVWY90", spot::explicit_magic_search, 0, 1, true },
|
||||
{ "CVWY90", ms_cons, 0, 1, true },
|
||||
{ "CVWY90_bsh", bsh_ms_cons, 0, 1, false },
|
||||
{ "GV04", spot::explicit_gv04_check, 0, 1, true },
|
||||
{ "SE05", spot::explicit_se05_search, 0, 1, true },
|
||||
{ "SE05", se05_cons, 0, 1, true },
|
||||
{ "SE05_bsh", bsh_se05_cons, 0, 1, false },
|
||||
{ "Tau03", spot::explicit_tau03_search, 1, -1U, true },
|
||||
{ "Tau03_opt", spot::explicit_tau03_opt_search, 0, -1U, true },
|
||||
|
|
@ -196,8 +210,10 @@ syntax(char* prog)
|
|||
<< " -O ALGO run Only ALGO" << std::endl
|
||||
<< " -R N repeat each emptiness-check and accepting run "
|
||||
<< "computation N times" << std::endl
|
||||
<< " -r compute and replay acceptance runs (implies -e)"
|
||||
<< " -r compute and replay accepting runs (implies -e)"
|
||||
<< std::endl
|
||||
<< " ar:MODE select the mode MODE for accepting runs computation "
|
||||
<< "(implies -r)" << std::endl
|
||||
<< std::endl
|
||||
<< "Where:" << std::endl
|
||||
<< " F are floats between 0.0 and 1.0 inclusive" << std::endl
|
||||
|
|
@ -945,6 +961,15 @@ main(int argc, char** argv)
|
|||
opt_n_acc = to_int_nonneg(argv[++argn], "-a");
|
||||
opt_a = to_float_nonneg(argv[++argn], "-a");
|
||||
}
|
||||
else if (!strncmp(argv[argn], "ar:", 3))
|
||||
{
|
||||
if (options.parse_options(argv[argn]))
|
||||
{
|
||||
std::cerr << "Failed to parse " << argv[argn] << std::endl;
|
||||
exit(2);
|
||||
}
|
||||
|
||||
}
|
||||
else if (!strcmp(argv[argn], "-d"))
|
||||
{
|
||||
if (argc < argn + 2)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue