* 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:
Denis Poitrenaud 2005-02-07 15:18:41 +00:00
parent e812e1926f
commit 661dee8633
13 changed files with 578 additions and 95 deletions

View file

@ -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> 2005-02-05 Alexandre Duret-Lutz <adl@src.lip6.fr>
* src/misc/ltstr.hh: Include <functional> * src/misc/ltstr.hh: Include <functional>

52
INSTALL
View file

@ -1,16 +1,13 @@
Installation Instructions Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software
************************* Foundation, Inc.
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004 Free This file is free documentation; the Free Software Foundation gives
Software Foundation, Inc.
This file is free documentation; the Free Software Foundation gives
unlimited permission to copy, distribute and modify it. unlimited permission to copy, distribute and modify it.
Basic Installation Basic Installation
================== ==================
These are generic installation instructions. These are generic installation instructions.
The `configure' shell script attempts to guess correct values for The `configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation. It uses various system-dependent variables used during compilation. It uses
@ -70,9 +67,9 @@ The simplest way to compile this package is:
Compilers and Options Compilers and Options
===================== =====================
Some systems require unusual options for compilation or linking that the Some systems require unusual options for compilation or linking that
`configure' script does not know about. Run `./configure --help' for the `configure' script does not know about. Run `./configure --help'
details on some of the pertinent environment variables. for details on some of the pertinent environment variables.
You can give `configure' initial values for configuration parameters You can give `configure' initial values for configuration parameters
by setting variables in the command line or in the environment. Here by setting variables in the command line or in the environment. Here
@ -85,7 +82,7 @@ is an example:
Compiling For Multiple Architectures Compiling For Multiple Architectures
==================================== ====================================
You can compile the package for more than one kind of computer at the You can compile the package for more than one kind of computer at the
same time, by placing the object files for each architecture in their same time, by placing the object files for each architecture in their
own directory. To do this, you must use a version of `make' that own directory. To do this, you must use a version of `make' that
supports the `VPATH' variable, such as GNU `make'. `cd' to the supports the `VPATH' variable, such as GNU `make'. `cd' to the
@ -102,19 +99,19 @@ for another architecture.
Installation Names Installation Names
================== ==================
By default, `make install' will install the package's files in By default, `make install' will install the package's files in
`/usr/local/bin', `/usr/local/man', etc. You can specify an `/usr/local/bin', `/usr/local/man', etc. You can specify an
installation prefix other than `/usr/local' by giving `configure' the installation prefix other than `/usr/local' by giving `configure' the
option `--prefix=PREFIX'. option `--prefix=PATH'.
You can specify separate installation prefixes for You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you architecture-specific files and architecture-independent files. If you
give `configure' the option `--exec-prefix=PREFIX', the package will give `configure' the option `--exec-prefix=PATH', the package will use
use PREFIX as the prefix for installing programs and libraries. PATH as the prefix for installing programs and libraries.
Documentation and other data files will still use the regular prefix. Documentation and other data files will still use the regular prefix.
In addition, if you use an unusual directory layout you can give 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 kinds of files. Run `configure --help' for a list of the directories
you can set and what kinds of files go in them. you can set and what kinds of files go in them.
@ -125,7 +122,7 @@ option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
Optional Features Optional Features
================= =================
Some packages pay attention to `--enable-FEATURE' options to Some packages pay attention to `--enable-FEATURE' options to
`configure', where FEATURE indicates an optional part of the package. `configure', where FEATURE indicates an optional part of the package.
They may also pay attention to `--with-PACKAGE' options, where PACKAGE They may also pay attention to `--with-PACKAGE' options, where PACKAGE
is something like `gnu-as' or `x' (for the X Window System). The is something like `gnu-as' or `x' (for the X Window System). The
@ -140,11 +137,11 @@ you can use the `configure' options `--x-includes=DIR' and
Specifying the System Type Specifying the System Type
========================== ==========================
There may be some features `configure' cannot figure out automatically, There may be some features `configure' cannot figure out
but needs to determine by the type of machine the package will run on. automatically, but needs to determine by the type of machine the package
Usually, assuming the package is built to be run on the _same_ will run on. Usually, assuming the package is built to be run on the
architectures, `configure' can figure that out, but if it prints a _same_ architectures, `configure' can figure that out, but if it prints
message saying it cannot guess the machine type, give it the 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 `--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: type, such as `sun4', or a canonical name which has the form:
@ -170,9 +167,9 @@ eventually be run) with `--host=TYPE'.
Sharing Defaults Sharing Defaults
================ ================
If you want to set default values for `configure' scripts to share, you If you want to set default values for `configure' scripts to share,
can create a site shell script called `config.site' that gives default you can create a site shell script called `config.site' that gives
values for variables like `CC', `cache_file', and `prefix'. default values for variables like `CC', `cache_file', and `prefix'.
`configure' looks for `PREFIX/share/config.site' if it exists, then `configure' looks for `PREFIX/share/config.site' if it exists, then
`PREFIX/etc/config.site' if it exists. Or, you can set the `PREFIX/etc/config.site' if it exists. Or, you can set the
`CONFIG_SITE' environment variable to the location of the site script. `CONFIG_SITE' environment variable to the location of the site script.
@ -181,7 +178,7 @@ A warning: not all `configure' scripts look for a site script.
Defining Variables Defining Variables
================== ==================
Variables not defined in a site shell script can be set in the Variables not defined in a site shell script can be set in the
environment passed to `configure'. However, some packages may run environment passed to `configure'. However, some packages may run
configure again during the build, and the customized values of these configure again during the build, and the customized values of these
variables may be lost. In order to avoid this problem, you should set variables may be lost. In order to avoid this problem, you should set
@ -195,7 +192,8 @@ overridden in the site shell script).
`configure' Invocation `configure' Invocation
====================== ======================
`configure' recognizes the following options to control how it operates. `configure' recognizes the following options to control how it
operates.
`--help' `--help'
`-h' `-h'

View file

@ -1,16 +1,13 @@
Installation Instructions Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software
************************* Foundation, Inc.
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004 Free This file is free documentation; the Free Software Foundation gives
Software Foundation, Inc.
This file is free documentation; the Free Software Foundation gives
unlimited permission to copy, distribute and modify it. unlimited permission to copy, distribute and modify it.
Basic Installation Basic Installation
================== ==================
These are generic installation instructions. These are generic installation instructions.
The `configure' shell script attempts to guess correct values for The `configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation. It uses various system-dependent variables used during compilation. It uses
@ -70,9 +67,9 @@ The simplest way to compile this package is:
Compilers and Options Compilers and Options
===================== =====================
Some systems require unusual options for compilation or linking that the Some systems require unusual options for compilation or linking that
`configure' script does not know about. Run `./configure --help' for the `configure' script does not know about. Run `./configure --help'
details on some of the pertinent environment variables. for details on some of the pertinent environment variables.
You can give `configure' initial values for configuration parameters You can give `configure' initial values for configuration parameters
by setting variables in the command line or in the environment. Here by setting variables in the command line or in the environment. Here
@ -85,7 +82,7 @@ is an example:
Compiling For Multiple Architectures Compiling For Multiple Architectures
==================================== ====================================
You can compile the package for more than one kind of computer at the You can compile the package for more than one kind of computer at the
same time, by placing the object files for each architecture in their same time, by placing the object files for each architecture in their
own directory. To do this, you must use a version of `make' that own directory. To do this, you must use a version of `make' that
supports the `VPATH' variable, such as GNU `make'. `cd' to the supports the `VPATH' variable, such as GNU `make'. `cd' to the
@ -102,19 +99,19 @@ for another architecture.
Installation Names Installation Names
================== ==================
By default, `make install' will install the package's files in By default, `make install' will install the package's files in
`/usr/local/bin', `/usr/local/man', etc. You can specify an `/usr/local/bin', `/usr/local/man', etc. You can specify an
installation prefix other than `/usr/local' by giving `configure' the installation prefix other than `/usr/local' by giving `configure' the
option `--prefix=PREFIX'. option `--prefix=PATH'.
You can specify separate installation prefixes for You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you architecture-specific files and architecture-independent files. If you
give `configure' the option `--exec-prefix=PREFIX', the package will give `configure' the option `--exec-prefix=PATH', the package will use
use PREFIX as the prefix for installing programs and libraries. PATH as the prefix for installing programs and libraries.
Documentation and other data files will still use the regular prefix. Documentation and other data files will still use the regular prefix.
In addition, if you use an unusual directory layout you can give 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 kinds of files. Run `configure --help' for a list of the directories
you can set and what kinds of files go in them. you can set and what kinds of files go in them.
@ -125,7 +122,7 @@ option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
Optional Features Optional Features
================= =================
Some packages pay attention to `--enable-FEATURE' options to Some packages pay attention to `--enable-FEATURE' options to
`configure', where FEATURE indicates an optional part of the package. `configure', where FEATURE indicates an optional part of the package.
They may also pay attention to `--with-PACKAGE' options, where PACKAGE They may also pay attention to `--with-PACKAGE' options, where PACKAGE
is something like `gnu-as' or `x' (for the X Window System). The is something like `gnu-as' or `x' (for the X Window System). The
@ -140,11 +137,11 @@ you can use the `configure' options `--x-includes=DIR' and
Specifying the System Type Specifying the System Type
========================== ==========================
There may be some features `configure' cannot figure out automatically, There may be some features `configure' cannot figure out
but needs to determine by the type of machine the package will run on. automatically, but needs to determine by the type of machine the package
Usually, assuming the package is built to be run on the _same_ will run on. Usually, assuming the package is built to be run on the
architectures, `configure' can figure that out, but if it prints a _same_ architectures, `configure' can figure that out, but if it prints
message saying it cannot guess the machine type, give it the 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 `--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: type, such as `sun4', or a canonical name which has the form:
@ -170,9 +167,9 @@ eventually be run) with `--host=TYPE'.
Sharing Defaults Sharing Defaults
================ ================
If you want to set default values for `configure' scripts to share, you If you want to set default values for `configure' scripts to share,
can create a site shell script called `config.site' that gives default you can create a site shell script called `config.site' that gives
values for variables like `CC', `cache_file', and `prefix'. default values for variables like `CC', `cache_file', and `prefix'.
`configure' looks for `PREFIX/share/config.site' if it exists, then `configure' looks for `PREFIX/share/config.site' if it exists, then
`PREFIX/etc/config.site' if it exists. Or, you can set the `PREFIX/etc/config.site' if it exists. Or, you can set the
`CONFIG_SITE' environment variable to the location of the site script. `CONFIG_SITE' environment variable to the location of the site script.
@ -181,7 +178,7 @@ A warning: not all `configure' scripts look for a site script.
Defining Variables Defining Variables
================== ==================
Variables not defined in a site shell script can be set in the Variables not defined in a site shell script can be set in the
environment passed to `configure'. However, some packages may run environment passed to `configure'. However, some packages may run
configure again during the build, and the customized values of these configure again during the build, and the customized values of these
variables may be lost. In order to avoid this problem, you should set variables may be lost. In order to avoid this problem, you should set
@ -195,7 +192,8 @@ overridden in the site shell script).
`configure' Invocation `configure' Invocation
====================== ======================
`configure' recognizes the following options to control how it operates. `configure' recognizes the following options to control how it
operates.
`--help' `--help'
`-h' `-h'

View file

@ -35,6 +35,7 @@ misc_HEADERS = \
ltstr.hh \ ltstr.hh \
minato.hh \ minato.hh \
modgray.hh \ modgray.hh \
optionmap.hh \
random.hh \ random.hh \
timer.hh \ timer.hh \
version.hh version.hh
@ -47,6 +48,7 @@ libmisc_la_SOURCES = \
freelist.cc \ freelist.cc \
minato.cc \ minato.cc \
modgray.cc \ modgray.cc \
optionmap.cc \
random.cc \ random.cc \
timer.cc \ timer.cc \
version.cc version.cc

102
src/misc/optionmap.cc Normal file
View 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
View 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

View file

@ -27,7 +27,6 @@
namespace spot namespace spot
{ {
tgba_run::~tgba_run() tgba_run::~tgba_run()
{ {
for (steps::const_iterator i = prefix.begin(); i != prefix.end(); ++i) for (steps::const_iterator i = prefix.begin(); i != prefix.end(); ++i)

View file

@ -22,9 +22,11 @@
#ifndef SPOT_TGBAALGOS_EMPTINESS_HH #ifndef SPOT_TGBAALGOS_EMPTINESS_HH
# define SPOT_TGBAALGOS_EMPTINESS_HH # define SPOT_TGBAALGOS_EMPTINESS_HH
#include <map>
#include <list> #include <list>
#include <iosfwd> #include <iosfwd>
#include <bdd.h> #include <bdd.h>
#include "misc/optionmap.hh"
#include "tgba/state.hh" #include "tgba/state.hh"
#include "emptiness_stats.hh" #include "emptiness_stats.hh"
@ -74,8 +76,13 @@ namespace spot
class emptiness_check_result class emptiness_check_result
{ {
public: public:
emptiness_check_result(const tgba* a) emptiness_check_result(const tgba* a, option_map o = option_map())
: a_(a) : a_(a), o_(o)
{
}
virtual
~emptiness_check_result()
{ {
} }
@ -100,19 +107,43 @@ namespace spot
return a_; 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. /// Return statistics, if available.
virtual const unsigned_statistics* statistics() const; virtual const unsigned_statistics* statistics() const;
protected: protected:
/// React when options are modified.
virtual void options_updated(const option_map& old)
{
(void)old;
}
const tgba* a_; ///< The automaton. const tgba* a_; ///< The automaton.
option_map o_; ///< The options
}; };
/// Common interface to emptiness check algorithms. /// Common interface to emptiness check algorithms.
class emptiness_check class emptiness_check
{ {
public: public:
emptiness_check(const tgba* a) emptiness_check(const tgba* a, option_map o = option_map())
: a_(a) : a_(a), o_(o)
{ {
} }
virtual ~emptiness_check(); virtual ~emptiness_check();
@ -124,6 +155,23 @@ namespace spot
return a_; 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. /// \brief Check whether the automaton contain an accepting run.
/// ///
/// Return 0 if the automaton accept no run. Return an instance /// Return 0 if the automaton accept no run. Return an instance
@ -142,8 +190,15 @@ namespace spot
/// Print statistics, if any. /// Print statistics, if any.
virtual std::ostream& print_stats(std::ostream& os) const; 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: protected:
const tgba* a_; ///< The automaton. const tgba* a_; ///< The automaton.
option_map o_; ///< The options
}; };
/// @} /// @}

View file

@ -53,8 +53,8 @@ namespace spot
/// ///
/// \pre The automaton \a a must have at most one accepting /// \pre The automaton \a a must have at most one accepting
/// condition (i.e. it is a TBA). /// condition (i.e. it is a TBA).
magic_search(const tgba *a, size_t size) magic_search(const tgba *a, size_t size, option_map o = option_map())
: emptiness_check(a), : emptiness_check(a, o),
h(size), h(size),
all_cond(a->all_acceptance_conditions()) all_cond(a->all_acceptance_conditions())
{ {
@ -96,17 +96,17 @@ namespace spot
h.add_new_state(s0, BLUE); h.add_new_state(s0, BLUE);
push(st_blue, s0, bddfalse, bddfalse); push(st_blue, s0, bddfalse, bddfalse);
if (dfs_blue()) if (dfs_blue())
return new ndfs_result<magic_search<heap>, heap>(*this); return new magic_search_result(*this, options());
} }
else else
{ {
h.pop_notify(st_red.front().s); h.pop_notify(st_red.front().s);
pop(st_red); pop(st_red);
if (!st_red.empty() && dfs_red()) if (!st_red.empty() && dfs_red())
return new ndfs_result<magic_search<heap>, heap>(*this); return new magic_search_result(*this, options());
else else
if (dfs_blue()) if (dfs_blue())
return new ndfs_result<magic_search<heap>, heap>(*this); return new magic_search_result(*this, options());
} }
return 0; return 0;
} }
@ -314,6 +314,108 @@ namespace spot
return false; 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 class explicit_magic_search_heap
@ -471,15 +573,15 @@ namespace spot
} // anonymous } // 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( emptiness_check* bit_state_hashing_magic_search(const tgba *a, size_t size,
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);
} }
} }

View file

@ -23,6 +23,7 @@
# define SPOT_TGBAALGOS_MAGIC_HH # define SPOT_TGBAALGOS_MAGIC_HH
#include <cstddef> #include <cstddef>
#include "misc/optionmap.hh"
namespace spot namespace spot
{ {
@ -93,7 +94,8 @@ namespace spot
/// } /// }
/// \endverbatim /// \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. /// \brief Returns an emptiness checker on the spot::tgba automaton \a a.
/// ///
@ -113,13 +115,17 @@ namespace spot
/// } /// }
/// \endverbatim /// \endverbatim
/// ///
/// Consequently, the detection of an acceptence cycle is not ensured. The /// Consequently, the detection of an acceptence cycle is not ensured.
/// implemented algorithm is the same as the one of ///
/// 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. /// spot::explicit_magic_search.
/// ///
/// \sa 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());
/// @} /// @}
} }

View file

@ -37,8 +37,6 @@
#include "se05.hh" #include "se05.hh"
#include "ndfs_result.hxx" #include "ndfs_result.hxx"
/// FIXME: make compiling depedent the taking into account of weights.
namespace spot namespace spot
{ {
namespace namespace
@ -55,9 +53,8 @@ namespace spot
/// ///
/// \pre The automaton \a a must have at most one accepting /// \pre The automaton \a a must have at most one accepting
/// condition (i.e. it is a TBA). /// condition (i.e. it is a TBA).
se05_search(const tgba *a, size_t size) se05_search(const tgba *a, size_t size, option_map o = option_map())
: emptiness_check(a), : emptiness_check(a, o),
ec_statistics(),
h(size), h(size),
all_cond(a->all_acceptance_conditions()) all_cond(a->all_acceptance_conditions())
{ {
@ -99,17 +96,17 @@ namespace spot
h.add_new_state(s0, CYAN); h.add_new_state(s0, CYAN);
push(st_blue, s0, bddfalse, bddfalse); push(st_blue, s0, bddfalse, bddfalse);
if (dfs_blue()) if (dfs_blue())
return new ndfs_result<se05_search<heap>, heap>(*this); return new se05_result(*this, options());
} }
else else
{ {
h.pop_notify(st_red.front().s); h.pop_notify(st_red.front().s);
pop(st_red); pop(st_red);
if (!st_red.empty() && dfs_red()) if (!st_red.empty() && dfs_red())
return new ndfs_result<se05_search<heap>, heap>(*this); return new se05_result(*this, options());
else else
if (dfs_blue()) if (dfs_blue())
return new ndfs_result<se05_search<heap>, heap>(*this); return new se05_result(*this, options());
} }
return 0; return 0;
} }
@ -322,6 +319,114 @@ namespace spot
return false; 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 class explicit_se05_search_heap
@ -559,14 +664,15 @@ namespace spot
} // anonymous } // 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);
} }
} }

View file

@ -23,6 +23,7 @@
# define SPOT_TGBAALGOS_SE05_HH # define SPOT_TGBAALGOS_SE05_HH
#include <cstddef> #include <cstddef>
#include "misc/optionmap.hh"
namespace spot namespace spot
{ {
@ -100,8 +101,8 @@ namespace spot
/// ///
/// \sa spot::explicit_magic_search /// \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. /// \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. /// \pre The automaton \a a must have at most one accepting condition (i.e.
@ -120,13 +121,17 @@ namespace spot
/// } /// }
/// \endverbatim /// \endverbatim
/// ///
/// Consequently, the detection of an acceptence cycle is not ensured. The /// Consequently, the detection of an acceptence cycle is not ensured.
/// implemented algorithm is the same as the one of ///
/// 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. /// spot::explicit_se05_search.
/// ///
/// \sa 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());
/// @} /// @}
} }

View file

@ -44,6 +44,7 @@
#include "tgbaalgos/dotty.hh" #include "tgbaalgos/dotty.hh"
#include "tgbaparse/public.hh" #include "tgbaparse/public.hh"
#include "misc/random.hh" #include "misc/random.hh"
#include "misc/optionmap.hh"
#include "tgba/tgbatba.hh" #include "tgba/tgbatba.hh"
#include "tgba/tgbaproduct.hh" #include "tgba/tgbaproduct.hh"
#include "misc/timer.hh" #include "misc/timer.hh"
@ -61,6 +62,7 @@
#include "tgbaalgos/tau03opt.hh" #include "tgbaalgos/tau03opt.hh"
#include "tgbaalgos/replayrun.hh" #include "tgbaalgos/replayrun.hh"
spot::option_map options;
spot::emptiness_check* spot::emptiness_check*
couvreur99_cons(const spot::tgba* a) 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); 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* spot::emptiness_check*
bsh_ms_cons(const spot::tgba* a) 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* spot::emptiness_check*
bsh_se05_cons(const spot::tgba* a) 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 struct ec_algo
@ -127,10 +141,10 @@ ec_algo ec_algos[] =
{ "Cou99_rem", couvreur99_rem_cons, 0, -1U, true }, { "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_minus_cons, 0, -1U, true },
{ "Cou99_rem_shy", couvreur99_rem_shy_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 }, { "CVWY90_bsh", bsh_ms_cons, 0, 1, false },
{ "GV04", spot::explicit_gv04_check, 0, 1, true }, { "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 }, { "SE05_bsh", bsh_se05_cons, 0, 1, false },
{ "Tau03", spot::explicit_tau03_search, 1, -1U, true }, { "Tau03", spot::explicit_tau03_search, 1, -1U, true },
{ "Tau03_opt", spot::explicit_tau03_opt_search, 0, -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 << " -O ALGO run Only ALGO" << std::endl
<< " -R N repeat each emptiness-check and accepting run " << " -R N repeat each emptiness-check and accepting run "
<< "computation N times" << std::endl << "computation N times" << std::endl
<< " -r compute and replay acceptance runs (implies -e)" << " -r compute and replay accepting runs (implies -e)"
<< std::endl << std::endl
<< " ar:MODE select the mode MODE for accepting runs computation "
<< "(implies -r)" << std::endl
<< std::endl << std::endl
<< "Where:" << std::endl << "Where:" << std::endl
<< " F are floats between 0.0 and 1.0 inclusive" << 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_n_acc = to_int_nonneg(argv[++argn], "-a");
opt_a = to_float_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")) else if (!strcmp(argv[argn], "-d"))
{ {
if (argc < argn + 2) if (argc < argn + 2)