fix status of lbtt's subtree. Apparently it was messed up during the cvsimport

This commit is contained in:
Alexandre Duret-Lutz 2008-02-23 00:17:42 +01:00
parent 17f76e371f
commit 91df6cab77
77 changed files with 16272 additions and 6019 deletions

View file

@ -1 +1 @@
lbtt was written by Heikki Tauriainen <heikki.tauriainen@hut.fi>
Heikki Tauriainen <heikki.tauriainen@tkk.fi>

View file

@ -16,13 +16,13 @@
Update description of the --formulafile command line option.
(Configuration::print): Do not display a file name when reading
formulas from standard input.
* src/SpotWrapper.h, src/SpotWrapper.cc: Merge files from
Spot 0.2 (contributed by Alexandre Duret-Lutz); remove #pragma
definitions.
* src/ExternalTranslator.h, src/Makefile.in, src/translate.cc:
Merge changes from Spot 0.2 (contributed by Alexandre Duret-Lutz).
* doc/lbtt.texi: Fix typo in URL of the FormulaOptions block
generator. Update version, add documentation and references about
support for Spot. Describe the new semantics of the --formulafile
@ -124,7 +124,7 @@
log file.
* configure.ac: Add test for the setsid library function.
2004-07-31 Heikki Tauriainen <heikki.tauriainen@hut.fi>
* src/Product.h (ProductEdge::edge_1, ProductEdge::edge_2):
@ -178,7 +178,7 @@
* doc/texinfo.tex: New upstream version.
* doc/lbtt.texi: Update to edition 1.1.0.
* NEWS: Update.
2004-07-02 Heikki Tauriainen <heikki.tauriainen@hut.fi>
* src/UserCommandReader.cc (parseCommand): Recognize
@ -257,13 +257,13 @@
New files for providing specializations of the general product
computation operation applicable to Büchi automata and state
spaces.
* src/Makefile.am: Add BuchiProduct.h, BuchiProduct.cc,
Product.h, SccCollection.h and StateSpaceProduct.h to
lbtt_SOURCES.
Remove ProductAutomaton.h, ProductAutomaton.cc and
SccIterator.h from lbtt_SOURCES.
* src/Graph.h.in (Graph::EdgeContainerType, Graph::Path): New
type definitions.
(Graph::PathElement): New class.
@ -337,7 +337,7 @@
(printAcceptingCycle): Update parameter list and documentation.
Display all relevant information about an accepting execution
of a Büchi automaton.
2004-05-18 Heikki Tauriainen <heikki.tauriainen@hut.fi>
* configure.ac (YACC): Do not add `-d' here.
@ -365,7 +365,7 @@
* src/NeverClaim-lex.ll: Add %option nounput to avoid a
compiler warning.
* src/ExternalTranslator.h: Include the TempFsysName.h header.
(ExternalTranslator::TempFileObject): Remove.
(ExternalTranslator::registerTempFileObject): Change
@ -475,7 +475,7 @@
command line option.
(printCommandHelp): Update the description of the `formula'
command.
* src/UserCommandReader.cc (executeUserCommands): Accept one
optional parameter for the `formula' command. Pass the input
tokens as an additional parameter in the printFormula call.
@ -505,7 +505,7 @@
* src/TempFsysName.h, src/TempFsysName.cc New files.
* src/Makefile.am: Add TempFsysName.h and TempFsysName.cc to
lbtt_SOURCES.
* src/TestRoundInfo.h: Include the TempFsysName.h header.
(TestRoundInfo::formula_file_name[])
(TestRoundInfo::automaton_file_name)
@ -513,7 +513,7 @@
TempFsysName*.
(TestRoundInfo::TestRoundInfo): Initialize temporary file
name pointers to 0.
* src/main.cc: Include the TempFsysName.h header.
(allocateTempFilenames, deallocateTempFilenames): New functions.
(abortHandler): New signal handler.
@ -858,7 +858,7 @@
after colon in output. Return 3 if an unexpected exception
occurred. In this case print an additional newline before the
error message.
2004-02-19 Heikki Tauriainen <heikki.tauriainen@hut.fi>
* src/StringUtil.h: Include the IntervalList.h header.
@ -926,7 +926,7 @@
Reformat the automata file format section to avoid overfull lines
in dvi generation.
Fix description of the Algorithm block used with lbtt-translate.
* doc/testprocedure.txt, doc/intersectioncheck.txt: Add initial
newlines.

180
lbtt/NEWS
View file

@ -1,5 +1,5 @@
lbtt NEWS -- history of user-visible changes. 01 Oct 2002
Copyright (C) 2002 Heikki Tauriainen
lbtt NEWS -- history of user-visible changes. 30 Aug 2005
Copyright (C) 2005 Heikki Tauriainen
Permission is granted to anyone to make or distribute verbatim copies
of this document as received, in any medium, provided that the
@ -10,7 +10,181 @@ Copyright (C) 2002 Heikki Tauriainen
provided also that they carry prominent notices stating who last
changed them.
Please send bug reports to <heikki.tauriainen@hut.fi>.
Please send bug reports to <heikki.tauriainen@tkk.fi>.
Version 1.2.0
* This release adds direct support (contributed by Alexandre Duret-Lutz)
for the LTL-to-Büchi translator distributed with the Spot model
checking library (available at <http://spot.lip6.fr/>).
lbtt 1.2.0 also supports reading input formulas from standard input
(by using the command-line option `--formulafile=-'; when reading input
formulas from an actual file, the filename needs to be different from
"-").
Version 1.1.3
* This release fixes build problems with GCC 4 and more job control
problems.
Version 1.1.2
* Another bug fix release that fixes memory access and job control
problems.
Version 1.1.1
* This release includes fixes to build problems with non-GNU
compilers on GNU libc systems and a few minor bug fixes.
Version 1.1.0
* File formats
- The file format for automata description files has changed to
accommodate automata with acceptance conditions on both states
and transitions. The old format for automata remains supported
with the restriction that each guard formula of a transition
should be followed by a newline (with optional preceding white
space).
- In addition to the prefix format for LTL formulas, the input
files used with the `--formulafile' command line option may now
contain formulas in a variety of other formats, such as in the
infix format used by lbtt for log messages, together with formats
used by some LTL-to-Büchi translator implementations (Spin,
LTL2BA, LTL2AUT, Temporal Massage Parlor, Wring, Spot, LBT).
These formats can also be used for guard formulas in automaton
description files (however, lbtt still uses the prefix format in
the input files for the translators).
Thanks to Alexandre Duret-Lutz for useful suggestions for
enhancements.
* Support for symbolic names of implementations
- Beside the numeric identifiers of implementations, lbtt now
accepts also the symbolic names of implementations (as defined in
a configuration file) as parameters for command line options and
internal commands. Consequently, the names of implementations
defined in the configuration file have to be unique.
- The name `lbtt' is now reserved for lbtt's internal model checking
algorithm and cannot be used as a name for an implementation in
the configuration file.
* User commands
- For consistency, numeric intervals in state or implementation
identifier lists can now be specified using either - or ... as a
separator between the bounds of the interval.
- The user command `formula' now accepts an additional parameter
(`normal' or `nnf') for choosing whether to display a formula in
the form in which it was generated or in negation normal form.
- The internal model checking algorithm is now referred to with the
keyword "lbtt" instead of "p" as was the case with previous
versions of lbtt. The internal model checking algorithm can now be
enabled or disabled similarly to the external translators.
- The `consistencyanalysis' and `buchianalysis' commands now show
more information about the accepting runs of Büchi automata to
help examining the runs. (Because of this change, the runs and
witnesses may be longer than in previous versions of lbtt.)
- The `implementations' and `translators' commands are now recognized
as synonyms of the `algorithms' command.
* Configuration files
- Quotes are no longer required for enclosing string values
containing no white space.
- Numeric intervals in formula or state space sizes can now be
specified using either - or ... as a separator between the bounds
of the interval.
- The keywords "Implementation" and "Translator" are now recognized
as synonyms of the "Algorithm" block identifier.
* User interrupts
Keyboard interrupt handling is now enabled only at explicit request
(if not enabled, lbtt simply aborts on keyboard interrupts). The
interrupt handler is enabled by combining the keyword `onbreak' with
any of the three standard interactivity modes (`always', `never', or
`onerror') in the arguments for the `GlobalOptions.Interactive'
configuration file option or the `--interactive' command line option.
For example, use the command line option
`--interactive=onerror,onbreak' to pause testing in case of an error
or on a user interrupt.
* Command line options
- The `--pause' command line option now works identically to the
`--interactive' option.
- The command-line options `--nopause' and `--pauseonerror' are no
longer supported. Use the `--interactive' or the `--pause'
option instead with an optional argument of a comma-separated list
of interactivity modes (`always', `never', `onerror', `onbreak').
* Timeouts
lbtt now supports specifying a time (in wall-clock time) after
which the execution of a translator is aborted if it has not yet
produced a result. The timeout can be set using either the new
configuration file option `GlobalOptions.TranslatorTimeout' or the
equivalent command line option `--translatortimeout'. Both options
require a parameter of the form [hours]h[minutes]min[seconds]s; for
example, use the command line option `--translatortimeout=1h30min'
to set the timeout at one hour and thirty minutes.
* Reporting
- lbtt now reports test statistics also in verbosity modes 1 and 2.
The output of the user command `results' also reflects the active
verbosity mode more accurately.
- lbtt now exits with status 0 only if no test failures were
detected; otherwise the exit status is either 1 (at least
one failure occurred), 2 (error in program configuration or
command line parameters) or 3 (lbtt exited due to an internal
error).
* Internal changes
Due to the changes in the supported file formats, this version
includes a rewrite of the product computation and emptiness checking
algorithms. As this is a major internal change, any information about
unexpected changes in the stability (*) of the tool is welcomed at the
e-mail address given above.
(*) Unfortunately, the above changes in the source code are known to
cause build problems with GCC 2.95. Therefore, this compiler is no
longer officially supported for building the tool.
---------------------------------------------------------------------------
Version 1.0.3
* This release fixes several compilation issues with GNU libc 2.3.2
and Darwin, and documentation generation in dvi format. A problem
with reading user commands from a source that is not a terminal was
also fixed. Many thanks to Alexandre Duret-Lutz for patches and
useful suggestions.
Version 1.0.2
* Bug fix release.
* The official WWW home page of the tool is now located at
<http://www.tcs.hut.fi/Software/lbtt/>. From there you can also
access the FormulaOptions block generator for lbtt configuration
files. The generator has limited support for specifying relative
(instead of absolute) priorities for the LTL operators.
Version 1.0.1

View file

@ -1,24 +1,24 @@
lbtt version 1.0.1
lbtt version 1.2.0
------------------
lbtt is a tool for testing programs which translate formulas
lbtt is a tool for testing programs that translate formulas
expressed in propositional linear temporal logic (LTL) into
Büchi automata. The goal of the tool is to assist in the
correct implementation of LTL-to-Büchi translation algorithms
by providing an automated testing environment for LTL-to-Büchi
translators. Additionally, the testing environment can be used
for very basic profiling of different LTL-to-Büchi translators
to evaluate their performance.
Büchi automata. The goal of the tool is to assist implementing
LTL-to-Büchi translation algorithms correctly by providing an
automated testing environment for LTL-to-Büchi translators.
Additionally, the testing environment can be used for very basic
profiling of different LTL-to-Büchi translators to evaluate their
performance.
The latest version of the program is available at
<http://www.tcs.hut.fi/%7Ehtauriai/lbtt/>.
<http://www.tcs.hut.fi/Software/lbtt/>.
lbtt is free software, you may change and redistribute it under
the terms of the GNU General Public License. lbtt comes with
NO WARRANTY. See the file COPYING for details.
Quick installation instructions:
Brief installation instructions:
--------------------------------
The basic procedure to build lbtt, the associated tools
@ -82,4 +82,4 @@ Documentation:
The documentation is also available in various formats
at the program's home page at
<http://www.tcs.hut.fi/%7Ehtauriai/lbtt/>.
<http://www.tcs.hut.fi/Software/lbtt/>.

View file

@ -1,8 +1,8 @@
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.59])
AC_INIT([lbtt], [1.1.1], [heikki.tauriainen@hut.fi])
AC_REVISION([Revision: 1.5])
AC_INIT([lbtt], [1.2.0], [heikki.tauriainen@tkk.fi])
AC_REVISION([Revision: 1.8])
AC_CONFIG_SRCDIR([src/main.cc])
AC_CONFIG_HEADERS([config.h])
AM_INIT_AUTOMAKE
@ -124,52 +124,6 @@ AC_CHECK_HEADERS(
# Checks for typedefs, structures, and compiler characteristics.
# Check for the availability of the slist header (an extension to the C++
# Standard Template Library). (In GCC 3.x the header is in the ext/
# subdirectory of the directory containing the standard C++ headers.)
AC_MSG_CHECKING([for slist])
for slist_header in slist ext/slist no; do
if test "${slist_header}" != no; then
AC_PREPROC_IFELSE(
[AC_LANG_SOURCE([[#include <${slist_header}>]])],
[break])
fi
done
# Try to determine the C++ namespace in which the class slist resides.
# (For example, GCC versions >= 3.1 put slist into the __gnu_cxx namespace.)
if test "${slist_header}" != no; then
for slist_namespace in std __gnu_cxx error; do
if test "${slist_namespace}" != error; then
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[[#include <${slist_header}>]],
[[${slist_namespace}::slist<int> s;]])],
[break])
fi
done
if test "${slist_namespace}" != error; then
AC_MSG_RESULT([header <${slist_header}>, typename ${slist_namespace}::slist])
AC_DEFINE(
[HAVE_SLIST],
[1],
[Define to 1 if you have the <slist> or <ext/slist> header file.])
AC_DEFINE_UNQUOTED(
[SLIST_NAMESPACE],
[${slist_namespace}],
[Define as the name of the C++ namespace containing slist.])
AC_SUBST([INCLUDE_SLIST_HEADER], ["#include <${slist_header}>"])
else
slist_header=no
fi
fi
if test "${slist_header}" = no; then
AC_MSG_RESULT([no])
fi
AC_LANG(C)
AC_CHECK_TYPES(
@ -191,7 +145,7 @@ AC_C_INLINE
# Checks for library functions.
AC_CHECK_FUNCS(
[strchr strtod strtol strtoul strerror mkdir mkstemp open read write close popen pclose pipe fork execvp getpid waitpid alarm sigaction sigprocmask sigemptyset sigaddset times sysconf],
[strchr strtod strtol strtoul strerror mkdir mkstemp open read write close popen pclose pipe fork execvp getpgrp setpgid tcgetpgrp tcsetpgrp getpid waitpid alarm sigaction sigprocmask sigemptyset sigaddset times sysconf],
[],
[AC_MSG_ERROR([missing one of the library functions required for compilation])])
AC_CHECK_FUNCS([strsignal isatty getopt_long])

View file

@ -1,3 +1,4 @@
,,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,,,,,,,,,,,,
: LTL formula `f' :_____ : Negated LTL formula `!f' :
'''''''T''''''T'''' \ ___'''''''T'''''''''''T''''''''

File diff suppressed because it is too large Load diff

View file

@ -1,3 +1,4 @@
,,,,,,,,,,,,,,,
: State space :
'''''''''''''''

7482
lbtt/doc/texinfo.tex Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -17,10 +17,6 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifdef __GNUC__
#pragma implementation
#endif /* __GNUC__ */
#include <config.h>
#ifdef HAVE_SSTREAM
#include <sstream>
@ -378,7 +374,7 @@ unsigned long int BitArray::find(const unsigned long int max_count) const
for (i = 0; i < bsize && bits[i] == 0; ++i)
;
if (i == max_count)
if (i == bsize)
return max_count;
unsigned char c = bits[i];

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -20,10 +20,6 @@
#ifndef BITARRAY_H
#define BITARRAY_H
#ifdef __GNUC__
#pragma interface
#endif /* __GNUC__ */
#include <config.h>
#include <cstring>
#include <string>
@ -363,7 +359,10 @@ inline void BitArray::set(const unsigned long int bit_count)
*
* ------------------------------------------------------------------------- */
{
memset(static_cast<void*>(bits), 0xFF, (bit_count + 7) >> 3);
unsigned long int bsize = bit_count >> 3;
memset(static_cast<void*>(bits), 0xFF, bsize);
if ((bit_count & 0x07) != 0)
bits[bsize] |= (1 << (bit_count & 7)) - 1;
}
/* ========================================================================= */
@ -394,7 +393,10 @@ inline void BitArray::clear(const unsigned long int bit_count)
*
* ------------------------------------------------------------------------- */
{
memset(static_cast<void*>(bits), 0, (bit_count + 7) >> 3);
unsigned long int bsize = bit_count >> 3;
memset(static_cast<void*>(bits), 0, bsize);
if ((bit_count & 0x07) != 0)
bits[bsize] &= ~((1 << (bit_count & 7)) - 1);
}
/* ========================================================================= */

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -17,10 +17,6 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifdef __GNUC__
#pragma implementation
#endif /* __GNUC__ */
#include <config.h>
#include <deque>
#include <stack>
@ -96,7 +92,9 @@ BuchiAutomaton::BuchiAutomaton(const BuchiAutomaton& automaton) :
++transition)
connect(state,
static_cast<const BuchiTransition*>(*transition)->targetNode(),
static_cast<const BuchiTransition*>(*transition)->guard());
static_cast<const BuchiTransition*>(*transition)->guard(),
static_cast<const BuchiTransition*>(*transition)
->acceptanceSets());
operator[](state).acceptanceSets().copy(automaton[state].acceptanceSets(),
number_of_acceptance_sets);
@ -133,7 +131,9 @@ BuchiAutomaton& BuchiAutomaton::operator=(const BuchiAutomaton& automaton)
++transition)
connect(state,
static_cast<const BuchiTransition*>(*transition)->targetNode(),
static_cast<const BuchiTransition*>(*transition)->guard());
static_cast<const BuchiTransition*>(*transition)->guard(),
static_cast<const BuchiTransition*>(*transition)
->acceptanceSets());
operator[](state).acceptanceSets().copy
(automaton[state].acceptanceSets(), number_of_acceptance_sets);
@ -194,113 +194,13 @@ BuchiAutomaton::size_type BuchiAutomaton::expand(size_type node_count)
return nodes.size() - 1;
}
/* ========================================================================= */
BuchiAutomaton* BuchiAutomaton::regularize() const
/* ----------------------------------------------------------------------------
*
* Description: Converts a generalized Büchi automaton (i.e., an automaton
* with any number of accepting state sets) into an automaton
* with only one set of accepting states.
*
* Arguments: None.
*
* Returns: A pointer to an equivalent BuchiAutomaton with exactly one
* set of accepting states.
*
* ------------------------------------------------------------------------- */
{
/*
* If `this' automaton already has exactly one set of accepting states,
* return a copy of `this' automaton.
*/
if (number_of_acceptance_sets == 1)
return new BuchiAutomaton(*this);
/*
* Otherwise construct the result using a depth-first search in `this'
* automaton.
*/
typedef pair<size_type, unsigned long int> ExpandedState;
BuchiAutomaton* result_automaton = new BuchiAutomaton(0, 0, 1);
if (empty())
return result_automaton;
stack<ExpandedState, deque<ExpandedState, ALLOC(ExpandedState) > >
states_to_process;
map<ExpandedState, size_type, less<ExpandedState>, ALLOC(size_type) >
state_mapping;
const GraphEdgeContainer* transitions;
size_type result_source_state, result_target_state;
map<ExpandedState, size_type, less<ExpandedState>, ALLOC(size_type) >
::const_iterator check_state;
ExpandedState state = make_pair(initial_state, 0);
states_to_process.push(state);
state_mapping[state] = result_automaton->expand();
while (!states_to_process.empty())
{
state = states_to_process.top();
states_to_process.pop();
result_source_state = state_mapping[state];
transitions = &operator[](state.first).edges();
if (number_of_acceptance_sets == 0
|| operator[](state.first).acceptanceSets().test(state.second))
{
if (state.second == 0)
(*result_automaton)[result_source_state].acceptanceSets().setBit(0);
if (number_of_acceptance_sets > 0)
{
++state.second;
state.second %= number_of_acceptance_sets;
}
}
for (GraphEdgeContainer::const_iterator transition = transitions->begin();
transition != transitions->end();
++transition)
{
state.first = (*transition)->targetNode();
check_state = state_mapping.find(state);
if (check_state == state_mapping.end())
{
result_target_state = result_automaton->expand();
state_mapping[state] = result_target_state;
states_to_process.push(state);
}
else
result_target_state = check_state->second;
result_automaton->connect(result_source_state, result_target_state,
static_cast<const BuchiTransition*>
(*transition)->guard());
}
}
return result_automaton;
}
/* ========================================================================= */
void BuchiAutomaton::read(istream& input_stream)
/* ----------------------------------------------------------------------------
*
* Description: Reads an automaton description (which may represent a
* generalized Büchi automaton) from a stream and stores it
* into the automaton object, converting it to a regular
* Büchi automaton if necessary.
* into the automaton object.
*
* Argument: input_stream -- A reference to an input stream.
*
@ -316,20 +216,63 @@ void BuchiAutomaton::read(istream& input_stream)
try
{
/*
* Read in the number of states in the generalized Büchi automaton.
*/
/* Read the number of states in the generalized Büchi automaton. */
einput_stream >> number_of_states;
/*
* If the automaton is empty, do nothing.
*/
/* If the automaton is empty, do nothing. */
if (number_of_states == 0)
return;
einput_stream >> number_of_acceptance_sets;
/*
* Determine the number and placement of acceptance sets.
* (Acceptance sets are described using strings described by the regular
* expression [0-9]+(s|S|t|T)*, where the [0-9]+ part corresponds to the
* number of the sets, and the (s|S|t|T)* part corresponds to the
* placement of the sets -- s or S for states, t or T for transitions.
* To retain compatibility with lbtt 1.0.x, the acceptance set placement
* defaults to acceptance sets on states if is not given explicitly.)
*/
bool acceptance_sets_on_states = false;
bool acceptance_sets_on_transitions = false;
string tok;
einput_stream >> tok;
string::size_type s_pos = string::npos;
string::size_type t_pos = string::npos;
string::size_type pos = tok.find_first_not_of("0123456789");
if (pos == 0)
throw AutomatonParseException
("invalid specification for acceptance sets");
number_of_acceptance_sets = strtoul(tok.substr(0, pos).c_str(), 0, 10);
for ( ; pos < tok.length(); ++pos)
{
if (tok[pos] == 's' || tok[pos] == 'S')
{
s_pos = pos;
acceptance_sets_on_states = true;
}
else if (tok[pos] == 't' || tok[pos] == 'T')
{
t_pos = pos;
acceptance_sets_on_transitions = true;
}
else
throw AutomatonParseException
("invalid specification for acceptance sets");
}
if (s_pos == string::npos && t_pos == string::npos)
{
acceptance_sets_on_states = true;
acceptance_sets_on_transitions = false;
}
BitArray acc_sets(number_of_acceptance_sets);
/*
* Allocate space for the regular Büchi automaton that will be constructed
@ -345,27 +288,20 @@ void BuchiAutomaton::read(istream& input_stream)
* to the interval [0...(number of states - 1)].
*/
map<long int, size_type, less<long int>, ALLOC(size_type) >
state_number_map;
map<long int, size_type> state_number_map;
pair<long int, size_type> state_mapping(0, 0);
pair<map<long int, size_type, less<long int>, ALLOC(size_type) >
::const_iterator,
bool>
state_finder;
pair<map<long int, size_type>::const_iterator, bool> state_finder;
/*
* Also the acceptance set numbers will be mapped to the interval
* [0...(number of acceptance sets - 1)].
*/
map<long int, unsigned long int, less<long int>, ALLOC(unsigned long int) >
acceptance_set_map;
map<long int, unsigned long int> acceptance_set_map;
pair<long int, unsigned long int> acceptance_set_mapping(0, 0);
pair<map<long int, unsigned long int, less<long int>,
ALLOC(unsigned long int) >::const_iterator,
bool>
pair<map<long int, unsigned long int>::const_iterator, bool>
acceptance_set_finder;
/*
@ -450,36 +386,41 @@ void BuchiAutomaton::read(istream& input_stream)
operator[](current_state).acceptanceSets().clear
(number_of_acceptance_sets);
while (1)
if (acceptance_sets_on_states)
{
einput_stream >> acceptance_set_mapping.first;
if (acceptance_set_mapping.first == -1)
break;
acceptance_set_finder =
acceptance_set_map.insert(acceptance_set_mapping);
if (!acceptance_set_finder.second)
acceptance_set = (acceptance_set_finder.first)->second;
else
while (1)
{
if (acceptance_set_mapping.second >= number_of_acceptance_sets)
throw AutomatonParseException("number of acceptance sets "
"does not match automaton state "
"definitions");
einput_stream >> acceptance_set_mapping.first;
acceptance_set = acceptance_set_mapping.second;
++acceptance_set_mapping.second;
}
if (acceptance_set_mapping.first == -1)
break;
operator[](current_state).acceptanceSets().setBit(acceptance_set);
acceptance_set_finder =
acceptance_set_map.insert(acceptance_set_mapping);
if (!acceptance_set_finder.second)
acceptance_set = (acceptance_set_finder.first)->second;
else
{
if (acceptance_set_mapping.second >= number_of_acceptance_sets)
throw AutomatonParseException("number of acceptance sets "
"does not match automaton state "
"definitions");
acceptance_set = acceptance_set_mapping.second;
++acceptance_set_mapping.second;
}
operator[](current_state).acceptanceSets().setBit(acceptance_set);
}
}
/*
* Process the transitions from the state to other states. Read a
* target state id and add a mapping for it in the translation table if
* necessary. Then, read the propositional formula guarding the
* necessary. If the automaton is allowed to have acceptance sets
* associated with transitions, read an additional list of acceptance
* sets. Finally, read the propositional formula guarding the
* transition and connect the current state to the target using the
* guard formula.
*/
@ -505,6 +446,42 @@ void BuchiAutomaton::read(istream& input_stream)
state_mapping.second++;
}
acc_sets.clear(number_of_acceptance_sets);
/*
* If automata with acceptance sets on transitions are accepted, read
* the acceptance sets associated with the transition.
*/
if (acceptance_sets_on_transitions)
{
while (1)
{
einput_stream >> acceptance_set_mapping.first;
if (acceptance_set_mapping.first == -1)
break;
acceptance_set_finder =
acceptance_set_map.insert(acceptance_set_mapping);
if (!acceptance_set_finder.second)
acceptance_set = (acceptance_set_finder.first)->second;
else
{
if (acceptance_set_mapping.second >= number_of_acceptance_sets)
throw AutomatonParseException("number of acceptance sets "
"does not match automaton state "
"definitions");
acceptance_set = acceptance_set_mapping.second;
++acceptance_set_mapping.second;
}
acc_sets.setBit(acceptance_set);
}
}
try
{
guard = ::Ltl::LtlFormula::read(input_stream);
@ -520,7 +497,7 @@ void BuchiAutomaton::read(istream& input_stream)
throw AutomatonParseException("illegal operators in guard formula");
}
connect(current_state, neighbor_state, guard);
connect(current_state, neighbor_state, guard, acc_sets);
}
processed_states.setBit(current_state);
@ -548,297 +525,6 @@ void BuchiAutomaton::read(istream& input_stream)
}
}
/* ========================================================================= */
BuchiAutomaton* BuchiAutomaton::intersect
(const BuchiAutomaton& a1, const BuchiAutomaton& a2,
map<size_type, StateIdPair, less<size_type>, ALLOC(StateIdPair) >*
intersection_state_mapping)
/* ----------------------------------------------------------------------------
*
* Description: Computes the intersection of two Büchi automata and returns
* a pointer to the intersection of the two automata.
*
* Arguments: a1, a2 -- References to two constant
* Büchi automata.
* intersection_state_mapping -- An (optional) pointer to a
* map which can be used to find
* out the state identifiers of
* the original automata to
* which a particular state in
* the intersection corresponds.
*
* Returns: A newly allocated BuchiAutomaton representing the
* intersection of the two automata.
*
* ------------------------------------------------------------------------- */
{
if (intersection_state_mapping != 0)
intersection_state_mapping->clear();
/*
* If either of the original automata is empty, the intersection is also
* empty.
*/
if (a1.empty() || a2.empty())
return new BuchiAutomaton(0, 0, 0);
BuchiAutomaton* automaton;
/*
* Determine the number of acceptance sets in the intersection.
*/
const bool a1_has_no_acceptance_sets = (a1.number_of_acceptance_sets == 0);
const bool a2_has_no_acceptance_sets = (a2.number_of_acceptance_sets == 0);
unsigned long int number_of_intersection_acceptance_sets;
if (a1_has_no_acceptance_sets && a2_has_no_acceptance_sets)
number_of_intersection_acceptance_sets = 0;
else
number_of_intersection_acceptance_sets = a1.number_of_acceptance_sets
+ a2.number_of_acceptance_sets;
automaton = new BuchiAutomaton(1, 0, number_of_intersection_acceptance_sets);
/*
* A stack for processing pairs of states of the original automata.
*/
stack<const StateIdPair*, deque<const StateIdPair*,
ALLOC(const StateIdPair*) > >
unprocessed_states;
/*
* `state_mapping' maps pairs of states of the original automata to the
* states of the new automaton.
*/
map<StateIdPair, size_type, less<StateIdPair>, ALLOC(size_type) >
state_mapping;
size_type first_free_id = 1; /* First free identifier for a
* new state in the intersection
* automaton.
*/
const StateIdPair* state_pair; /* Pointer to pair of two state
* identifiers of the original
* automata.
*/
size_type intersect_state; /* `Current' state in the
* intersection automaton.
*/
bool intersect_state_valid; /* True if the current state has
* been determined by using the
* mapping.
*/
BitArray* intersect_acceptance_sets; /* Pointers for accessing the */
const BitArray* acceptance_sets; /* acceptance sets of the new
* and the original automata.
*/
const GraphEdgeContainer* transitions1; /* Pointers for accessing the */
const GraphEdgeContainer* transitions2; /* transitions of the two
* original automata.
*/
::Ltl::LtlFormula* guard1; /* Pointers for accessing the */
::Ltl::LtlFormula* guard2; /* guard formulas of the */
::Ltl::LtlFormula* new_guard; /* transitions of the
* automata.
*/
/*
* Insert the initial state into the state mapping.
*/
state_mapping.insert(make_pair(make_pair(a1.initial_state, a2.initial_state),
0));
unprocessed_states.push(&(state_mapping.begin()->first));
/*
* Adjust the acceptance sets of the initial state of the intersection.
*/
intersect_acceptance_sets = &((*automaton)[0].acceptanceSets());
if (!a1_has_no_acceptance_sets)
{
acceptance_sets = &(a1[a1.initial_state].acceptanceSets());
for (unsigned long int accept_set = 0;
accept_set < a1.number_of_acceptance_sets;
accept_set++)
{
if (acceptance_sets->test(accept_set))
intersect_acceptance_sets->setBit(accept_set);
}
}
if (!a2_has_no_acceptance_sets)
{
acceptance_sets = &(a2[a2.initial_state].acceptanceSets());
for (unsigned long int accept_set = 0;
accept_set < a2.number_of_acceptance_sets;
accept_set++)
{
if (acceptance_sets->test(accept_set))
intersect_acceptance_sets->setBit(a1.number_of_acceptance_sets
+ accept_set);
}
}
/*
* Pop pairs of states of the two original automata until all states have
* been processed.
*/
try
{
while (!unprocessed_states.empty())
{
if (::user_break)
throw UserBreakException();
intersect_state_valid = false;
state_pair = unprocessed_states.top();
unprocessed_states.pop();
/*
* Loop through the transitions of the two original automata. If the
* conjunction of the guard formulae of any two transitions is
* satisfiable, insert a new transition into the intersection automaton.
* Create new states in the intersection automaton if necessary.
*/
transitions1 = &a1[state_pair->first].edges();
transitions2 = &a2[state_pair->second].edges();
for (GraphEdgeContainer::const_iterator tr1 = transitions1->begin();
tr1 != transitions1->end();
++tr1)
{
guard1 = &(static_cast<BuchiTransition*>(*tr1)->guard());
for (GraphEdgeContainer::const_iterator tr2 = transitions2->begin();
tr2 != transitions2->end();
++tr2)
{
guard2 = &(static_cast<BuchiTransition*>(*tr2)->guard());
new_guard = &Ltl::And::construct(*guard1, *guard2);
if (new_guard->satisfiable())
{
/*
* Determine the `current' state of the intersection automaton.
*/
if (!intersect_state_valid)
{
intersect_state = state_mapping[*state_pair];
intersect_state_valid = true;
}
/*
* Test whether the state pair pointed to by the two transitions
* is already in the intersection.
*/
pair<map<StateIdPair, size_type, less<StateIdPair>,
ALLOC(size_type) >::iterator, bool>
check_state;
check_state
= state_mapping.insert(make_pair(make_pair((*tr1)->targetNode(),
(*tr2)->targetNode()),
first_free_id));
if (check_state.second) /* insertion occurred? */
{
automaton->expand();
/*
* Determine the acceptance sets to which the new state in the
* intersection automaton belongs.
*/
intersect_acceptance_sets
= &((*automaton)[first_free_id].acceptanceSets());
if (!a1_has_no_acceptance_sets)
{
acceptance_sets = &(a1[check_state.first->first.first].
acceptanceSets());
for (unsigned long int accept_set = 0;
accept_set < a1.number_of_acceptance_sets;
accept_set++)
{
if (acceptance_sets->test(accept_set))
intersect_acceptance_sets->setBit(accept_set);
}
}
if (!a2_has_no_acceptance_sets)
{
acceptance_sets = &(a2[check_state.first->first.second].
acceptanceSets());
for (unsigned long int accept_set = 0;
accept_set < a2.number_of_acceptance_sets;
accept_set++)
{
if (acceptance_sets->test(accept_set))
intersect_acceptance_sets->setBit
(a1.number_of_acceptance_sets + accept_set);
}
}
/*
* Connect the `current' state of the intersection automaton to
* the new state.
*/
automaton->connect(intersect_state, first_free_id, new_guard);
first_free_id++;
unprocessed_states.push(&(check_state.first->first));
}
else
automaton->connect(intersect_state, check_state.first->second,
new_guard);
}
else
::Ltl::LtlFormula::destruct(new_guard);
}
}
}
if (intersection_state_mapping != 0)
{
for (map<StateIdPair, size_type, less<StateIdPair>, ALLOC(size_type) >
::const_iterator mapping = state_mapping.begin();
mapping != state_mapping.end();
++mapping)
intersection_state_mapping->insert(make_pair(mapping->second,
mapping->first));
}
}
catch (...)
{
delete automaton;
throw;
}
return automaton;
}
/* ========================================================================= */
void BuchiAutomaton::print
(ostream& stream, const int indent, const GraphOutputFormat fmt) const
@ -880,7 +566,7 @@ void BuchiAutomaton::print
<< " transitions.\n" + string(indent, ' ')
+ "The automaton has "
<< number_of_acceptance_sets
<< " sets of accepting states.\n" + string(indent, ' ')
<< " acceptance sets.\n" + string(indent, ' ')
+ "The reachable part of the automaton contains\n"
+ string(indent + 4, ' ')
<< reachable_part_statistics.first
@ -941,7 +627,8 @@ void BuchiAutomaton::print
++transition)
{
estream << string(indent + 2, ' ') + 'n' << state;
(*transition)->print(stream, indent, fmt);
static_cast<const BuchiTransition*>(*transition)
->print(stream, indent, fmt, number_of_acceptance_sets);
estream << ";\n";
}
}
@ -964,16 +651,23 @@ void BuchiAutomaton::print
/* ========================================================================= */
void BuchiAutomaton::BuchiTransition::print
(ostream& stream, const int indent, const GraphOutputFormat fmt) const
(ostream& stream, const int indent, const GraphOutputFormat fmt,
const unsigned long int number_of_acceptance_sets) const
/* ----------------------------------------------------------------------------
*
* Description: Writes information about a transition between two states of
* a Büchi automaton.
*
* Arguments: stream -- A reference to an output stream.
* indent -- Number of spaces to leave to the left of output.
* fmt -- Determines the format of output.
*
* Arguments: stream -- A reference to an output
* stream.
* indent -- Number of spaces to leave to
* the left of output.
* fmt -- Determines the format of
* output.
* number_of_acceptance_sets -- Number of acceptance sets in
* the automaton to which the
* transition belongs.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
@ -981,11 +675,9 @@ void BuchiAutomaton::BuchiTransition::print
Exceptional_ostream estream(&stream, ios::failbit | ios::badbit);
if (fmt == NORMAL)
{
estream << string(indent, ' ') + "Transition to state "
<< targetNode()
<< " [ guard: " << *guard_formula << " ]\n";
}
<< " [ acc.: ";
else if (fmt == DOT)
{
string formula(StringUtil::toString(*guard_formula));
@ -1006,9 +698,33 @@ void BuchiAutomaton::BuchiTransition::print
else
estream << formula[i];
}
estream << "\",fontsize=10,fontname=\"Courier-Bold\"]";
estream << "\\n";
}
estream << '{';
bool first_printed = false;
for (unsigned long int accept_set = 0;
accept_set < number_of_acceptance_sets;
++accept_set)
{
if (acceptance_sets[accept_set])
{
if (first_printed)
estream << ", ";
else
first_printed = true;
estream << accept_set;
}
}
estream << '}';
if (fmt == NORMAL)
estream << ", guard: " << *guard_formula << " ]\n";
else if (fmt == DOT)
estream << "\",fontsize=10,fontname=\"Courier-Bold\"]";
estream.flush();
}
@ -1073,7 +789,8 @@ void BuchiAutomaton::BuchiState::print
GraphEdgeContainer::const_iterator edge;
for (edge = edges().begin(); edge != edges().end(); ++edge)
(*edge)->print(stream, indent);
static_cast<const BuchiAutomaton::BuchiTransition*>(*edge)
->print(stream, indent, fmt, number_of_acceptance_sets);
} else
estream << string(indent, ' ') + "No transitions to other states.\n";

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -21,6 +21,7 @@
#define BUCHIAUTOMATON_H
#include <config.h>
#include <cstdlib>
#include <iostream>
#include <map>
#include <string>
@ -38,8 +39,7 @@ namespace Graph
/******************************************************************************
*
* A class for representing Büchi automata with a single set of accepting
* states.
* A class for representing generalized Büchi automata.
*
*****************************************************************************/
@ -139,15 +139,19 @@ public:
void connect /* Connects two states */
(const size_type father, /* of the automaton with */
const size_type child); /* an unguarded
* transition.
* transition with no
* associated acceptance
* sets.
*/
void connect /* Connects two states */
(const size_type father, const size_type child, /* of the automaton with */
::Ltl::LtlFormula& guard); /* a transition guarded */
void connect /* by a propositional */
(const size_type father, const size_type child, /* formula. */
::Ltl::LtlFormula* guard);
::Ltl::LtlFormula& guard, /* a transition guarded */
const BitArray& acc_sets); /* by a propositional */
void connect /* formula. */
(const size_type father, const size_type child,
::Ltl::LtlFormula* guard,
const BitArray& acc_sets);
/* `disconnect' inherited from Graph<GraphEdgeContainer> */
@ -167,12 +171,6 @@ public:
* automaton.
*/
BuchiAutomaton* regularize() const; /* Converts a generalized
* automaton to an
* automaton with one set
* of accepting states.
*/
void read(istream& input_stream); /* Reads the automaton
* from a stream.
*/
@ -181,17 +179,10 @@ public:
(ostream& stream = cout, /* about the automaton */
const int indent = 0, /* to a stream in */
const GraphOutputFormat fmt = NORMAL) const; /* various formats
* (determined by the
* `fmt' argument).
* (determined by the
* `fmt' argument).
*/
static BuchiAutomaton* intersect /* Computes the */
(const BuchiAutomaton& a1, /* intersection of two */
const BuchiAutomaton& a2, /* Büchi automata. */
map<size_type, StateIdPair,
less<size_type>, ALLOC(StateIdPair) >*
intersection_state_mapping = 0);
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
class AutomatonParseException; /* Class for reporting
@ -227,14 +218,12 @@ class BuchiAutomaton::BuchiTransition : public Graph<GraphEdgeContainer>::Edge
public:
BuchiTransition /* Constructor. */
(const size_type target,
::Ltl::LtlFormula* formula);
::Ltl::LtlFormula* formula,
const BitArray& acc_sets,
unsigned long int num_acc_sets);
~BuchiTransition(); /* Destructor. */
private:
public:
/* `targetNode' inherited from Graph<GraphEdgeContainer>::Edge */
bool enabled /* These functions test */
@ -249,14 +238,24 @@ public:
* propositional formula
* guarding the transition.
*/
BitArray& acceptanceSets(); /* Returns the */
const BitArray& acceptanceSets() const; /* acceptance sets
* associated with the
* the transition.
*/
void print /* Writes information */
(ostream& stream, /* about the transition */
const int indent, /* (as a plain graph */
const GraphOutputFormat fmt) const; /* edge) to a stream. */
void print /* Writes information */
(ostream& stream = cout, /* about the transition */
const int indent = 0, /* to a stream in */
const GraphOutputFormat fmt = NORMAL) const; /* various formats
* (determined by the
* `fmt' argument).
*/
(ostream& stream, /* about the transition */
const int indent, /* to a stream in */
const GraphOutputFormat fmt, /* various formats */
const unsigned long int /* (determined by the */
number_of_acceptance_sets) const; /* `fmt' argument). */
private:
BuchiTransition(const BuchiTransition&); /* Prevent copying and */
@ -281,6 +280,11 @@ private:
* formula guarding the
* transition.
*/
BitArray acceptance_sets; /* Acceptance sets
* associated with the
* transition.
*/
};
@ -372,7 +376,8 @@ inline void BuchiAutomaton::connect
*
* Description: Connects two states of a BuchiAutomaton to each other with an
* unguarded transition (actually, a transition with a guard
* that is always true).
* that is always true) with an empty set of acceptance
* conditions.
*
* Arguments: father -- Source state identifier.
* child -- Target state identifier.
@ -381,50 +386,59 @@ inline void BuchiAutomaton::connect
*
* ------------------------------------------------------------------------- */
{
connect(father, child, &(::Ltl::True::construct()));
BitArray acc_sets(number_of_acceptance_sets);
acc_sets.clear(number_of_acceptance_sets);
connect(father, child, &(::Ltl::True::construct()), acc_sets);
}
/* ========================================================================= */
inline void BuchiAutomaton::connect
(const size_type father, const size_type child, ::Ltl::LtlFormula& guard)
(const size_type father, const size_type child, ::Ltl::LtlFormula& guard,
const BitArray& acc_sets)
/* ----------------------------------------------------------------------------
*
* Description: Connects two states of a BuchiAutomaton to each other, using
* a LtlFormula (which is actually a propositional formula) to
* guard the transition between the states.
*
* Arguments: father -- Source state.
* child -- Target state.
* guard -- A reference to an LtlFormula (a propositional
* formula) guarding the transition.
* Arguments: father -- Source state.
* child -- Target state.
* guard -- A reference to an LtlFormula (a propositional
* formula) guarding the transition.
* acc_sets -- A reference to a BitArray giving the
* acceptance sets associated with the transition.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
connect(father, child, guard.clone());
connect(father, child, guard.clone(), acc_sets);
}
/* ========================================================================= */
inline void BuchiAutomaton::connect
(const size_type father, const size_type child, ::Ltl::LtlFormula* guard)
(const size_type father, const size_type child, ::Ltl::LtlFormula* guard,
const BitArray& acc_sets)
/* ----------------------------------------------------------------------------
*
* Description: Connects two states of a BuchiAutomaton to each other, using
* a LtlFormula (which is actually a propositional formula) to
* guard the transition between the states.
*
* Arguments: father -- Source state.
* child -- Target state.
* guard -- A pointer to an LtlFormula (a propositional
* formula) guarding the transition. The transition
* will "own" the guard formula.
* Arguments: father -- Source state.
* child -- Target state.
* guard -- A pointer to an LtlFormula (a propositional
* formula) guarding the transition. The
* transition will "own" the guard formula.
* acc_sets -- A reference to a BitArray giving the acceptance
* sets associated with the transition.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
BuchiTransition* new_buchi_transition = new BuchiTransition(child, guard);
BuchiTransition* new_buchi_transition
= new BuchiTransition(child, guard, acc_sets, number_of_acceptance_sets);
try
{
@ -512,39 +526,28 @@ inline istream& operator>>(istream& stream, BuchiAutomaton& automaton)
/* ========================================================================= */
inline BuchiAutomaton::BuchiTransition::BuchiTransition
(const size_type target, ::Ltl::LtlFormula* formula) :
Edge(target), guard_formula(formula)
(const size_type target, ::Ltl::LtlFormula* formula,
const BitArray& acc_sets, unsigned long int num_acc_sets) :
Edge(target), guard_formula(formula), acceptance_sets(num_acc_sets)
/* ----------------------------------------------------------------------------
*
* Description: Constructor for class BuchiAutomaton::BuchiTransition.
* Initializes a new transition to a BuchiState, guarded by an
* LtlFormula (which is actually a propositional formula).
*
* Arguments: target -- Identifier of the target state of the automaton.
* formula -- A pointer to a propositional formula guarding
* the transition.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
inline BuchiAutomaton::BuchiTransition::BuchiTransition
(const BuchiTransition& transition) :
Edge(transition), guard_formula(transition.guard_formula->clone())
/* ----------------------------------------------------------------------------
*
* Description: Copy constructor for class BuchiAutomaton::BuchiTransition.
* Creates a copy of a BuchiTransition object.
*
* Arguments: transition -- BuchiTransition to be copied.
* Arguments: target -- Identifier of the target state of the
* automaton.
* formula -- A pointer to a propositional formula guarding
* the transition.
* acc_sets -- A reference to a constant BitArray containing
* the acceptance sets associated with the
* transition.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
acceptance_sets.copy(acc_sets, num_acc_sets);
}
/* ========================================================================= */
@ -688,6 +691,59 @@ inline ::Ltl::LtlFormula& BuchiAutomaton::BuchiTransition::guard() const
return *guard_formula;
}
/* ========================================================================= */
inline BitArray& BuchiAutomaton::BuchiTransition::acceptanceSets()
/* ----------------------------------------------------------------------------
*
* Description: Returns the acceptance sets associated with a
* BuchiTransition.
*
* Arguments: None.
*
* Returns: A reference to the BitArray storing the acceptance sets
* associated with the transition.
*
* ------------------------------------------------------------------------- */
{
return acceptance_sets;
}
/* ========================================================================= */
inline const BitArray& BuchiAutomaton::BuchiTransition::acceptanceSets() const
/* ----------------------------------------------------------------------------
*
* Description: Returns the acceptance sets associated with a
* BuchiTransition.
*
* Arguments: None.
*
* Returns: A constant reference to the BitArray storing the acceptance
* sets associated with the transition.
*
* ------------------------------------------------------------------------- */
{
return acceptance_sets;
}
/* ========================================================================= */
inline void BuchiAutomaton::BuchiTransition::print
(ostream& stream, const int indent, const GraphOutputFormat fmt) const
/* ----------------------------------------------------------------------------
*
* Description: Writes information about a transition (as a plain graph edge
* without any associated information) to a stream.
*
* Arguments: stream -- A reference to an output stream.
* indent -- Number of spaces to leave to the left of output.
* fmt -- Determines the output format of the transition.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
Graph<GraphEdgeContainer>::Edge::print(stream, indent, fmt);
}
/******************************************************************************

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -28,8 +28,7 @@ namespace Graph
*
*****************************************************************************/
map< ::Ltl::LtlFormula*, BuchiProduct::SatisfiabilityMapping,
less< ::Ltl::LtlFormula*>, ALLOC(BuchiProduct::SatisfiabilityMapping) >
map< ::Ltl::LtlFormula*, BuchiProduct::SatisfiabilityMapping>
BuchiProduct::sat_cache;
@ -73,8 +72,7 @@ bool BuchiProduct::synchronizable
guard_1 = swap_guard;
}
map<LtlFormula*, SatisfiabilityMapping, less<LtlFormula*>,
ALLOC(SatisfiabilityMapping) >::iterator
map<LtlFormula*, SatisfiabilityMapping>::iterator
sat_cache_element = sat_cache.find(guard_1);
if (sat_cache_element == sat_cache.end())

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -142,18 +142,16 @@ private:
* automata.
*/
typedef map< ::Ltl::LtlFormula*, bool, /* Type definition for */
less< ::Ltl::LtlFormula*>, /* storing information */
ALLOC(bool) > /* about the */
SatisfiabilityMapping; /* satisfiability of the
typedef map< ::Ltl::LtlFormula*, bool> /* Type definition for */
SatisfiabilityMapping; /* storing information
* about the
* satisfiability of the
* guards of product
* transitions.
*/
static map< ::Ltl::LtlFormula*, /* Result cache for */
SatisfiabilityMapping, /* satisfiability tests. */
less< ::Ltl::LtlFormula*>,
ALLOC(SatisfiabilityMapping) >
SatisfiabilityMapping> /* satisfiability tests. */
sat_cache;
};

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -19,11 +19,6 @@
%{
#include <config.h>
#include <cmath>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <string>
#include "Configuration.h"
#include "Config-parse.h"
@ -34,225 +29,102 @@ extern int config_file_line_number;
%option case-insensitive
%option never-interactive
%option noyywrap
%option nounput
%x ATTR EQ VAL
SQSTR [^\'\n]*
DQSTR ([^\"\\\n]|\\.)*
UQC [^\'\"\\ \t\n]
UQSTR ({UQC}+|\\.)({UQC}*|\\.)*
OKVAL \'{SQSTR}\'|\"{DQSTR}\"|{UQSTR}
%%
[ \t]* { /* Skip whitespace. */ }
"#"[^\n]* { /* Skip comments. */ }
<*>[ \t]* { /* Skip whitespace everywhere. */ }
<*>"#".*$ { /* Skip comments everywhere. */ }
"\n" { /* Skip newlines, but update the line number. */
<INITIAL,ATTR>"\n" { /* Skip newlines, but update the line number. */
config_file_line_number++;
}
"{" { return CFG_LBRACE; }
"}" { return CFG_RBRACE; }
"=" { return CFG_EQUALS; }
algorithm { return CFG_ALGORITHM; }
enabled { return CFG_ENABLED; }
name { return CFG_NAME; }
parameters { return CFG_PARAMETERS; }
path { return CFG_PROGRAMPATH; }
"{" { BEGIN(ATTR); return CFG_LBRACE; }
algorithm|implementation|translator { return CFG_ALGORITHM; }
globaloptions { return CFG_GLOBALOPTIONS; }
comparisoncheck { return CFG_COMPARISONTEST; }
comparisontest { return CFG_COMPARISONTEST; }
consistencycheck { return CFG_CONSISTENCYTEST; }
consistencytest { return CFG_CONSISTENCYTEST; }
interactive { return CFG_INTERACTIVE; }
intersectioncheck { return CFG_INTERSECTIONTEST; }
intersectiontest { return CFG_INTERSECTIONTEST; }
modelcheck { return CFG_MODELCHECK; }
rounds { return CFG_ROUNDS; }
verbosity { return CFG_VERBOSITY; }
statespaceoptions { return CFG_STATESPACEOPTIONS; }
edgeprobability { return CFG_EDGEPROBABILITY; }
propositions { return CFG_PROPOSITIONS; }
size { return CFG_SIZE; }
truthprobability { return CFG_TRUTHPROBABILITY; }
changeinterval { return CFG_CHANGEINTERVAL; }
randomseed { return CFG_RANDOMSEED; }
formulaoptions { return CFG_FORMULAOPTIONS; }
abbreviatedoperators { return CFG_ABBREVIATEDOPERATORS; }
andpriority { return CFG_ANDPRIORITY; }
beforepriority { return CFG_BEFOREPRIORITY; }
defaultoperatorpriority { return CFG_DEFAULTOPERATORPRIORITY; }
equivalencepriority { return CFG_EQUIVALENCEPRIORITY; }
falsepriority { return CFG_FALSEPRIORITY; }
finallypriority { return CFG_FINALLYPRIORITY; }
generatemode { return CFG_GENERATEMODE; }
globallypriority { return CFG_GLOBALLYPRIORITY; }
implicationpriority { return CFG_IMPLICATIONPRIORITY; }
nextpriority { return CFG_NEXTPRIORITY; }
notpriority { return CFG_NOTPRIORITY; }
orpriority { return CFG_ORPRIORITY; }
outputmode { return CFG_OUTPUTMODE; }
propositionpriority { return CFG_PROPOSITIONPRIORITY; }
releasepriority { return CFG_RELEASEPRIORITY; }
strongreleasepriority { return CFG_STRONGRELEASEPRIORITY; }
truepriority { return CFG_TRUEPRIORITY; }
untilpriority { return CFG_UNTILPRIORITY; }
weakuntilpriority { return CFG_WEAKUNTILPRIORITY; }
xorpriority { return CFG_XORPRIORITY; }
true|yes {
yylval.truth_value = true;
return CFG_TRUTH_VALUE;
[^ \t\n]+ { return CFG_UNKNOWN; }
<ATTR>enabled { BEGIN(EQ); return CFG_ENABLED; }
<ATTR>name { BEGIN(EQ); return CFG_NAME; }
<ATTR>parameters { BEGIN(EQ); return CFG_PARAMETERS; }
<ATTR>path { BEGIN(EQ); return CFG_PROGRAMPATH; }
<ATTR>comparisoncheck { BEGIN(EQ); return CFG_COMPARISONTEST; }
<ATTR>comparisontest { BEGIN(EQ); return CFG_COMPARISONTEST; }
<ATTR>consistencycheck { BEGIN(EQ); return CFG_CONSISTENCYTEST; }
<ATTR>consistencytest { BEGIN(EQ); return CFG_CONSISTENCYTEST; }
<ATTR>interactive { BEGIN(EQ); return CFG_INTERACTIVE; }
<ATTR>intersectioncheck { BEGIN(EQ); return CFG_INTERSECTIONTEST; }
<ATTR>intersectiontest { BEGIN(EQ); return CFG_INTERSECTIONTEST; }
<ATTR>modelcheck { BEGIN(EQ); return CFG_MODELCHECK; }
<ATTR>rounds { BEGIN(EQ); return CFG_ROUNDS; }
<ATTR>translatortimeout { BEGIN(EQ); return CFG_TRANSLATORTIMEOUT; }
<ATTR>verbosity { BEGIN(EQ); return CFG_VERBOSITY; }
<ATTR>edgeprobability { BEGIN(EQ); return CFG_EDGEPROBABILITY; }
<ATTR>propositions { BEGIN(EQ); return CFG_PROPOSITIONS; }
<ATTR>size { BEGIN(EQ); return CFG_SIZE; }
<ATTR>truthprobability { BEGIN(EQ); return CFG_TRUTHPROBABILITY; }
<ATTR>changeinterval { BEGIN(EQ); return CFG_CHANGEINTERVAL; }
<ATTR>randomseed { BEGIN(EQ); return CFG_RANDOMSEED; }
<ATTR>abbreviatedoperators { BEGIN(EQ); return CFG_ABBREVIATEDOPERATORS; }
<ATTR>andpriority { BEGIN(EQ); return CFG_ANDPRIORITY; }
<ATTR>beforepriority { BEGIN(EQ); return CFG_BEFOREPRIORITY; }
<ATTR>defaultoperatorpriority {
BEGIN(EQ); return CFG_DEFAULTOPERATORPRIORITY;
}
<ATTR>equivalencepriority { BEGIN(EQ); return CFG_EQUIVALENCEPRIORITY; }
<ATTR>falsepriority { BEGIN(EQ); return CFG_FALSEPRIORITY; }
<ATTR>finallypriority { BEGIN(EQ); return CFG_FINALLYPRIORITY; }
<ATTR>generatemode { BEGIN(EQ); return CFG_GENERATEMODE; }
<ATTR>globallypriority { BEGIN(EQ); return CFG_GLOBALLYPRIORITY; }
<ATTR>implicationpriority { BEGIN(EQ); return CFG_IMPLICATIONPRIORITY; }
<ATTR>nextpriority { BEGIN(EQ); return CFG_NEXTPRIORITY; }
<ATTR>notpriority { BEGIN(EQ); return CFG_NOTPRIORITY; }
<ATTR>orpriority { BEGIN(EQ); return CFG_ORPRIORITY; }
<ATTR>outputmode { BEGIN(EQ); return CFG_OUTPUTMODE; }
<ATTR>propositionpriority { BEGIN(EQ); return CFG_PROPOSITIONPRIORITY; }
<ATTR>releasepriority { BEGIN(EQ); return CFG_RELEASEPRIORITY; }
<ATTR>strongreleasepriority { BEGIN(EQ); return CFG_STRONGRELEASEPRIORITY; }
<ATTR>truepriority { BEGIN(EQ); return CFG_TRUEPRIORITY; }
<ATTR>untilpriority { BEGIN(EQ); return CFG_UNTILPRIORITY; }
<ATTR>weakuntilpriority { BEGIN(EQ); return CFG_WEAKUNTILPRIORITY; }
<ATTR>xorpriority { BEGIN(EQ); return CFG_XORPRIORITY; }
<ATTR>"}" { BEGIN(INITIAL); return CFG_RBRACE; }
<ATTR>"="?[^= \t\n]* { return CFG_UNKNOWN; }
<EQ>"=" { BEGIN(VAL); return CFG_EQUALS; }
<EQ>. { return CFG_UNKNOWN; }
<VAL>\\|{OKVAL}+(\\)? {
yylval.value = yytext;
BEGIN(ATTR);
return CFG_VALUE;
}
false|no {
yylval.truth_value = false;
return CFG_TRUTH_VALUE;
}
always {
yylval.interactivity_value =
Configuration::ALWAYS;
return CFG_INTERACTIVITY_VALUE;
}
never {
yylval.interactivity_value =
Configuration::NEVER;
return CFG_INTERACTIVITY_VALUE;
}
onerror {
yylval.interactivity_value =
Configuration::ONERROR;
return CFG_INTERACTIVITY_VALUE;
}
normal {
yylval.formula_mode_value =
Configuration::NORMAL;
return CFG_FORMULA_MODE_VALUE;
}
nnf {
yylval.formula_mode_value = Configuration::NNF;
return CFG_FORMULA_MODE_VALUE;
}
local {
yylval.product_type_value = Configuration::LOCAL;
return CFG_PRODUCT_TYPE_VALUE;
}
global {
yylval.product_type_value =
Configuration::GLOBAL;
return CFG_PRODUCT_TYPE_VALUE;
}
randomgraph {
yylval.statespace_mode_value
= Configuration::RANDOMGRAPH;
return CFG_STATESPACE_MODE_VALUE;
}
randomconnectedgraph {
yylval.statespace_mode_value
= Configuration::RANDOMCONNECTEDGRAPH;
return CFG_STATESPACE_MODE_VALUE;
}
randompath {
yylval.statespace_mode_value
= Configuration::RANDOMPATH;
return CFG_STATESPACE_MODE_VALUE;
}
enumeratedpath {
yylval.statespace_mode_value
= Configuration::ENUMERATEDPATH;
return CFG_STATESPACE_MODE_VALUE;
}
"-"?[0-9]+"...""-"?[0-9]+ {
char* dot_ptr;
yylval.integer_interval.min
= strtol(yytext, &dot_ptr, 10);
if (yylval.integer_interval.min == LONG_MIN
|| yylval.integer_interval.min == LONG_MAX)
throw Configuration::ConfigurationException
(config_file_line_number,
"integer out of range");
dot_ptr += 3;
yylval.integer_interval.max
= strtol(dot_ptr, 0, 10);
if (yylval.integer_interval.max == LONG_MIN
|| yylval.integer_interval.max == LONG_MAX)
throw Configuration::ConfigurationException
(config_file_line_number,
"integer out of range");
return CFG_INTEGER_INTERVAL;
}
"-"?[0-9]+ {
yylval.integer = strtol(yytext, 0, 10);
if (yylval.integer == LONG_MIN
|| yylval.integer == LONG_MAX)
throw Configuration::ConfigurationException
(config_file_line_number,
"integer out of range");
return CFG_INTEGER;
}
"-"?[0-9]*"."[0-9]+ {
yylval.real = strtod(yytext, 0);
if (yylval.real == HUGE_VAL
|| yylval.real == -HUGE_VAL)
throw Configuration::ConfigurationException
(config_file_line_number,
"real number out of range");
return CFG_REAL;
}
\"([^\n\"\\]*(\\[^\n])?)*\" {
unsigned long int len = strlen(yytext);
bool escape = false;
yylval.str = new string;
for (unsigned long int i = 1; i < len - 1; i++)
{
if (!escape && yytext[i] == '\\')
escape = true;
else
{
escape = false;
(*yylval.str) += yytext[i];
}
}
return CFG_STRING_CONSTANT;
}
. {
return CFG_UNKNOWN;
<VAL>{OKVAL}*(\'{SQSTR}|\"{DQSTR})(\\)? {
throw Configuration::ConfigurationException
(config_file_line_number,
"unmatched quotes");
}
<EQ,VAL>"\n" { return CFG_UNKNOWN; }
%%
/* ========================================================================= */
int getCharacter()
/* ----------------------------------------------------------------------------
*
* Description: Reads the next character from the lexer input stream.
*
* Arguments: None.
*
* Returns: The next character in the lexer input stream or EOF if there
* are no more characters to read.
*
* ------------------------------------------------------------------------- */
{
return yyinput();
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -21,6 +21,7 @@
#define CONFIGURATION_H
#include <config.h>
#include <cstdio>
#include <iostream>
#include <map>
#include <set>
@ -35,8 +36,6 @@
using namespace std;
/******************************************************************************
*
* A class for storing program configuration information.
@ -63,21 +62,29 @@ public:
struct AlgorithmInformation; /* See below. */
string algorithmString /* Formats the the id */
(vector<AlgorithmInformation, /* of an algorithm and */
ALLOC(AlgorithmInformation) >::size_type/* the name of the */
algorithm_id) const; /* algorithm into a
(vector<AlgorithmInformation>::size_type /* of an algorithm and */
algorithm_id) const; /* the name of the
* algorithm into a
* string.
*/
bool isInternalAlgorithm(unsigned long int id) /* Tests whether a given */
const; /* algorithm identifier
* refers to lbtt's
* internal model
* checking algorithm.
*/
static void showCommandLineHelp /* Prints the list of */
(const char* program_name); /* command line options. */
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
enum InteractionMode {NEVER, ALWAYS, ONERROR}; /* Enumeration constants
* affecting the behaviour
* of the program as
* regards user control.
enum InteractionMode {NEVER, ALWAYS, ONERROR, /* Enumeration constants */
ONBREAK}; /* affecting the
* behavior of the
* program as regards
* user control.
*/
enum FormulaMode {NORMAL, NNF}; /* Enumeration constants
@ -109,19 +116,23 @@ public:
* parameters).
*/
{
string* name; /* Name of the algorithm.
string name; /* Name of the algorithm.
*/
string* path_to_program; /* Path to the executable
char** parameters; /* Command-line parameters
* required for running
* the algorithm.
*/
string* extra_parameters; /* Additional command-line
* parameters required for
* running the executable.
* the executable. See
* the documentation for
* the registerAlgorithm
* function (in
* Configuration.cc) for
* more information.
*/
vector<string>::size_type num_parameters; /* Number of command-line
* parameters.
*/
bool enabled; /* Determines whether the
* algorithm is enabled
* (whether it will be used
@ -169,6 +180,12 @@ public:
* commands.
*/
bool handle_breaks; /* If true, pause testing
* also on interrupt
* signals instead of
* simply aborting.
*/
unsigned long int number_of_rounds; /* Number of test rounds.
*/
@ -278,6 +295,10 @@ public:
* formula generation
* algorithms.
*/
unsigned int translator_timeout; /* Timeout (in seconds) for
* translators.
*/
};
struct FormulaConfiguration /* A structure for storing
@ -290,11 +311,12 @@ public:
* LTL formula symbols.
*/
map<int, int, less<int>, ALLOC(int) > /* Priorities for LTL */
symbol_priority; /* formula symbols. */
map<int, int> symbol_priority; /* Priorities for LTL
* formula symbols.
*/
map<int, double, less<int>, ALLOC(double) > /* Expected numbers of */
symbol_distribution; /* occurrence for the
map<int, double> symbol_distribution; /* Expected numbers of
* occurrence for the
* different formula
* operators.
*/
@ -354,12 +376,18 @@ public:
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
vector<AlgorithmInformation, /* A vector containing */
ALLOC(AlgorithmInformation) > algorithms; /* information about the
vector<AlgorithmInformation> algorithms; /* A vector containing
* information about the
* algorithms used in
* the tests.
*/
map<string, unsigned long int> algorithm_names; /* Mapping between
* algorithm names and
* their numeric
* identifiers.
*/
GlobalConfiguration global_options; /* General configuration
* information.
*/
@ -376,15 +404,6 @@ public:
* algorithms.
*/
typedef pair<int, int> IntPair;
set<IntPair, less<IntPair>, ALLOC(IntPair) > /* Configuration options */
locked_options; /* the values of which
* should not be
* initialized from the
* configuration file.
*/
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
class ConfigurationException : public Exception /* A class for reporting
@ -419,6 +438,9 @@ public:
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
private:
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
struct IntegerRange /* Data structure for
* representing integer-
* valued ranges of certain
@ -426,11 +448,11 @@ public:
* options.
*/
{
long int min; /* Lower bound. */
unsigned long int min; /* Lower bound. */
long int max; /* Upper bound. */
unsigned long int max; /* Upper bound. */
char* error_message; /* Error message to be
const char* error_message; /* Error message to be
* displayed if the value
* is not within the
* specified range.
@ -439,31 +461,30 @@ public:
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/*
* Ranges for certain integer-valued configuration options.
*/
/* Ranges for certain integer-valued configuration options. */
static const struct IntegerRange
VERBOSITY_RANGE, ROUND_COUNT_RANGE, GENERATION_RANGE, PRIORITY_RANGE,
PROPOSITION_COUNT_RANGE, FORMULA_SIZE_RANGE, FORMULA_MAX_SIZE_RANGE,
STATESPACE_SIZE_RANGE, STATESPACE_MAX_SIZE_RANGE;
DEFAULT_RANGE, VERBOSITY_RANGE,
ROUND_COUNT_RANGE, RANDOM_SEED_RANGE,
ATOMIC_PRIORITY_RANGE, OPERATOR_PRIORITY_RANGE;
private:
enum CommandLineOptionType /* Command line options. */
{OPT_COMPARISONTEST = 10000, OPT_CONFIGFILE,
/* Command line options. */
enum CommandLineOptionType
{OPT_HELP = 'h', OPT_VERSION = 'V',
OPT_COMPARISONTEST = 10000, OPT_CONFIGFILE,
OPT_CONSISTENCYTEST, OPT_DISABLE, OPT_ENABLE,
OPT_FORMULACHANGEINTERVAL, OPT_FORMULAFILE,
OPT_FORMULARANDOMSEED, OPT_HELP = 'h',
OPT_GLOBALPRODUCT = 20000, OPT_INTERACTIVE,
OPT_FORMULACHANGEINTERVAL,
OPT_FORMULAFILE, OPT_FORMULARANDOMSEED,
OPT_GLOBALPRODUCT, OPT_INTERACTIVE,
OPT_INTERSECTIONTEST, OPT_LOGFILE,
OPT_MODELCHECK, OPT_NOCOMPARISONTEST,
OPT_NOCONSISTENCYTEST, OPT_NOINTERSECTIONTEST,
OPT_NOPAUSE, OPT_PAUSE, OPT_PAUSEONERROR,
OPT_PROFILE, OPT_QUIET, OPT_ROUNDS,
OPT_SHOWCONFIG, OPT_SHOWOPERATORDISTRIBUTION,
OPT_SKIP, OPT_STATESPACECHANGEINTERVAL,
OPT_STATESPACERANDOMSEED, OPT_VERBOSITY,
OPT_VERSION,
OPT_MODELCHECK, OPT_PROFILE, OPT_QUIET,
OPT_ROUNDS, OPT_SHOWCONFIG,
OPT_SHOWOPERATORDISTRIBUTION, OPT_SKIP,
OPT_STATESPACECHANGEINTERVAL,
OPT_STATESPACERANDOMSEED,
OPT_TRANSLATORTIMEOUT, OPT_VERBOSITY,
OPT_LOCALPRODUCT,
@ -476,7 +497,6 @@ private:
OPT_FORMULAPROPOSITIONS, OPT_FORMULASIZE,
OPT_GENERATENNF, OPT_GLOBALLYPRIORITY,
OPT_IMPLICATIONPRIORITY, OPT_NEXTPRIORITY,
OPT_NOABBREVIATEDOPERATORS,
OPT_NOGENERATENNF, OPT_NOOUTPUTNNF,
OPT_NOTPRIORITY, OPT_ORPRIORITY,
OPT_OUTPUTNNF, OPT_PROPOSITIONPRIORITY,
@ -492,17 +512,18 @@ private:
OPT_STATESPACEPROPOSITIONS,
OPT_STATESPACESIZE, OPT_TRUTHPROBABILITY};
typedef map<pair<int, int>, double, /* Type definitions for */
less<pair<int, int> >, /* the result cache used */
ALLOC(double) > /* for computing the */
ProbabilityMapElement; /* probability */
typedef map<int, ProbabilityMapElement, /* distribution of LTL */
less<int>, /* formula operators. */
ALLOC(ProbabilityMapElement) >
ProbabilityMap;
typedef map<pair<int, int>, double> /* Type definitions for */
ProbabilityMapElement; /* the result cache used */
/* for computing the */
typedef map<int, ProbabilityMapElement> /* probability */
ProbabilityMap; /* distribution of LTL
* formula operators.
*/
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
friend int yyparse();
Configuration(const Configuration& cfg); /* Prevent copying and */
Configuration& operator= /* assignment of */
(const Configuration& cfg); /* Configuration
@ -514,10 +535,59 @@ private:
* to default values.
*/
long int parseCommandLineInteger /* Converts an integer */
(const string& option, const string& value) /* to a string with */
const; /* some additional
* validity checks.
void registerAlgorithm /* Adds a new algorithm */
(const string& name, const string& path, /* to the configuration. */
const string& parameters, bool enabled,
const int block_begin_line);
template<typename T> /* Reads an integer, */
void readInteger /* checks that it is */
(T& target, const string& value, /* within given bounds */
const IntegerRange& range = DEFAULT_RANGE); /* and stores it into
* an unsigned integer
* type variable.
*/
void readProbability /* Reads a probability */
(double& target, const string& value); /* and stores it into
* a given variable of
* type double.
*/
void readSize(int valtype, const string& value); /* Initializes formula or
* state space size
* ranges from a given
* string.
*/
void readTruthValue /* Interprets a symbolic */
(bool& target, const string& value); /* truth value. */
void readInteractivity(const string& value); /* Interprets a symbolic
* interactivity mode.
*/
void readProductType(const string& value); /* Interprets a symbolic
* model checking mode.
*/
void readFormulaMode /* Interprets a symbolic */
(FormulaMode& target, const string& mode); /* formula mode.
*/
void readStateSpaceMode(const string& mode); /* Initializes
* `global_options.
* statespace_generation
* _mode' from a
* symbolic mode
* identifier.
*/
void readTranslatorTimeout(const string& value); /* Initializes
* `global_options.
* translator_timeout'
* from a symbolic time
* specification.
*/
double operatorProbability /* Computes the */
@ -532,6 +602,97 @@ private:
/******************************************************************************
*
* Declarations for functions and variables provided by the parser.
*
*****************************************************************************/
extern int config_file_line_number; /* Number of the current
* line in the
* configuration file.
*/
extern int parseConfiguration /* Parser interface. */
(FILE*, Configuration&);
/******************************************************************************
*
* Inline function definitions for class Configuration.
*
*****************************************************************************/
/* ========================================================================= */
inline bool Configuration::isInternalAlgorithm(unsigned long int id) const
/* ----------------------------------------------------------------------------
*
* Description: Tests whether a given algorithm identifier refers to lbtt's
* internal model checking algorithm.
*
* Argument: id -- Identifier to test.
*
* Returns: True if `id' is the identifier of lbtt's internal model
* checking algorithm.
*
* ------------------------------------------------------------------------- */
{
return ((global_options.statespace_generation_mode & Configuration::PATH)
&& id == algorithms.size() - 1);
}
/******************************************************************************
*
* Template function definitions for class Configuration.
*
*****************************************************************************/
/* ========================================================================= */
template<typename T>
void Configuration::readInteger
(T& target, const string& value, const IntegerRange& range)
/* ----------------------------------------------------------------------------
*
* Description: Reads an integer and stores it into `target'.
*
* Arguments: target -- A reference to an unsigned integer type variable
* for storing the result.
* value -- The integer as a string.
* range -- A reference to a constant IntegerRange object
* giving the bounds for the value.
*
* Returns: Nothing; the result is stored into `target'. The function
* throws a ConfigurationException if `value' is not a valid
* integer within the bounds specified by `range'.
*
* ------------------------------------------------------------------------- */
{
string error;
unsigned long int val;
try
{
val = ::StringUtil::parseNumber(value);
}
catch (const ::StringUtil::NotANumberException&)
{
error = "`" + value + "' is not a valid nonnegative integer";
}
if (error.empty() && (val < range.min || val > range.max))
error = range.error_message;
if (!error.empty())
throw ConfigurationException(config_file_line_number, error);
target = val;
}
/******************************************************************************
*
* Inline function definitions for class Configuration::ConfigurationException.

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -32,10 +32,10 @@
namespace DispUtil
{
stack<StreamFormatting, /* Stack for storing the */
deque<StreamFormatting, /* previous states of an */
ALLOC(StreamFormatting) > > /* output stream. */
stream_formatting_stack;
stack<StreamFormatting, deque<StreamFormatting> > /* Stack for storing the */
stream_formatting_stack; /* previous states of an
* output stream.
*/
/* ========================================================================= */
void changeStreamFormatting

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -20,10 +20,6 @@
#ifndef DISPUTIL_H
#define DISPUTIL_H
#ifdef __GNUC__
#pragma interface
#endif /* __GNUC__ */
#include <config.h>
#include <iostream>
#include <string>
@ -62,6 +58,16 @@ void printTextBlock /* Writes an indented */
* a stream.
*/
bool printText /* "Verbosity-aware" */
(const char* text, /* functions for writing */
const int verbosity_threshold, /* text to standard */
const int indent); /* output. */
bool printText
(const string& text,
const int verbosity_threshold,
const int indent);
/******************************************************************************
@ -82,16 +88,6 @@ struct StreamFormatting
* e.g. the justification
* of output.
*/
bool printText /* "Verbosity-aware" */
(const char* text, /* functions for writing */
const int verbosity_threshold, /* text to standard */
const int indent); /* output. */
bool printText
(const string& text,
const int verbosity_threshold,
const int indent);
};

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -23,6 +23,7 @@
#include <config.h>
#include <string>
#include <exception>
#include <istream>
#include <iostream>
using namespace std;
@ -299,6 +300,16 @@ public:
template<class T> /* Operator for reading */
Exceptional_istream &operator>>(T &t); /* from the stream. */
Exceptional_istream& get(istream::char_type& C); /* Reads a character from
* the stream.
*/
Exceptional_istream& read /* Reads a given number */
(istream::char_type* buffer, streamsize count); /* of characters from
* the stream into a
* buffer.
*/
operator istream&(); /* Casts the exception-
* aware input stream into
* a regular input stream.
@ -992,6 +1003,47 @@ inline Exceptional_istream::~Exceptional_istream()
{
}
/* ========================================================================= */
inline Exceptional_istream& Exceptional_istream::get(istream::char_type& c)
/* ----------------------------------------------------------------------------
*
* Description: Reads a character from the input stream.
*
* Argument: c -- A reference to a character to extract.
*
* Returns: A reference to the stream.
*
* ------------------------------------------------------------------------- */
{
stream->get(c);
if (stream->rdstate() & exception_mask)
throw IOException("error reading from stream");
return *this;
}
/* ========================================================================= */
inline Exceptional_istream& Exceptional_istream::read
(istream::char_type* buffer, streamsize count)
/* ----------------------------------------------------------------------------
*
* Description: Reads a given number of characters from the stream into a
* buffer.
*
* Arguments: buffer -- A pointer to the buffer.
* count -- Number of characters to read.
*
* Returns: A reference to the stream.
*
* ------------------------------------------------------------------------- */
{
stream->read(buffer, count);
if (stream->rdstate() & exception_mask)
throw IOException("error reading from stream");
return *this;
}
/* ========================================================================= */
inline Exceptional_istream::operator istream&()
/* ----------------------------------------------------------------------------

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -18,12 +18,11 @@
*/
#include <config.h>
#include <csignal>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif /* HAVE_FCNTL_H */
@ -64,25 +63,30 @@ ExternalTranslator::~ExternalTranslator()
}
/* ========================================================================= */
ExternalTranslator::TempFileObject&
ExternalTranslator::registerTempFileObject
(const string& filename, TempFileObject::Type type)
const char* ExternalTranslator::registerTempFileObject
(const string& filename, const TempFsysName::NameType type,
const bool literal)
/* ----------------------------------------------------------------------------
*
* Description: Registers a temporary file or directory such that it will be
* automatically deleted when the ExternalTranslator object is
* destroyed.
*
* Arguments: filename -- Name of the temporary file or directory.
* Arguments: filename -- Name of the temporary file or directory. If
* empty, a new name will be created.
* type -- Type of the object (TempFileObject::FILE or
* TempFileObject::DIRECTORY).
* literal -- Tells whether the file name should be
* interpreted literally.
*
* Returns: A reference to the file object.
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
temporary_file_objects.push(new TempFileObject(filename, type));
return *temporary_file_objects.top();
TempFsysName* name = new TempFsysName;
name->allocate(filename.c_str(), type, literal);
temporary_file_objects.push(name);
return name->get();
}
/* ========================================================================= */
@ -101,21 +105,19 @@ void ExternalTranslator::translate
*
* ------------------------------------------------------------------------- */
{
TempFileObject& external_program_input_file = registerTempFileObject();
const char* external_program_input_file
= registerTempFileObject("lbtt-translate");
TempFileObject& external_program_output_file = registerTempFileObject();
const char* external_program_output_file
= registerTempFileObject("lbtt-translate");
string translated_formula;
translateFormula(formula, translated_formula);
std::cout << translated_formula << std::endl;
ofstream input_file;
input_file.open(external_program_input_file.getName().c_str(),
ios::out | ios::trunc);
input_file.open(external_program_input_file, ios::out | ios::trunc);
if (!input_file.good())
throw FileCreationException(string("`")
+ external_program_input_file.getName()
throw FileCreationException(string("`") + external_program_input_file
+ "'");
Exceptional_ostream einput_file(&input_file, ios::failbit | ios::badbit);
@ -125,106 +127,11 @@ void ExternalTranslator::translate
input_file.close();
string command_line = string(command_line_arguments[2])
+ commandLine(external_program_input_file.getName(),
external_program_output_file.getName());
+ commandLine(external_program_input_file,
external_program_output_file);
int exitcode = system(command_line.c_str());
/*
* system() blocks SIGINT and SIGQUIT. If the child was killed
* by such a signal, forward the signal to the current process.
*/
if (WIFSIGNALED(exitcode) &&
(WTERMSIG(exitcode) == SIGINT || WTERMSIG(exitcode) == SIGQUIT))
raise(WTERMSIG(exitcode));
if (!execSuccess(exitcode))
if (!execSuccess(system(command_line.c_str())))
throw ExecFailedException(command_line_arguments[2]);
parseAutomaton(external_program_output_file.getName(), filename);
}
/******************************************************************************
*
* Function definitions for class ExternalTranslator::TempFileObject.
*
*****************************************************************************/
/* ========================================================================= */
ExternalTranslator::TempFileObject::TempFileObject
(const string& filename, Type t)
/* ----------------------------------------------------------------------------
*
* Description: Constructor for class TempFileObject. Creates a temporary
* file or a directory and tests whether it can really be
* written to (if not, a FileCreationException is thrown).
*
* Arguments: filename -- Name of the temporary file or directory.
* If the filename is an empty string, the
* filename is obtained by a call to tmpnam(3).
* t -- Type of the object (TempFileObject::FILE or
* TempFileObject::DIRECTORY).
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
if (filename.empty())
{
char tempname[L_tmpnam + 1];
if (tmpnam(tempname) == 0)
throw FileCreationException("a temporary file");
name = tempname;
}
else
name = filename;
if (t == FILE)
{
ofstream tempfile;
tempfile.open(name.c_str(), ios::out | ios::trunc);
if (!tempfile.good())
throw FileCreationException("a temporary file");
tempfile.close();
}
else
{
if (mkdir(name.c_str(), 0700) != 0)
throw FileCreationException("a temporary directory");
}
type = t;
}
/* ========================================================================= */
ExternalTranslator::TempFileObject::~TempFileObject()
/* ----------------------------------------------------------------------------
*
* Description: Destructor for class TempFileObject. Deletes the file or
* the directory associated with the object (displays a warning
* if this fails).
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
if (remove(name.c_str()) != 0)
{
string msg("error removing temporary ");
if (type == TempFileObject::FILE)
msg += "file";
else
msg += "directory";
msg += " `" + name + "'";
printWarning(msg);
}
parseAutomaton(external_program_output_file, filename);
}

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -17,10 +17,6 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifdef __GNUC__
#pragma implementation
#endif /* __GNUC__ */
#include <config.h>
#include "FormulaRandomizer.h"
#include "Random.h"
@ -96,7 +92,7 @@ LtlFormula* FormulaRandomizer::recGenerate(unsigned long int target_size)
*
* ------------------------------------------------------------------------- */
{
vector<IntegerPair, ALLOC(IntegerPair) >::const_iterator symbol_priority;
vector<IntegerPair>::const_iterator symbol_priority;
LtlFormula* formula;
long int x;

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -21,6 +21,7 @@
#define FORMULARANDOMIZER_H
#include <config.h>
#include <map>
#include <vector>
#include <utility>
#include "LbttAlloc.h"
@ -86,16 +87,16 @@ public:
* `reset'.
*/
const map<unsigned long int, unsigned long int, /* Get the numbers of */
less<unsigned long int>, /* different atomic */
ALLOC(unsigned long int) >& /* propositions */
propositionStatistics() const; /* generated since the
const map<unsigned long int, unsigned long int>& /* Get the numbers of */
propositionStatistics() const; /* different atomic
* propositions
* generated since the
* last call to `reset'.
*/
const map<int, unsigned long int, less<int>, /* Get the numbers of */
ALLOC(unsigned long int) >& /* different symbols */
symbolStatistics() const; /* generated since the
const map<int, unsigned long int>& /* Get the numbers of */
symbolStatistics() const; /* different symbols
* generated since the
* last call to `reset'.
*/
@ -123,21 +124,20 @@ private:
typedef pair<int, int> IntegerPair;
vector<IntegerPair, ALLOC(IntegerPair) > /* Operand symbols and */
vector<IntegerPair> /* Operand symbols and */
propositional_symbol_priorities; /* their priorities in
* random formulae.
*/
vector<IntegerPair, ALLOC(IntegerPair) > /* Operators and their */
short_formula_operators; /* priorities in random
* formulae of size
* two.
vector<IntegerPair> short_formula_operators; /* Operators and their
* priorities in random
* formulae of size two.
*/
vector<IntegerPair, ALLOC(IntegerPair) > /* Operators and their */
long_formula_operators; /* priorities in random
* formulae of size
* greater than two.
vector<IntegerPair> long_formula_operators; /* Operators and their
* priorities in random
* formulae of size greater
* than two.
*/
unsigned long int number_of_generated_formulas; /* Number of generated
@ -145,14 +145,15 @@ private:
* last call to `reset'.
*/
map<unsigned long int, unsigned long int, /* Number of different */
less<unsigned long int>, /* atomic propositions */
ALLOC(unsigned long int) > /* generated since the */
proposition_statistics; /* last call to `reset' */
map<unsigned long int, unsigned long int> /* Number of different */
proposition_statistics; /* atomic propositions
* generated since the
* last call to `reset'
*/
map<int, unsigned long int, less<int>, /* Number of different */
ALLOC(unsigned long int) > /* formula symbols */
symbol_statistics; /* generated since the
map<int, unsigned long int> symbol_statistics; /* Number of different
* formula symbols
* generated since the
* last call to `reset'.
*/
};
@ -288,8 +289,7 @@ inline unsigned long int FormulaRandomizer::numberOfFormulas() const
}
/* ========================================================================= */
inline const map<unsigned long int, unsigned long int, less<unsigned long int>,
ALLOC(unsigned long int) >&
inline const map<unsigned long int, unsigned long int>&
FormulaRandomizer::propositionStatistics() const
/* ----------------------------------------------------------------------------
*
@ -307,7 +307,7 @@ FormulaRandomizer::propositionStatistics() const
}
/* ========================================================================= */
inline const map<int, unsigned long int, less<int>, ALLOC(unsigned long int) >&
inline const map<int, unsigned long int>&
FormulaRandomizer::symbolStatistics() const
/* ----------------------------------------------------------------------------
*

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -21,13 +21,11 @@
#define FORMULAWRITER_H
#include "Exception.h"
#include "LtlFormula.h"
namespace Ltl
{
class LtlFormula;
class Atom;
/******************************************************************************
*
* A function template class for writing the formula to a stream.

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -186,25 +186,38 @@ public:
* graph nodes.
*/
class PathElement; /* A class for representing
* (node, edge) pairs
*/
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
protected:
vector<Node*, ALLOC(Node*) > nodes; /* Nodes of the graph.
vector<Node*> nodes; /* Nodes of the graph.
* Derived classes can
* access this vector
* directly.
*/
public:
typedef typename /* Type definition for */
vector<Node*, ALLOC(Node*) >::size_type /* the size of the */
size_type; /* graph. The size can
typedef typename vector<Node*>::size_type /* Type definition for */
size_type; /* the size of the
* graph. The size can
* be no greater than
* the maximum size of
* the vector containing
* the graph nodes.
*/
typedef EdgeContainer EdgeContainerType; /* Type definition for
* containers of graph
* edges.
*/
typedef deque<PathElement> Path; /* Type definition for
* paths in a graph.
*/
typedef pair<size_type, size_type> StateIdPair; /* Type definition for a
* pair of state
* identifiers in a graph.
@ -323,8 +336,8 @@ public:
/* default assignment operator */
Graph<EdgeContainer>::size_type targetNode() /* Returns the index of */
const; /* the target node of
size_type targetNode() const; /* Returns the index of */
/* the target node of
* the directed edge.
*/
@ -353,7 +366,7 @@ protected:
*/
private:
Graph<EdgeContainer>::size_type target_node; /* Identifier of the edge's
size_type target_node; /* Identifier of the edge's
* target node.
*/
};
@ -404,6 +417,62 @@ protected:
/******************************************************************************
*
* A template class for representing (node identifier, edge) pairs in a graph.
*
*****************************************************************************/
template <class EdgeContainer>
class Graph<EdgeContainer>::PathElement
{
public:
explicit PathElement /* Constructors. */
(const typename Graph<EdgeContainer>::size_type
n,
const typename Graph<EdgeContainer>::Edge*
e = 0);
PathElement
(const typename Graph<EdgeContainer>::size_type
n,
const typename Graph<EdgeContainer>::Edge& e);
/* default copy constructor */
~PathElement(); /* Destructor. */
/* default assignment operator */
size_type node() const; /* Returns the identifier
* of the node associated
* with the path element.
*/
bool hasEdge() const; /* Tells whether there is
* an edge associated with
* the path element.
*/
const Edge& edge() const; /* Returns the edge
* associated with the
* path element.
*/
private:
typename Graph<EdgeContainer>::size_type node_id; /* Identifier of the node
* associated with the path
* element.
*/
const typename Graph<EdgeContainer>::Edge* /* Pointer to the edge */
edge_pointer; /* associated with the
* path element.
*/
};
/******************************************************************************
*
* An exception class for reporting errors when indexing graph nodes.
@ -434,8 +503,7 @@ public:
*
*****************************************************************************/
class EdgeList : public list<Graph<EdgeList>::Edge*,
ALLOC(Graph<EdgeList>::Edge*) >
class EdgeList : public list<Graph<EdgeList>::Edge*>
{
public:
EdgeList(); /* Constructor. */
@ -450,14 +518,12 @@ public:
* the end of the list.
*/
list<Graph<EdgeList>::Edge*, /* Functions for finding */
ALLOC(Graph<EdgeList>::Edge*) > /* an element in the */
::const_iterator /* list. */
find(const Graph<EdgeList>::Edge* edge) const;
list<Graph<EdgeList>::Edge*,
ALLOC(Graph<EdgeList>::Edge*) >
::iterator
list<Graph<EdgeList>::Edge*>::const_iterator /* Functions for finding */
find(const Graph<EdgeList>::Edge* edge) const; /* an element in the
* list.
*/
list<Graph<EdgeList>::Edge*>::iterator
find(const Graph<EdgeList>::Edge* edge);
};
@ -472,8 +538,7 @@ public:
#ifdef HAVE_SLIST
class EdgeSlist : public slist<Graph<EdgeSlist>::Edge*,
ALLOC(Graph<EdgeSlist>::Edge*) >
class EdgeSlist : public slist<Graph<EdgeSlist>::Edge*>
{
public:
EdgeSlist(); /* Constructor. */
@ -489,14 +554,12 @@ public:
* list.
*/
slist<Graph<EdgeSlist>::Edge*, /* Functions for finding */
ALLOC(Graph<EdgeSlist>::Edge*) > /* an element in the */
::const_iterator /* list. */
find(const Graph<EdgeSlist>::Edge* edge) const;
slist<Graph<EdgeSlist>::Edge*>::const_iterator /* Functions for finding */
find(const Graph<EdgeSlist>::Edge* edge) const; /* an element in the
* list.
*/
slist<Graph<EdgeSlist>::Edge*,
ALLOC(Graph<EdgeSlist>::Edge*) >
::iterator
slist<Graph<EdgeSlist>::Edge*>::iterator
find(const Graph<EdgeSlist>::Edge* edge);
};
@ -510,8 +573,7 @@ public:
*
*****************************************************************************/
class EdgeVector : public vector<Graph<EdgeVector>::Edge*,
ALLOC(Graph<EdgeVector>::Edge*) >
class EdgeVector : public vector<Graph<EdgeVector>::Edge*>
{
public:
EdgeVector(); /* Constructor. */
@ -527,15 +589,11 @@ public:
* to edges.
*/
vector<Graph<EdgeVector>::Edge*, /* Functions for finding */
ALLOC(Graph<EdgeVector>::Edge*) > /* an element in the */
::const_iterator /* container. */
find(const Graph<EdgeVector>::Edge* edge)
const;
vector<Graph<EdgeVector>::Edge*>::const_iterator /* Functions for finding */
find(const Graph<EdgeVector>::Edge* edge) /* an element in the */
const; /* container. */
vector<Graph<EdgeVector>::Edge*,
ALLOC(Graph<EdgeVector>::Edge*) >
::iterator
vector<Graph<EdgeVector>::Edge*>::iterator
find(const Graph<EdgeVector>::Edge* edge);
};
@ -548,8 +606,7 @@ public:
*****************************************************************************/
class EdgeSet : public set<Graph<EdgeSet>::Edge*,
Graph<EdgeSet>::Edge::ptr_less,
ALLOC(Graph<EdgeSet>::Edge*) >
Graph<EdgeSet>::Edge::ptr_less>
{
};
@ -562,8 +619,7 @@ class EdgeSet : public set<Graph<EdgeSet>::Edge*,
*****************************************************************************/
class EdgeMultiSet : public multiset<Graph<EdgeMultiSet>::Edge*,
Graph<EdgeMultiSet>::Edge::ptr_less,
ALLOC(Graph<EdgeMultiSet>::Edge*) >
Graph<EdgeMultiSet>::Edge::ptr_less>
{
};
@ -689,7 +745,7 @@ Graph<EdgeContainer>::Graph(const size_type initial_number_of_nodes) :
{
nodes.reserve(initial_number_of_nodes);
for (typename vector<Node*, ALLOC(Node*) >::iterator node = nodes.begin();
for (typename vector<Node*>::iterator node = nodes.begin();
node != nodes.end();
++node)
*node = new Node();
@ -711,8 +767,7 @@ Graph<EdgeContainer>::Graph(const Graph<EdgeContainer>& graph)
* ------------------------------------------------------------------------- */
{
nodes.reserve(graph.nodes.size());
for (typename vector<Node*, ALLOC(Node*) >::const_iterator
node = graph.nodes.begin();
for (typename vector<Node*>::const_iterator node = graph.nodes.begin();
node != graph.nodes.end(); ++node)
nodes.push_back(new Node(**node));
}
@ -738,8 +793,7 @@ Graph<EdgeContainer>& Graph<EdgeContainer>::operator=
clear();
nodes.reserve(graph.nodes.size());
for (typename vector<Node*, ALLOC(Node*) >::const_iterator
node = graph.nodes.begin();
for (typename vector<Node*>::const_iterator node = graph.nodes.begin();
node != graph.nodes.end();
++node)
nodes.push_back(new Node(**node));
@ -782,8 +836,7 @@ void Graph<EdgeContainer>::clear()
*
* ------------------------------------------------------------------------- */
{
for (typename vector<Node*, ALLOC(Node*) >::reverse_iterator
node = nodes.rbegin();
for (typename vector<Node*>::reverse_iterator node = nodes.rbegin();
node != nodes.rend();
++node)
delete *node;
@ -924,13 +977,12 @@ Graph<EdgeContainer>::stats() const
*
* ------------------------------------------------------------------------- */
{
pair<Graph<EdgeContainer>::size_type, unsigned long int> result;
pair<size_type, unsigned long int> result;
result.first = nodes.size();
result.second = 0;
for (typename vector<Node*, ALLOC(Node*) >::const_iterator
node = nodes.begin();
for (typename vector<Node*>::const_iterator node = nodes.begin();
node != nodes.end(); ++node)
result.second += (*node)->edges().size();
@ -964,7 +1016,7 @@ Graph<EdgeContainer>::subgraphStats(const size_type index) const
if (index >= s)
throw NodeIndexException();
stack<size_type, deque<size_type, ALLOC(size_type) > > unprocessed_nodes;
stack<size_type, deque<size_type> > unprocessed_nodes;
BitArray visited_nodes(s);
visited_nodes.clear(s);
@ -1468,6 +1520,128 @@ void Graph<EdgeContainer>::Node::print
/******************************************************************************
*
* Inline function definitions for template class
* Graph<EdgeContainer>::PathElement.
*
*****************************************************************************/
/* ========================================================================= */
template <class EdgeContainer>
inline Graph<EdgeContainer>::PathElement::PathElement
(const typename Graph<EdgeContainer>::size_type n,
const typename Graph<EdgeContainer>::Edge* e) :
node_id(n), edge_pointer(e)
/* ----------------------------------------------------------------------------
*
* Description: Constructor for class Graph<EdgeContainer>::PathElement.
* Creates a (node identifier, edge) pair from a node identifier
* and a pointer to an edge.
*
* Arguments: n -- Numeric identifier of a graph node.
* e -- A constant pointer to a graph edge.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
template <class EdgeContainer>
inline Graph<EdgeContainer>::PathElement::PathElement
(const typename Graph<EdgeContainer>::size_type n,
const typename Graph<EdgeContainer>::Edge& e) :
node_id(n), edge_pointer(&e)
/* ----------------------------------------------------------------------------
*
* Description: Constructor for class Graph<EdgeContainer>::PathElement.
* Creates a (node identifier, edge) pair from a node identifier
* and an edge.
*
* Arguments: n -- Numeric identifier of a graph node.
* e -- A constant reference to a graph edge.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
template <class EdgeContainer>
inline Graph<EdgeContainer>::PathElement::~PathElement()
/* ----------------------------------------------------------------------------
*
* Description: Destructor for class Graph<EdgeContainer>::PathElement.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
template <class EdgeContainer>
inline typename Graph<EdgeContainer>::size_type
Graph<EdgeContainer>::PathElement::node() const
/* ----------------------------------------------------------------------------
*
* Description: Returns the identifier of the node associated with a
* Graph<EdgeContainer>::PathElement object.
*
* Arguments: None.
*
* Returns: Identifier of the node associated with the object.
*
* ------------------------------------------------------------------------- */
{
return node_id;
}
/* ========================================================================= */
template <class EdgeContainer>
inline bool Graph<EdgeContainer>::PathElement::hasEdge() const
/* ----------------------------------------------------------------------------
*
* Description: Tells whether there is an edge associated with a
* Graph<EdgeContainer>::PathElement object.
*
* Arguments: None.
*
* Returns: true iff there is an edge associated with the object.
*
* ------------------------------------------------------------------------- */
{
return (edge != 0);
}
/* ========================================================================= */
template <class EdgeContainer>
inline const typename Graph<EdgeContainer>::Edge&
Graph<EdgeContainer>::PathElement::edge() const
/* ----------------------------------------------------------------------------
*
* Description: Returns the edge associated with a
* Graph<EdgeContainer>::PathElement object. The function
* assumes that there is such an edge; it is an error to call
* this function for a PathElement object `element' for which
* `element.hasEdge() == false'.
*
* Arguments: None.
*
* Returns: The edge associated with the object.
*
* ------------------------------------------------------------------------- */
{
return *edge_pointer;
}
/******************************************************************************
*
* Inline function definitions for class NodeIndexException.
@ -1574,8 +1748,7 @@ inline void EdgeList::insert(Graph<EdgeList>::Edge* edge)
}
/* ========================================================================= */
inline list<Graph<EdgeList>::Edge*, ALLOC(Graph<EdgeList>::Edge*) >
::const_iterator
inline list<Graph<EdgeList>::Edge*>::const_iterator
EdgeList::find(const Graph<EdgeList>::Edge* edge) const
/* ----------------------------------------------------------------------------
*
@ -1586,9 +1759,9 @@ EdgeList::find(const Graph<EdgeList>::Edge* edge) const
* between the actual values of the edges (not the
* pointers).
*
* Returns: A list<Graph<EdgeList>::Edge*, ALLOC>::const_iterator
* Returns: A list<Graph<EdgeList>::Edge*>::const_iterator
* pointing to the edge in the list or
* list<Graph<EdgeList>::Edge*, ALLOC>::end() if the edge is
* list<Graph<EdgeList>::Edge*>::end() if the edge is
* not found in the list.
*
* ------------------------------------------------------------------------- */
@ -1603,7 +1776,7 @@ EdgeList::find(const Graph<EdgeList>::Edge* edge) const
}
/* ========================================================================= */
inline list<Graph<EdgeList>::Edge*, ALLOC(Graph<EdgeList>::Edge*) >::iterator
inline list<Graph<EdgeList>::Edge*>::iterator
EdgeList::find(const Graph<EdgeList>::Edge* edge)
/* ----------------------------------------------------------------------------
*
@ -1614,9 +1787,9 @@ EdgeList::find(const Graph<EdgeList>::Edge* edge)
* between the actual values of the edges (not the
* pointers).
*
* Returns: A list<Graph<EdgeList>::Edge*, ALLOC>::iterator pointing
* Returns: A list<Graph<EdgeList>::Edge*>::iterator pointing
* to the edge in the list or
* list<Graph<EdgeList>::Edge*, ALLOC>::end() if the edge is
* list<Graph<EdgeList>::Edge*>::end() if the edge is
* not found in the list.
*
* ------------------------------------------------------------------------- */
@ -1685,8 +1858,7 @@ inline void EdgeSlist::insert(Graph<EdgeSlist>::Edge* edge)
}
/* ========================================================================= */
inline slist<Graph<EdgeSlist>::Edge*, ALLOC(Graph<EdgeSlist>::Edge*) >
::const_iterator
inline slist<Graph<EdgeSlist>::Edge*>::const_iterator
EdgeSlist::find(const Graph<EdgeSlist>::Edge* edge) const
/* ----------------------------------------------------------------------------
*
@ -1697,9 +1869,9 @@ EdgeSlist::find(const Graph<EdgeSlist>::Edge* edge) const
* between the actual values of the edges (not the
* pointers).
*
* Returns: A slist<Graph<EdgeSlist>::Edge*, ALLOC>::const_iterator
* Returns: A slist<Graph<EdgeSlist>::Edge*>::const_iterator
* pointing to the edge in the list or
* slist<Graph<EdgeSlist>::Edge*, ALLOC>::end() if the edge
* slist<Graph<EdgeSlist>::Edge*>::end() if the edge
* is not found in the list.
*
* ------------------------------------------------------------------------- */
@ -1714,8 +1886,7 @@ EdgeSlist::find(const Graph<EdgeSlist>::Edge* edge) const
}
/* ========================================================================= */
inline slist<Graph<EdgeSlist>::Edge*, ALLOC(Graph<EdgeSlist>::Edge*) >
::iterator
inline slist<Graph<EdgeSlist>::Edge*>::iterator
EdgeSlist::find(const Graph<EdgeSlist>::Edge* edge)
/* ----------------------------------------------------------------------------
*
@ -1726,9 +1897,9 @@ EdgeSlist::find(const Graph<EdgeSlist>::Edge* edge)
* between the actual values of the edges (not the
* pointers).
*
* Returns: A slist<Graph<EdgeSlist>::Edge*, ALLOC>::iterator
* Returns: A slist<Graph<EdgeSlist>::Edge*>::iterator
* pointing to the edge in the list or
* slist<Graph<EdgeSlist>::Edge*, ALLOC>::end() if the edge
* slist<Graph<EdgeSlist>::Edge*>::end() if the edge
* is not found in the list.
*
* ------------------------------------------------------------------------- */
@ -1797,8 +1968,7 @@ inline void EdgeVector::insert(Graph<EdgeVector>::Edge* edge)
}
/* ========================================================================= */
inline vector<Graph<EdgeVector>::Edge*, ALLOC(Graph<EdgeVector>::Edge*) >
::const_iterator
inline vector<Graph<EdgeVector>::Edge*>::const_iterator
EdgeVector::find(const Graph<EdgeVector>::Edge* edge) const
/* ----------------------------------------------------------------------------
*
@ -1809,9 +1979,9 @@ EdgeVector::find(const Graph<EdgeVector>::Edge* edge) const
* between the actual values of the edges (not the
* pointers).
*
* Returns: A vector<Graph<EdgeVector>::Edge*, ALLOC>::const_iterator
* Returns: A vector<Graph<EdgeVector>::Edge*>::const_iterator
* pointing to the edge in the container or
* vector<Graph<EdgeVector>::Edge*, ALLOC>::end() if the
* vector<Graph<EdgeVector>::Edge*>::end() if the
* edge is not found in the container.
*
* ------------------------------------------------------------------------- */
@ -1826,8 +1996,7 @@ EdgeVector::find(const Graph<EdgeVector>::Edge* edge) const
}
/* ========================================================================= */
inline vector<Graph<EdgeVector>::Edge*, ALLOC(Graph<EdgeVector>::Edge*) >
::iterator
inline vector<Graph<EdgeVector>::Edge*>::iterator
EdgeVector::find(const Graph<EdgeVector>::Edge* edge)
/* ----------------------------------------------------------------------------
*
@ -1838,9 +2007,9 @@ EdgeVector::find(const Graph<EdgeVector>::Edge* edge)
* between the actual values of the edges (not the
* pointers).
*
* Returns: A vector<Graph<EdgeVector>::Edge*, ALLOC>::iterator
* Returns: A vector<Graph<EdgeVector>::Edge*>::iterator
* pointing to the edge in the container or
* vector<Graph<EdgeSlist>::Edge*, ALLOC>::end() if the edge
* vector<Graph<EdgeSlist>::Edge*>::end() if the edge
* is not found in the container.
*
* ------------------------------------------------------------------------- */

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 2004
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
* Copyright (C) 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -41,7 +41,7 @@ void IntervalList::merge(unsigned long int min, unsigned long int max)
if (min > max)
return;
list<Interval, ALLOC(Interval) >::iterator interval;
list<Interval>::iterator interval;
for (interval = intervals.begin();
interval != intervals.end() && interval->second + 1 < min;
++interval)
@ -68,14 +68,14 @@ void IntervalList::merge(unsigned long int min, unsigned long int max)
if (interval->second < max)
{
interval->second = max;
list<Interval, ALLOC(Interval) >::iterator interval2 = interval;
list<Interval>::iterator interval2 = interval;
++interval2;
while (interval2 != intervals.end()
&& interval2->first <= interval->second + 1)
{
if (interval->second < interval2->second)
interval->second = interval2->second;
list<Interval, ALLOC(Interval) >::iterator interval_to_erase = interval2;
list<Interval>::iterator interval_to_erase = interval2;
++interval2;
intervals.erase(interval_to_erase);
}
@ -97,7 +97,7 @@ void IntervalList::remove(unsigned long int min, unsigned long int max)
if (min > max)
return;
list<Interval, ALLOC(Interval) >::iterator interval;
list<Interval>::iterator interval;
for (interval = intervals.begin();
interval != intervals.end() && interval->second < min;
++interval)
@ -126,7 +126,7 @@ void IntervalList::remove(unsigned long int min, unsigned long int max)
}
else /* min <= imin <= imax <= max */
{
list<Interval, ALLOC(Interval) >::iterator interval_to_erase = interval;
list<Interval>::iterator interval_to_erase = interval;
++interval;
intervals.erase(interval_to_erase);
}
@ -148,7 +148,7 @@ bool IntervalList::covers(unsigned long int min, unsigned long int max) const
if (min > max)
return true; /* empty interval is always covered */
list<Interval, ALLOC(Interval) >::const_iterator interval;
list<Interval>::const_iterator interval;
for (interval = intervals.begin();
interval != intervals.end() && min > interval->second;
++interval)
@ -173,8 +173,7 @@ string IntervalList::toString() const
* ------------------------------------------------------------------------- */
{
string s;
for (list<Interval, ALLOC(Interval) >::const_iterator
interval = intervals.begin();
for (list<Interval>::const_iterator interval = intervals.begin();
interval != intervals.end();
++interval)
{

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 2004
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
* Copyright (C) 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -74,13 +74,15 @@ public:
unsigned long int operator++(int); /* Postfix increment. */
private:
const list<Interval, ALLOC(Interval) >* /* The interval list */
interval_list; /* associated with the */
/* iterator. */
const list<Interval>* interval_list; /* The interval list
* associated with the
* iterator.
*/
list<Interval, ALLOC(Interval) > /* An iterator pointing */
::const_iterator interval; /* at the current */
/* interval list. */
list<Interval>::const_iterator interval; /* An iterator pointing at
* the current intrerval
* list.
*/
unsigned long int element; /* Element currently
* pointed to by the
@ -143,8 +145,7 @@ public:
* iterators.
*/
typedef list<Interval, ALLOC(Interval) > /* Size type. */
::size_type size_type;
typedef list<Interval>::size_type size_type; /* Size type. */
size_type size() const; /* Tell the number of
* disjoint intervals in
@ -170,7 +171,7 @@ public:
*/
private:
list<Interval, ALLOC(Interval) > intervals; /* List of intervals. */
list<Interval> intervals; /* List of intervals. */
friend class const_iterator;
};

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -22,12 +22,6 @@
#include <config.h>
#ifdef HAVE_SINGLE_CLIENT_ALLOC
#define ALLOC(typename) single_client_alloc
#else
#define ALLOC(typename) allocator<typename>
#endif /* HAVE_SINGLE_CLIENT_ALLOC */
#ifdef HAVE_OBSTACK_H
/* GNU libc 2.3.2's copy of obstack.h uses a definition of __INT_TO_PTR

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 2004
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
* Copyright (C) 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -44,9 +44,9 @@ static LtlFormula* result; /* This variable stores the
* ltl_parse.
*/
static std::set<LtlFormula*, less<LtlFormula*>, /* Intermediate results. */
ALLOC(LtlFormula*) > /* (This set is used */
intermediate_results; /* for keeping track of
static std::set<LtlFormula*> intermediate_results; /* Intermediate results.
* (This set is used
* for keeping track of
* the subformulas of a
* partially constructed
* formula in case the
@ -426,8 +426,8 @@ LtlFormula* parseFormula(istream& stream)
}
catch (...)
{
for (std::set<LtlFormula*, less<LtlFormula*>, ALLOC(LtlFormula*) >
::const_iterator f = intermediate_results.begin();
for (std::set<LtlFormula*>::const_iterator
f = intermediate_results.begin();
f != intermediate_results.end();
++f)
LtlFormula::destruct(*f);

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -17,10 +17,6 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifdef __GNUC__
#pragma implementation
#endif /* __GNUC__ */
#include <config.h>
#include "FormulaWriter.h"
#include "LtlFormula.h"
@ -28,10 +24,8 @@
namespace Ltl
{
map<LtlFormula*, unsigned long int, /* Shared storage for */
LtlFormula::ptr_less, /* LTL formulae. */
ALLOC(unsigned long int) >
LtlFormula::formula_storage;
set<LtlFormula*, LtlFormula::ptr_less> /* Shared storage for */
LtlFormula::formula_storage; /* LTL formulae. */
unsigned long int /* Upper limit for the */
LtlFormula::eval_proposition_id_limit; /* atomic proposition
@ -42,8 +36,6 @@ unsigned long int /* Upper limit for the */
* truth assignment).
*/
/******************************************************************************
*
* Function for obtaining the infix symbol associated with a given
@ -147,12 +139,10 @@ public:
*/
private:
stack<LtlFormula*,
deque<LtlFormula*, ALLOC(LtlFormula*) > >
stack<LtlFormula*, deque<LtlFormula*> >
formula_stack;
stack<bool, deque<bool, ALLOC(bool) > >
negation_stack;
stack<bool, deque<bool> > negation_stack;
NnfConverter(const NnfConverter&); /* Prevent copying and */
NnfConverter& operator=(const NnfConverter&); /* assignment of
@ -203,8 +193,7 @@ class SubformulaCollector
public:
SubformulaCollector /* Constructor. */
(stack<const LtlFormula*,
deque<const LtlFormula*,
ALLOC(const LtlFormula*) > >&
deque<const LtlFormula*> >&
result_stack);
~SubformulaCollector(); /* Destructor. */
@ -216,8 +205,7 @@ public:
private:
stack<const LtlFormula*, /* Stack of subformulae. */
deque<const LtlFormula*,
ALLOC(const LtlFormula*) > >&
deque<const LtlFormula*> >&
subformula_stack;
SubformulaCollector(const SubformulaCollector&); /* Prevent copying and */
@ -389,9 +377,7 @@ inline void FormulaSizeCounter::operator()(const LtlFormula*, int)
/* ========================================================================= */
inline SubformulaCollector::SubformulaCollector
(stack<const LtlFormula*, deque<const LtlFormula*,
ALLOC(const LtlFormula*) > >&
result_stack) :
(stack<const LtlFormula*, deque<const LtlFormula*> >& result_stack) :
subformula_stack(result_stack)
/* ----------------------------------------------------------------------------
*
@ -773,9 +759,7 @@ unsigned long int LtlFormula::size() const
/* ========================================================================= */
void LtlFormula::collectSubformulae
(stack<const LtlFormula*, deque<const LtlFormula*,
ALLOC(const LtlFormula*) > >&
result_stack) const
(stack<const LtlFormula*, deque<const LtlFormula*> >& result_stack) const
/* ----------------------------------------------------------------------------
*
* Description: Collects the subformulae of a LtlFormula into a stack. After
@ -879,193 +863,6 @@ Bitset LtlFormula::findPropositionalModel(long int max_atom) const
return model;
}
/* ========================================================================= */
LtlFormula* LtlFormula::read(Exceptional_istream& stream)
/* ----------------------------------------------------------------------------
*
* Description: Recursively constructs an LtlFormula by parsing input from an
* exception-aware input stream.
*
* Argument: stream -- A reference to an exception-aware input stream.
*
* Returns: The constructed LtlFormula.
*
* ------------------------------------------------------------------------- */
{
string token;
LtlFormula* formula;
try
{
stream >> token;
}
catch (const IOException&)
{
if (static_cast<istream&>(stream).eof())
throw ParseErrorException("error parsing LTL formula (unexpected end of "
"input)");
else
throw ParseErrorException("error parsing LTL formula (I/O error)");
}
if (token[0] == 'p')
{
if (token.length() == 1)
throw ParseErrorException("error parsing LTL formula (unrecognized "
"token: `" + token + "')");
long int id;
char* endptr;
id = strtol(token.c_str() + 1, &endptr, 10);
if (*endptr != '\0' || id < 0 || id == LONG_MIN || id == LONG_MAX)
throw ParseErrorException("error parsing LTL formula (unrecognized "
"token: `" + token + "')");
formula = &Atom::construct(id);
}
else
{
if (token.length() > 1)
throw ParseErrorException("error parsing LTL formula (unrecognized "
"token: `" + token + "')");
switch (token[0])
{
case LTL_TRUE :
formula = &True::construct();
break;
case LTL_FALSE :
formula = &False::construct();
break;
case LTL_NEGATION :
case LTL_NEXT :
case LTL_FINALLY :
case LTL_GLOBALLY :
{
LtlFormula* g = read(stream);
try
{
switch (token[0])
{
case LTL_NEGATION :
formula = &Not::construct(g);
break;
case LTL_NEXT :
formula = &Next::construct(g);
break;
case LTL_FINALLY :
formula = &Finally::construct(g);
break;
default : /* LTL_GLOBALLY */
formula = &Globally::construct(g);
break;
}
}
catch (...)
{
LtlFormula::destruct(g);
throw;
}
break;
}
case LTL_CONJUNCTION :
case LTL_DISJUNCTION :
case LTL_IMPLICATION :
case LTL_EQUIVALENCE :
case LTL_XOR :
case LTL_UNTIL :
case LTL_V :
case LTL_WEAK_UNTIL :
case LTL_STRONG_RELEASE :
case LTL_BEFORE :
{
LtlFormula* g = read(stream);
LtlFormula* h;
try
{
h = read(stream);
}
catch (...)
{
LtlFormula::destruct(g);
throw;
}
try
{
switch (token[0])
{
case LTL_CONJUNCTION :
formula = &And::construct(g, h);
break;
case LTL_DISJUNCTION :
formula = &Or::construct(g, h);
break;
case LTL_IMPLICATION :
formula = &Imply::construct(g, h);
break;
case LTL_EQUIVALENCE :
formula = &Equiv::construct(g, h);
break;
case LTL_XOR :
formula = &Xor::construct(g, h);
break;
case LTL_UNTIL :
formula = &Until::construct(g, h);
break;
case LTL_V :
formula = &V::construct(g, h);
break;
case LTL_WEAK_UNTIL :
formula = &WeakUntil::construct(g, h);
break;
case LTL_STRONG_RELEASE :
formula = &StrongRelease::construct(g, h);
break;
default : /* LTL_BEFORE */
formula = &Before::construct(g, h);
break;
}
}
catch (...)
{
LtlFormula::destruct(g);
LtlFormula::destruct(h);
throw;
}
break;
}
default :
throw ParseErrorException("error parsing LTL formula (unrecognized "
"token: `" + token + "')");
}
}
return formula;
}
/* ========================================================================= */
void LtlFormula::print(Exceptional_ostream& estream, OutputMode mode) const
/* ----------------------------------------------------------------------------

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -23,7 +23,7 @@
#include <config.h>
#include <deque>
#include <iostream>
#include <map>
#include <set>
#include <stack>
#include <string>
#include "LbttAlloc.h"
@ -188,13 +188,6 @@ public:
* input stream.
*/
static LtlFormula* read /* Constructs an */
(Exceptional_istream& stream); /* LtlFormula by parsing
* input from an
* exception-aware input
* stream.
*/
void print /* Writes the formula to */
(ostream& stream = cout, /* an output stream. */
OutputMode mode = LTL_INFIX) const;
@ -250,6 +243,10 @@ protected:
unsigned int is_constant : 1; /* operators and atomic */
} info_flags; /* propositions. */
unsigned long int refcount; /* Number of references to
* `this' LtlFormula.
*/
static LtlFormula& /* Updates the shared */
insertToStorage(LtlFormula* f); /* formula storage with
* a new formula.
@ -264,21 +261,18 @@ private:
void collectSubformulae /* Builds a stack of the */
(stack<const LtlFormula*, /* subformulae of the */
deque<const LtlFormula*, /* formula. */
ALLOC(const LtlFormula*) > >&
deque<const LtlFormula*> >& /* formula. */
result_stack) const;
typedef pair<bool, const LtlFormula*> /* Shorthand type */
FormulaStackElement; /* definitions for the */
typedef stack<FormulaStackElement, /* propositional */
deque<FormulaStackElement, /* satisfiability */
ALLOC(FormulaStackElement) > >/* checking algorithm. */
FormulaStack;
deque<FormulaStackElement> > /* satisfiability */
FormulaStack; /* checking algorithm. */
typedef pair<FormulaStack, Bitset>
TableauStackElement;
typedef stack<TableauStackElement,
deque<TableauStackElement,
ALLOC(TableauStackElement) > >
deque<TableauStackElement> >
TableauStack;
bool sat_eval /* Helper function for */
@ -288,9 +282,8 @@ private:
* formula.
*/
static map<LtlFormula*, unsigned long int, /* Shared storage for */
ptr_less, ALLOC(unsigned long int) > /* LTL formulae. */
formula_storage;
static set<LtlFormula*, ptr_less> /* Shared storage for */
formula_storage; /* LTL formulae. */
static unsigned long int /* Upper limit for the */
eval_proposition_id_limit; /* atomic proposition
@ -330,6 +323,16 @@ private:
/******************************************************************************
*
* Interface to the formula parser.
*
*****************************************************************************/
extern LtlFormula* parseFormula(istream& stream);
/******************************************************************************
*
* A class for atomic propositions.
@ -474,7 +477,7 @@ private:
* to satisfy the
* LtlFormula member
* function interface.
*/
*/
};
@ -1076,7 +1079,7 @@ typedef BinaryFormula<LtlBefore> Before;
*****************************************************************************/
/* ========================================================================= */
inline LtlFormula::LtlFormula()
inline LtlFormula::LtlFormula() : refcount(1)
/* ----------------------------------------------------------------------------
*
* Description: Constructor for class LtlFormula. Initializes the attributes
@ -1088,8 +1091,6 @@ inline LtlFormula::LtlFormula()
*
* --------------------------------------------------------------------------*/
{
info_flags.is_propositional = 0;
info_flags.is_constant = 0;
}
/* ========================================================================= */
@ -1122,14 +1123,9 @@ inline void LtlFormula::destruct(LtlFormula* f)
*
* ------------------------------------------------------------------------- */
{
map<LtlFormula*, unsigned long int, LtlFormula::ptr_less,
ALLOC(unsigned long int) >::iterator
deleter;
deleter = formula_storage.find(f);
if (--deleter->second == 0)
if (--f->refcount == 0)
{
formula_storage.erase(deleter);
formula_storage.erase(f);
delete f;
}
}
@ -1147,7 +1143,7 @@ inline LtlFormula* LtlFormula::clone()
*
* ------------------------------------------------------------------------- */
{
formula_storage.find(this)->second++;
++refcount;
return this;
}
@ -1241,8 +1237,7 @@ inline LtlFormula* LtlFormula::read(istream& stream)
*
* ------------------------------------------------------------------------- */
{
Exceptional_istream estream(&stream, ios::badbit | ios::failbit);
return read(estream);
return parseFormula(stream);
}
/* ========================================================================= */
@ -1303,8 +1298,6 @@ inline Exceptional_ostream& operator<<
return stream;
}
/* ========================================================================= */
inline LtlFormula& LtlFormula::insertToStorage(LtlFormula* f)
/* ----------------------------------------------------------------------------
@ -1317,19 +1310,15 @@ inline LtlFormula& LtlFormula::insertToStorage(LtlFormula* f)
*
* ------------------------------------------------------------------------- */
{
map<LtlFormula*, unsigned long int, LtlFormula::ptr_less,
ALLOC(unsigned long int) >::iterator
inserter;
inserter = formula_storage.find(f);
set<LtlFormula*, ptr_less>::iterator inserter = formula_storage.find(f);
if (inserter != formula_storage.end())
{
delete f;
inserter->second++;
return *(inserter->first);
++(*inserter)->refcount;
return **inserter;
}
formula_storage.insert(make_pair(f, 1));
formula_storage.insert(f);
return *f;
}
@ -1571,8 +1560,7 @@ inline Atom& Atom::construct(long int a)
}
/* ========================================================================= */
inline Atom::Atom(long int a) :
LtlFormula(), atom(a)
inline Atom::Atom(long int a) : atom(a)
/* ----------------------------------------------------------------------------
*
* Description: Constructor for class Atom. Creates a new propositional atom.
@ -1886,8 +1874,7 @@ inline UnaryFormula<Operator>& UnaryFormula<Operator>::construct(LtlFormula& f)
/* ========================================================================= */
template<class Operator>
inline UnaryFormula<Operator>::UnaryFormula(LtlFormula* f) :
LtlFormula(), subformula(f)
inline UnaryFormula<Operator>::UnaryFormula(LtlFormula* f) : subformula(f)
/* ----------------------------------------------------------------------------
*
* Description: Constructs an LTL formula with a unary operator.
@ -2189,7 +2176,7 @@ BinaryFormula<Operator>::construct(LtlFormula& f1, LtlFormula* f2)
/* ========================================================================= */
template<class Operator>
inline BinaryFormula<Operator>::BinaryFormula(LtlFormula* f1, LtlFormula* f2) :
LtlFormula(), subformula1(f1), subformula2(f2)
subformula1(f1), subformula2(f2)
/* ----------------------------------------------------------------------------
*
* Description: Constructs a binary LTL formula.

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -30,6 +30,7 @@ extern int current_neverclaim_line_number;
%option never-interactive
%option noyywrap
%option nounput
%%

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -17,10 +17,6 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifdef __GNUC__
#pragma implementation
#endif /* __GNUC__ */
#include <config.h>
#include <cstdio>
#include <fstream>
@ -66,8 +62,7 @@ void NeverClaimAutomaton::clear()
*
* ------------------------------------------------------------------------- */
{
for (vector<StateInfo*, ALLOC(StateInfo*) >::iterator
state = state_list.begin();
for (vector<StateInfo*>::iterator state = state_list.begin();
state != state_list.end();
++state)
delete (*state);
@ -158,8 +153,7 @@ void NeverClaimAutomaton::write(const char* output_filename)
* `-1'.
*/
for (vector<StateInfo*, ALLOC(StateInfo*) >::const_iterator
state = state_list.begin();
for (vector<StateInfo*>::const_iterator state = state_list.begin();
state != state_list.end();
++state)
{
@ -167,7 +161,7 @@ void NeverClaimAutomaton::write(const char* output_filename)
+ ((*state)->initial() ? "1" : "0") + ' '
+ ((*state)->accepting() ? "0 " : "") + "-1\n";
for (multimap<Cstr, Cstr*, less<Cstr>, ALLOC(Cstr*) >::const_iterator
for (multimap<Cstr, Cstr*>::const_iterator
transition = (*state)->transitions().begin();
transition != (*state)->transitions().end(); ++transition)
{
@ -272,7 +266,7 @@ NeverClaimAutomaton::StateInfo::~StateInfo()
*
* ------------------------------------------------------------------------- */
{
for (multimap<Cstr, Cstr*, less<Cstr>, ALLOC(Cstr*) >::const_iterator
for (multimap<Cstr, Cstr*>::const_iterator
transition = state_transitions.begin();
transition != state_transitions.end();
++transition)
@ -312,7 +306,7 @@ ParseErrorException::ParseErrorException
else
{
string space_string(msg.substr(0, error_pos));
for (string::size_type c = 0; c < msg.length(); c++)
for (string::size_type c = 0; c < space_string.length(); c++)
if (space_string[c] != ' ' && space_string[c] != '\t')
space_string[c] = ' ';

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -93,12 +93,13 @@ public:
*/
private:
vector<StateInfo*, ALLOC(StateInfo*) > /* States of the */
state_list; /* automaton. */
vector<StateInfo*> state_list; /* States of the automaton.
*/
map<string, StateInfo*, less<string>, /* Mapping from state */
ALLOC(StateInfo*) > /* labels to the states */
label_mapping; /* itself. */
map<string, StateInfo*> label_mapping; /* Mapping from state
* labels to the states
* itself.
*/
StateInfo* current_state; /* Pointer to the state
* introduced most recently
@ -142,9 +143,9 @@ public:
/* of the state.
*/
const multimap<Cstr, Cstr*, less<Cstr>, /* Returns the labels of */
ALLOC(Cstr*) >& /* the state's successor */
transitions() const; /* states, including the
const multimap<Cstr, Cstr*>& transitions() const; /* Returns the labels of
* the state's successor
* states, including the
* conditions controlling
* the enabledness of the
* transition.
@ -174,8 +175,8 @@ private:
* accepting state?
*/
multimap<Cstr, Cstr*, less<Cstr>, ALLOC(Cstr*) > /* Labels of the state's */
state_transitions; /* successors, including
multimap<Cstr, Cstr*> state_transitions; /* Labels of the state's
* successors, including
* the guard formulae
* controlling the
* enabledness of the
@ -373,9 +374,7 @@ inline bool& NeverClaimAutomaton::StateInfo::accepting()
}
/* ========================================================================= */
inline const multimap<NeverClaimAutomaton::Cstr, NeverClaimAutomaton::Cstr*,
less<NeverClaimAutomaton::Cstr>,
ALLOC(NeverClaimAutomaton::Cstr*) >&
inline const multimap<NeverClaimAutomaton::Cstr, NeverClaimAutomaton::Cstr*>&
NeverClaimAutomaton::StateInfo::transitions() const
/* ----------------------------------------------------------------------------
*

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -17,10 +17,6 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifdef __GNUC__
#pragma implementation
#endif /* __GNUC__ */
#include <config.h>
#include <deque>
#include <stack>
@ -53,9 +49,8 @@ void PathEvaluator::reset()
current_loop_state = 0;
path_states.clear();
for (map<const LtlFormula*, BitArray*, LtlFormula::ptr_less,
ALLOC(BitArray*) >::iterator it
= eval_info.begin();
for (map<const LtlFormula*, BitArray*, LtlFormula::ptr_less>::iterator
it = eval_info.begin();
it != eval_info.end();
++it)
delete it->second;
@ -65,26 +60,25 @@ void PathEvaluator::reset()
/* ========================================================================= */
bool PathEvaluator::evaluate
(const LtlFormula& formula, const StateSpace& statespace,
const vector<StateSpace::size_type, ALLOC(StateSpace::size_type) >&
states_on_path,
StateSpace::size_type loop_state)
(const LtlFormula& formula, const StateSpace::Path& prefix,
const StateSpace::Path& cycle, const StateSpace& statespace)
/* ----------------------------------------------------------------------------
*
* Description: Evaluates an LTL formula in a state space in which the states
* are connected into a non-branching sequence that ends in a
* loop.
* Description: Evaluates an LTL formula in a path formed from a prefix and
* an infinitely repeating cycle of states in a state space.
*
* Arguments: formula -- Formula to be evaluated.
* statespace -- State space from which the path is
* extracted.
* states_on_path -- Mapping between states in the path and
* the states in `statespace' such that
* `statespace[states_on_path[i]]'
* corresponds to the ith state of the path.
* loop_state -- Number of the state in the path to which
* the ``last'' state of the path is
* connected.
* Arguments: formula -- Formula to be evaluated.
* prefix -- A StateSpace::Path object corresponding to
* the prefix of the path. Only the state
* identifiers in the path elements are used;
* the function will not require `prefix' to
* actually represent a path in `statespace'.
* cycle -- A StateSpace::Path object corresponding to
* the infinitely repeating cycle. Only the
* state identifiers in the path elements are
* relevant.
* statespace -- State space to which the state identifiers in
* `path' and `cycle' refer.
*
* Returns: `true' if and only if the LTL formula holds in the path.
*
@ -92,13 +86,21 @@ bool PathEvaluator::evaluate
{
reset();
if (states_on_path.empty() || loop_state >= states_on_path.size())
if (cycle.empty())
return false;
current_formula = &formula;
current_path = &statespace;
current_loop_state = loop_state;
path_states = states_on_path;
current_loop_state = prefix.size();
path_states.reserve(prefix.size() + cycle.size());
for (StateSpace::Path::const_iterator state = prefix.begin();
state != prefix.end();
++state)
path_states.push_back(state->node());
for (StateSpace::Path::const_iterator state = cycle.begin();
state != cycle.end();
++state)
path_states.push_back(state->node());
return eval();
}
@ -128,8 +130,7 @@ bool PathEvaluator::evaluate
current_formula = &formula;
current_path = &statespace;
map<StateSpace::size_type, StateSpace::size_type,
less<StateSpace::size_type>, ALLOC(StateSpace::size_type) > ordering;
map<StateSpace::size_type, StateSpace::size_type> ordering;
StateSpace::size_type state = statespace.initialState();
StateSpace::size_type state_count = 0;
@ -173,9 +174,7 @@ bool PathEvaluator::eval()
*
* ------------------------------------------------------------------------- */
{
stack<const LtlFormula*, deque<const LtlFormula*,
ALLOC(const LtlFormula*) > >
subformula_stack;
stack<const LtlFormula*, deque<const LtlFormula*> > subformula_stack;
const LtlFormula* f;
BitArray* val;

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -54,11 +54,11 @@ public:
bool evaluate /* Tests whether an */
(const LtlFormula& formula, /* LtlFormula holds in a */
const StateSpace& statespace, /* state space. */
const vector<StateSpace::size_type,
ALLOC(StateSpace::size_type) >&
states_on_path,
StateSpace::size_type loop_state);
const StateSpace::Path& prefix, /* path described by a */
const StateSpace::Path& cycle, /* prefix and a cycle of */
const StateSpace& statespace); /* states from a state
* space.
*/
bool evaluate /* Same as above. */
(const LtlFormula& formula,
@ -105,15 +105,15 @@ private:
* the current path.
*/
vector<StateSpace::size_type, /* Correspondence */
ALLOC(StateSpace::size_type) > /* between states of the */
path_states; /* path and the states
vector<StateSpace::size_type> path_states; /* Correspondence
* between states of the
* path and the states
* of the current state
* space.
*/
map<const LtlFormula*, BitArray*, /* Information about the */
LtlFormula::ptr_less, ALLOC(BitArray*) > /* truth values of the */
LtlFormula::ptr_less> /* truth values of the */
eval_info; /* subformulae of the
* formula to be
* evaluated.

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -17,10 +17,6 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifdef __GNUC__
#pragma implementation
#endif /* __GNUC__ */
#include <config.h>
#include "BitArray.h"
#include "PathIterator.h"

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -20,10 +20,6 @@
#ifndef PATHITERATOR_H
#define PATHITERATOR_H
#ifdef __GNUC__
#pragma interface
#endif /* __GNUC__ */
#include <config.h>
#include "StateSpace.h"

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -393,8 +393,8 @@ public:
typedef ProductEdgeCollection EdgeContainerType; /* required for making */
/* Product<Operations> */
struct PathElement; /* suitable for */
typedef deque<PathElement, ALLOC(PathElement) > /* instantiating the */
Path; /* SccCollection
typedef deque<PathElement> Path; /* instantiating the
* SccCollection
* template (see
* SccCollection.h).
*/
@ -419,9 +419,7 @@ private:
Graph<GraphEdgeContainer>::Path >& cycle, /* segment of the cycle */
size_type source_state_id, Edge transition, /* in a witness for the */
const size_type root_id, /* nonemptiness of the */
const map<size_type, PathElement, /* product. */
less<size_type>,
ALLOC(PathElement) >&
const map<size_type, PathElement>& /* product. */
predecessor) const;
Operations operations; /* Operations for
@ -524,8 +522,8 @@ public:
*/
private:
const Graph<GraphEdgeContainer>::Edge* edge_1; /* Components of the */
const Graph<GraphEdgeContainer>::Edge* edge_2; /* transition. */
GraphEdgeContainer::const_iterator edge_1; /* Components of the */
GraphEdgeContainer::const_iterator edge_2; /* transition. */
};
@ -655,9 +653,10 @@ protected:
* acceptance sets.
*/
typedef deque<AcceptanceStackElement, /* Stack formed from */
ALLOC(AcceptanceStackElement) > /* the above */
AcceptanceStack; /* associations. */
typedef deque<AcceptanceStackElement> /* Stack formed from */
AcceptanceStack; /* the above
* associations.
*/
AcceptanceStack acceptance_stack; /* Stack for storing the
* dfs numbers of roots
@ -877,9 +876,9 @@ private:
* reachable.
*/
set<size_type, less<size_type>, /* Set of states from */
ALLOC(size_type) > /* which an accepting */
reachability_info; /* component is known to
set<size_type> reachability_info; /* Set of states from
* which an accepting
* component is known to
* be reachable in the
* product.
*/
@ -928,9 +927,9 @@ public:
~AcceptingComponentFinder(); /* Destructor. */
typedef set<size_type, less<size_type>, /* Type definition for */
ALLOC(size_type) > /* the set of product */
SccType; /* state identifiers in
typedef set<size_type> SccType; /* Type definition for
* the set of product
* state identifiers in
* an accepting
* strongly connected
* component.
@ -1369,10 +1368,9 @@ void Product<Operations>::findWitness
unsigned long int number_of_collected_acceptance_sets
= collected_acceptance_sets.count(number_of_acceptance_sets);
deque<size_type, ALLOC(size_type) > search_queue;
set<size_type, less<size_type>, ALLOC(size_type) > visited;
map<size_type, PathElement, less<size_type>, ALLOC(PathElement) >
shortest_path_predecessor;
deque<size_type> search_queue;
set<size_type> visited;
map<size_type, PathElement> shortest_path_predecessor;
size_type bfs_root = search_start_state;
@ -1475,8 +1473,7 @@ void Product<Operations>::addCycleSegment
(pair<Graph<GraphEdgeContainer>::Path, Graph<GraphEdgeContainer>::Path>&
cycle,
size_type source_state_id, Edge transition, const size_type root_id,
const map<size_type, PathElement, less<size_type>, ALLOC(PathElement) >&
predecessor) const
const map<size_type, PathElement>& predecessor) const
/* ----------------------------------------------------------------------------
*
* Description: Helper function for constructing a segment of an accepting
@ -1598,7 +1595,7 @@ template <class Operations>
inline Product<Operations>::ProductEdge::ProductEdge
(const GraphEdgeContainer::const_iterator& e1,
const GraphEdgeContainer::const_iterator& e2)
: edge_1(*e1), edge_2(*e2)
: edge_1(e1), edge_2(e2)
/* ----------------------------------------------------------------------------
*
* Description: Constructor for class Product<Operations>::ProductEdge.
@ -1643,7 +1640,7 @@ Product<Operations>::ProductEdge::firstComponent() const
*
* ------------------------------------------------------------------------- */
{
return *edge_1;
return **edge_1;
}
/* ========================================================================= */
@ -1662,7 +1659,7 @@ Product<Operations>::ProductEdge::secondComponent() const
*
* ------------------------------------------------------------------------- */
{
return *edge_2;
return **edge_2;
}
/* ========================================================================= */
@ -1679,7 +1676,7 @@ Product<Operations>::ProductEdge::targetNode() const
*
* ------------------------------------------------------------------------- */
{
return product->stateId(edge_1->targetNode(), edge_2->targetNode());
return product->stateId((*edge_1)->targetNode(), (*edge_2)->targetNode());
}

1063
lbtt/src/ProductAutomaton.cc Normal file

File diff suppressed because it is too large Load diff

596
lbtt/src/ProductAutomaton.h Normal file
View file

@ -0,0 +1,596 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
*
* This program 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.
*
* This program 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, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef PRODUCTAUTOMATON_H
#define PRODUCTAUTOMATON_H
#include <config.h>
#include <deque>
#include <iostream>
#include <vector>
#include "LbttAlloc.h"
#include "BitArray.h"
#include "BuchiAutomaton.h"
#include "EdgeContainer.h"
#include "Exception.h"
#include "Graph.h"
#include "StateSpace.h"
using namespace std;
extern bool user_break;
namespace UserCommands
{
extern void printAutomatonAnalysisResults
(ostream&, int, unsigned long int, unsigned long int);
}
namespace Graph
{
/******************************************************************************
*
* A class for representing the synchronous product of a Büchi automaton and
* a state space.
*
*****************************************************************************/
class ProductAutomaton : public Graph<GraphEdgeContainer>
{
private:
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
class ProductState : /* A class for */
public Graph<GraphEdgeContainer>::Node /* representing the */
{ /* states of the product
* automaton.
*/
public:
explicit ProductState /* Constructor. */
(const size_type hash_val = 0);
~ProductState(); /* Destructor. */
/* `edges' inherited from Graph<GraphEdgeContainer>::Node */
size_type hashValue() const; /* Get or set the hash */
size_type& hashValue(); /* value for the product
* state (this value can
* be used to extract
* the identifiers of
* the original state
* space and the Büchi
* automaton with which
* the product state is
* associated).
*/
void print /* Writes information */
(ostream& stream = cout, /* about the product */
const int indent = 0, /* state to a stream. */
const GraphOutputFormat fmt = NORMAL) const;
private:
friend class ProductAutomaton;
ProductState(const ProductState&); /* Prevent copying and */
ProductState& operator=(const ProductState&); /* assignment of
* ProductState objects.
*/
size_type hash_value; /* Hash value for the
* product state (can be
* used to extract the
* identifiers of the
* original state space and
* the Büchi automaton with
* which the product state
* is associated).
*/
Edge* incoming_edge; /* The unique edge pointing
* to `this' ProductState.
*/
};
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
class ProductScc : /* A class for storing */
public vector<ProductAutomaton::size_type, /* maximal strongly */
ALLOC(ProductAutomaton::size_type) > /* connected components */
{ /* of the product.
*/
public:
ProductScc(); /* Constructor. */
/* default copy constructor */
~ProductScc(); /* Destructor. */
/* default assignment operator */
bool fair /* Tests whether the */
(const ProductAutomaton& product_automaton) /* component is fair, */
const; /* i.e. it is a
* nontrivial component
* with a state from
* each acceptance set
* of the Büchi
* automaton used for
* constructing a
* given product.
*/
void insert /* Inserts a state into */
(const ProductAutomaton::size_type /* the container. */
product_state);
};
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
public:
class ProductSizeException; /* An exception class for
* reporting the situation
* where the size of the
* product automaton may
* be too big.
*/
friend class ProductScc;
friend void UserCommands::printAutomatonAnalysisResults
(ostream&, int, unsigned long int, unsigned long int);
ProductAutomaton(); /* Constructor. */
~ProductAutomaton(); /* Destructor. */
ProductState& operator[](const size_type index) /* Indexing operator. No */
const; /* range check is performed
* on the argument.
*/
ProductState& node(const size_type index) const; /* Synonym for the indexing
* operator. This function
* also checks the range of
* the argument.
*/
/* `size' inherited from Graph<GraphEdgeContainer> */
/* `empty' inherited from Graph<GraphEdgeContainer> */
void clear(); /* Makes the automaton
* empty.
*/
void connect /* Connects two states */
(const size_type father, /* of the product */
const size_type child); /* automaton. */
void disconnect /* Disconnects two */
(const size_type father, /* states of the product */
const size_type child); /* automaton. */
/* `connected' inherited from Graph<GraphEdgeContainer> */
/* `stats' inherited from Graph<GraphEdgeContainer> */
/* `subgraphStats' inherited from Graph<GraphEdgeContainer> */
void computeProduct /* Function for */
(const BuchiAutomaton& automaton, /* initializing the */
const StateSpace& statespace, /* product automaton. */
const bool global_product);
StateSpace::size_type systemState /* Returns the */
(const size_type state) const; /* identifier of the
* state of the original
* state space with
* which a given product
* state is associated.
*/
BuchiAutomaton::size_type buchiState /* Returns the */
(const size_type state) const; /* identifier of the
* state of the original
* automaton with which
* a given product state
* is associated.
*/
void emptinessCheck(Bitset& result) const; /* Performs an emptiness
* check on the product.
*/
void findAcceptingExecution /* Extracts an accepting */
(const StateSpace::size_type initial_state, /* execution from the */
pair<deque<StateIdPair, ALLOC(StateIdPair) >, /* product automaton. */
deque<StateIdPair,
ALLOC(StateIdPair) > >&
execution) const;
void print /* Writes information */
(ostream& stream = cout, /* about the product */
const int indent = 0, /* automaton to a */
const GraphOutputFormat fmt = NORMAL) const; /* stream. */
private:
ProductAutomaton(const ProductAutomaton&); /* Prevent copying and */
ProductAutomaton& operator= /* assignment of */
(const ProductAutomaton&); /* ProductAutomaton
* objects.
*/
size_type expand(size_type node_count = 1); /* Inserts states to the
* product automaton.
*/
const BuchiAutomaton* buchi_automaton; /* A pointer to the
* Büchi automaton used for
* constructing the
* product.
*/
StateSpace::size_type statespace_size; /* Size of the state space
* used for constructing
* the product automaton.
*/
#ifdef HAVE_OBSTACK_H /* Storage for product */
ObstackAllocator store; /* states and */
#endif /* HAVE_OBSTACK_H */ /* transitions. */
};
/******************************************************************************
*
* An exception class for reporting the situation where the product may be too
* big to compute.
*
*****************************************************************************/
class ProductAutomaton::ProductSizeException : public Exception
{
public:
ProductSizeException(); /* Constructor. */
/* default copy constructor */
~ProductSizeException() throw(); /* Destructor. */
ProductSizeException& /* Assignment operator. */
operator=(const ProductSizeException& e);
/* `what' inherited from class Exception */
};
/******************************************************************************
*
* Inline function definitions for class ProductAutomaton.
*
*****************************************************************************/
/* ========================================================================= */
inline ProductAutomaton::ProductAutomaton() :
buchi_automaton(0), statespace_size(0)
#ifdef HAVE_OBSTACK_H
, store()
#endif /* HAVE_OBSTACK_H */
/* ----------------------------------------------------------------------------
*
* Description: Constructor for class ProductAutomaton. Initializes a
* new object for storing the product of a Büchi automaton and a
* state space. The product must then be explicitly initialized
* by calling the function `computeProduct' on the object.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
inline ProductAutomaton::~ProductAutomaton()
/* ----------------------------------------------------------------------------
*
* Description: Destructor for class ProductAutomaton.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
clear();
}
/* ========================================================================= */
inline ProductAutomaton::ProductState&
ProductAutomaton::operator[](const size_type index) const
/* ----------------------------------------------------------------------------
*
* Description: Indexing operator for class ProductAutomaton. Can be used to
* refer to the individual states of the product automaton. No
* range check will be performed on the argument.
*
* Argument: index -- Index of a state of the product automaton.
*
* Returns: A reference to the product state corresponding to the index.
*
* ------------------------------------------------------------------------- */
{
return static_cast<ProductState&>(*nodes[index]);
}
/* ========================================================================= */
inline ProductAutomaton::ProductState&
ProductAutomaton::node(const size_type index) const
/* ----------------------------------------------------------------------------
*
* Description: Function for referring to a single state of a
* ProductAutomaton. This function will also check the range
* argument.
*
* Argument: index -- Index of a state of the product automaton.
*
* Returns: A reference to the corresponding product state.
*
* ------------------------------------------------------------------------- */
{
return static_cast<ProductState&>(Graph<GraphEdgeContainer>::node(index));
}
/* ========================================================================= */
inline StateSpace::size_type ProductAutomaton::systemState
(const size_type state) const
/* ----------------------------------------------------------------------------
*
* Description: Returns the identifier of the system state with which a
* given product state is associated. This function will perform
* no range checks on its argument.
*
* Argument: state -- Identifier of a product state.
*
* Returns: Identifier of a state in a state space.
*
* ------------------------------------------------------------------------- */
{
return operator[](state).hashValue() % statespace_size;
}
/* ========================================================================= */
inline StateSpace::size_type ProductAutomaton::buchiState
(const size_type state) const
/* ----------------------------------------------------------------------------
*
* Description: Returns the identifier of the state of the Büchi automaton
* with which a given product state is associated. This function
* will perform no range checks on its argument.
*
* Argument: state -- Identifier of a product state.
*
* Returns: Identifier of a state in a Büchi automaton.
*
* ------------------------------------------------------------------------- */
{
return operator[](state).hashValue() / statespace_size;
}
/******************************************************************************
*
* Inline function definitions for class ProductAutomaton::ProductState.
*
*****************************************************************************/
/* ========================================================================= */
inline ProductAutomaton::ProductState::ProductState(const size_type hash_val) :
Graph<GraphEdgeContainer>::Node(), hash_value(hash_val), incoming_edge(0)
/* ----------------------------------------------------------------------------
*
* Description: Constructor for class ProductAutomaton::ProductState. Creates
* a new object representing a synchronous product of a state of
* a Büchi automaton with a state of a state space.
*
* Arguments: hash_val -- Hash value for the product state.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
inline ProductAutomaton::ProductState::~ProductState()
/* ----------------------------------------------------------------------------
*
* Description: Destructor for class ProductAutomaton::ProductState.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
if (incoming_edge != 0)
{
#ifdef HAVE_OBSTACK_H
incoming_edge->~Edge();
#else
delete incoming_edge;
#endif /* HAVE_OBSTACK_H */
}
outgoing_edges.clear();
}
/* ========================================================================= */
inline ProductAutomaton::size_type ProductAutomaton::ProductState::hashValue()
const
/* ----------------------------------------------------------------------------
*
* Description: Returns the product state's hash value by value.
*
* Arguments: None.
*
* Returns: The hash value of the product state.
*
* ------------------------------------------------------------------------- */
{
return hash_value;
}
/* ========================================================================= */
inline ProductAutomaton::size_type& ProductAutomaton::ProductState::hashValue()
/* ----------------------------------------------------------------------------
*
* Description: Returns the product state's hash value by reference. (This
* function can therefore be used to change the value.)
*
* Arguments: None.
*
* Returns: A reference to the hash value of the product state.
*
* ------------------------------------------------------------------------- */
{
return hash_value;
}
/******************************************************************************
*
* Inline function definitions for class ProductAutomaton::ProductScc.
*
*****************************************************************************/
/* ========================================================================= */
inline ProductAutomaton::ProductScc::ProductScc()
/* ----------------------------------------------------------------------------
*
* Description: Constructor for class ProductAutomaton::ProductScc. Creates a
* new container for storing a maximal strongly connected
* component of a ProductAutomaton.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
inline ProductAutomaton::ProductScc::~ProductScc()
/* ----------------------------------------------------------------------------
*
* Description: Destructor for class ProductAutomaton::ProductScc.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
inline void ProductAutomaton::ProductScc::insert
(const ProductAutomaton::size_type product_state)
/* ----------------------------------------------------------------------------
*
* Description: Inserts a new product state identifier to the container.
*
* Argument: product_state -- Identifier of a product state.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
push_back(product_state);
}
/******************************************************************************
*
* Inline function definitions for class
* ProductAutomaton::ProductSizeException.
*
*****************************************************************************/
/* ========================================================================= */
inline ProductAutomaton::ProductSizeException::ProductSizeException() :
Exception("product may be too large")
/* ----------------------------------------------------------------------------
*
* Description: Constructor for class ProductAutomaton::ProductSizeException.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
inline ProductAutomaton::ProductSizeException::~ProductSizeException() throw()
/* ----------------------------------------------------------------------------
*
* Description: Destructor for class ProductAutomaton::ProductSizeException.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
inline ProductAutomaton::ProductSizeException&
ProductAutomaton::ProductSizeException::operator=
(const ProductAutomaton::ProductSizeException& e)
/* ----------------------------------------------------------------------------
*
* Description: Assignment operator for class
* ProductAutomaton::ProductSizeException. Assigns the value of
* another ProductAutomaton::ProductSizeException to `this' one.
*
* Arguments: e -- A reference to a constant
* ProductAutomaton::ProductSizeException.
*
* Returns: A reference to the object whose value was changed.
*
* ------------------------------------------------------------------------- */
{
Exception::operator=(e);
return *this;
}
}
#endif /* !PRODUCTAUTOMATON_H */

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -195,10 +195,8 @@ public:
/* default assignment operator */
typedef set<typename GraphType::size_type, /* Type definition for */
less<typename GraphType::size_type>, /* a set of node id's. */
ALLOC(typename GraphType::size_type) >
SccType;
typedef set<typename GraphType::size_type> /* Type definition for */
SccType; /* a set of node id's. */
const SccType& operator()() const; /* Returns the set of node
* identifiers in a
@ -338,10 +336,10 @@ public:
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
typedef map<typename GraphType::size_type, /* Type definition for a */
typename GraphType::size_type, /* mapping between node */
less<typename GraphType::size_type>, /* identifiers and the */
ALLOC(typename GraphType::size_type) >/* order in which they */
DfsOrdering; /* were encountered in
typename GraphType::size_type> /* mapping between node */
DfsOrdering; /* identifiers and the
* order in which they
* were encountered in
* the search for
* strongly connected
* components.
@ -433,18 +431,19 @@ public:
typename GraphType::size_type lowlink;
};
deque<NodeStackElement, /* Depth-first search */
ALLOC(NodeStackElement) > /* backtracking stack. */
node_stack;
deque<NodeStackElement> node_stack; /* Depth-first search
* backtracking stack.
*/
NodeStackElement* current_node; /* Pointer to the top
* element of the
* backtracking stack.
*/
deque<typename GraphType::size_type, /* Stack used for */
ALLOC(typename GraphType::size_type) > /* collecting the nodes */
scc_stack; /* in a strongly
deque<typename GraphType::size_type> scc_stack; /* Stack used for
* collecting the nodes
* in a strongly
* connected component,
* excluding the root
* nodes of the
@ -998,8 +997,7 @@ void SccCollection<GraphType, NodeVisitor>::iterator::getPath
* when exiting from this function).
*/
typename deque<NodeStackElement, ALLOC(NodeStackElement) >::const_iterator
n = node_stack.begin();
typename deque<NodeStackElement>::const_iterator n = node_stack.begin();
if (n != node_stack.end())
{
for (++n; n != node_stack.end(); ++n)

752
lbtt/src/SccIterator.h Normal file
View file

@ -0,0 +1,752 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
*
* This program 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.
*
* This program 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, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef SCCITERATOR_H
#define SCCITERATOR_H
#include <config.h>
#include <deque>
#include <set>
#include <stack>
#include <vector>
#include "LbttAlloc.h"
#include "Graph.h"
using namespace std;
namespace Graph
{
/******************************************************************************
*
* A template iterator class for computing the maximal strongly connected
* components of a graph represented as an object of class
* Graph<EdgeContainer>.
*
* The iterator class has three template arguments:
* class EdgeContainer -- Container class storing the edges in the
* graph with which the iterator is associated.
*
* class SccContainer -- Container for storing the identifiers of the
* nodes belonging to some maximal strongly
* connected component. The container class
* must be able to store elements of type
* Graph<EdgeContainer>::size_type. The container
* class interface must support the following
* operations:
*
* Default constructor which can be called
* without any arguments
* Copy constructor
* Assignment operator
* clear()
* [makes the container empty]
* insert(Graph<EdgeContainer>::size_type s)
* [inserts an element into the
* container]
*
* If the container class is left unspecified,
* it defaults to
* set<Graph<EdgeContainer>::size_type,
* less<Graph<EdgeContainer>::size_type>,
* ALLOC(Graph<EdgeContainer>::size_type)>.
*
* class Filter -- Class for representing function objects that
* can be used to restrict the iterator
* dereferencing operators to return only
* those nodes of a strongly connected component
* which satisfy a certain condition that can be
* tested using Filter::operator(). This function
* has to accept a single parameter of type
* Graph<EdgeContainer>::Node*. It must return a
* Boolean value. The nodes for which the
* function returns `false' will then not be
* included in the collection of nodes returned
* by the iterator dereferencing operators.
*
* If the Filter class is left unspecified, it
* defaults to the NullSccFilter<EdgeContainer>
* class, which does not restrict the set of
* nodes in any way.
*
*****************************************************************************/
template<class EdgeContainer>
class NullSccFilter;
template<class EdgeContainer,
class SccContainer
= set<typename Graph<EdgeContainer>::size_type,
less<typename Graph<EdgeContainer>::size_type>,
ALLOC(typename Graph<EdgeContainer>::size_type) >,
class Filter = NullSccFilter<EdgeContainer> >
class SccIterator
{
public:
SccIterator(const Graph<EdgeContainer>& g); /* Constructor. */
/* default copy constructor */
~SccIterator(); /* Destructor. */
/* default assignment operator */
bool operator== /* Equality test for */
(const SccIterator<EdgeContainer, /* two iterators. */
SccContainer,
Filter>& it) const;
bool operator!= /* Inequality test for */
(const SccIterator<EdgeContainer, /* two iterators. */
SccContainer,
Filter>& it) const;
bool operator< /* `Less than' relation */
(const SccIterator<EdgeContainer, /* between two */
SccContainer, /* iterators. */
Filter>& it) const;
bool operator<= /* `Less than or equal' */
(const SccIterator<EdgeContainer, /* relation between two */
SccContainer, /* iterators. */
Filter>& it) const;
bool operator> /* `Greater than' */
(const SccIterator<EdgeContainer, /* relation between two */
SccContainer, /* iterators. */
Filter>& it) const;
bool operator>= /* `Greater than or */
(const SccIterator<EdgeContainer, /* equal' relation */
SccContainer, /* between two */
Filter>& it) const; /* iterators. */
const SccContainer& operator*() const; /* Dereferencing */
const SccContainer* operator->() const; /* operators. */
const SccContainer& operator++(); /* Prefix and postfix */
const SccContainer operator++(int); /* increment operators. */
bool atEnd() const; /* Tests whether the
* iterator has scanned
* through all the
* strongly connected
* components of the
* graph.
*/
private:
const Graph<EdgeContainer>& graph; /* Reference to the graph
* with which the iterator
* is associated.
*/
typename Graph<EdgeContainer>::size_type /* Number of graph */
dfs_number; /* nodes processed by
* the iterator.
*/
vector<typename Graph<EdgeContainer>::size_type, /* dfs_ordering[i] */
ALLOC(typename Graph<EdgeContainer> /* indicates the */
::size_type) > /* position of graph */
dfs_ordering; /* node i in the depth-
* first search order.
* (If the node has not
* yet been visited,
* dfs_ordering[i]==0.)
*/
vector<typename Graph<EdgeContainer>::size_type, /* lowlink[i] indicates */
ALLOC(typename Graph<EdgeContainer> /* the least graph node */
::size_type) > /* (in the depth-first */
lowlink; /* search order) that
* is reachable from
* graph node i and
* does not belong to
* any strongly
* connected component
* which has already been
* processed.
*/
typedef pair<typename Graph<EdgeContainer>::size_type,
typename EdgeContainer::const_iterator>
NodeStackElement;
stack<NodeStackElement, /* Depth-first search */
deque<NodeStackElement, /* backtracking stack. */
ALLOC(NodeStackElement) > >
node_stack;
typename Graph<EdgeContainer>::size_type /* Current graph node */
current_node; /* the depth-first
* search.
*/
typename EdgeContainer::const_iterator edge; /* Iterator to scan
* through the successors
* of the current node.
*/
stack<typename Graph<EdgeContainer>::size_type, /* Stack used for */
deque<typename Graph<EdgeContainer> /* collecting the nodes */
::size_type, /* in a strongly */
ALLOC(typename Graph<EdgeContainer> /* connected component. */
::size_type)
>
>
scc_stack;
SccContainer current_scc; /* Container of nodes
* forming the maximal
* strongly connected
* graph component
* currently `pointed to'
* by the iterator.
*/
Filter cond; /* Function object for
* filtering out a subset
* of nodes in the
* strongly connected
* components.
*/
void reset(); /* Initializes the
* iterator to point to
* the first strongly
* connected component of
* the graph.
*/
void computeNextScc(); /* Updates the iterator to
* point to the next
* strongly connected
* component.
*/
};
/******************************************************************************
*
* Default test for collecting the nodes in a strongly connected component.
* (See documentation on class SccIterator for information about the purpose
* of the class.)
*
*****************************************************************************/
template<class EdgeContainer>
class NullSccFilter
{
public:
bool operator()(const typename Graph<EdgeContainer>::Node*) const;
};
/******************************************************************************
*
* Inline function definitions for template class
* SccIterator<EdgeContainer, SccContainer, Filter>.
*
*****************************************************************************/
/* ========================================================================= */
template<class EdgeContainer, class SccContainer, class Filter>
inline SccIterator<EdgeContainer, SccContainer, Filter>::SccIterator
(const Graph<EdgeContainer>& g) :
graph(g), dfs_ordering(graph.size()), lowlink(graph.size())
/* ----------------------------------------------------------------------------
*
* Description: Constructor for class
* SccIterator<EdgeContainer, SccContainer, Filter>.
* Initializes a new iterator for scanning the maximal strongly
* connected components of a graph.
*
* Arguments: g -- The graph with which the iterator is to be associated
* (a Graph<EdgeContainer> object).
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
reset();
computeNextScc();
}
/* ========================================================================= */
template<class EdgeContainer, class SccContainer, class Filter>
inline SccIterator<EdgeContainer, SccContainer, Filter>::~SccIterator()
/* ----------------------------------------------------------------------------
*
* Description: Destructor for class
* SccIterator<EdgeContainer, SccContainer, Filter>.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
template<class EdgeContainer, class SccContainer, class Filter>
inline bool SccIterator<EdgeContainer, SccContainer, Filter>::operator==
(const SccIterator<EdgeContainer, SccContainer, Filter>& it) const
/* ----------------------------------------------------------------------------
*
* Description: Equality test for two SccIterators. Two SccIterators are
* `equal' if and only if both of them are associated with
* exactly the same graph object in memory and the iterators
* have processed the same amount of graph nodes.
*
* Arguments: it -- A constant reference to another SccIterator.
*
* Returns: A truth value according to the result of the equality test.
*
* ------------------------------------------------------------------------- */
{
return (&graph == &(it.graph) && dfs_number == it.dfs_number);
}
/* ========================================================================= */
template<class EdgeContainer, class SccContainer, class Filter>
inline bool SccIterator<EdgeContainer, SccContainer, Filter>::operator!=
(const SccIterator<EdgeContainer, SccContainer, Filter>& it) const
/* ----------------------------------------------------------------------------
*
* Description: Inequality test for two SccIterators. Two SccIterators are
* not equal if and only if they are associated with different
* graphs or they are associated with the same graph object in
* memory but the iterators have processed a different number of
* graph nodes.
*
* Arguments: it -- A constant reference to another SccIterator.
*
* Returns: A truth value according to the result of the inequality test.
*
* ------------------------------------------------------------------------- */
{
return (&graph != &(it.graph) || dfs_number != it.dfs_number);
}
/* ========================================================================= */
template<class EdgeContainer, class SccContainer, class Filter>
inline bool SccIterator<EdgeContainer, SccContainer, Filter>::operator<
(const SccIterator<EdgeContainer, SccContainer, Filter>& it) const
/* ----------------------------------------------------------------------------
*
* Description: `Less than' relation between two SccIterators. An
* SccIterator is `less than' another if and only if the
* iterators relate to the same graph object in memory and
* the first iterator has processed a smaller number of nodes
* than the second one.
*
* Arguments: it -- A constant reference to another SccIterator.
*
* Returns: A truth value according to the result of the test.
*
* ------------------------------------------------------------------------- */
{
return (&graph == &(it.graph) && dfs_number < it.dfs_number);
}
/* ========================================================================= */
template<class EdgeContainer, class SccContainer, class Filter>
inline bool SccIterator<EdgeContainer, SccContainer, Filter>::operator<=
(const SccIterator<EdgeContainer, SccContainer, Filter>& it) const
/* ----------------------------------------------------------------------------
*
* Description: `Less than or equal' relation between two SccIterators. An
* SccIterator is `less than or equal to' another if and only
* if the iterators relate to the same graph object in memory
* and the first iterator has processed a number of nodes not
* exceeding the number of nodes the second iterator has
* processed.
*
* Arguments: it -- A constant reference to another SccIterator.
*
* Returns: A truth value according to the result of the test.
*
* ------------------------------------------------------------------------- */
{
return (&graph == &(it.graph) && dfs_number <= it.dfs_number);
}
/* ========================================================================= */
template<class EdgeContainer, class SccContainer, class Filter>
inline bool SccIterator<EdgeContainer, SccContainer, Filter>::operator>
(const SccIterator<EdgeContainer, SccContainer, Filter>& it) const
/* ----------------------------------------------------------------------------
*
* Description: `Greater than' relation between two SccIterators. An
* SccIterator is `greater than' another if and only if the
* iterators relate to the same graph object in memory and
* the first iterator has processed a greater number of nodes
* than the second one.
*
* Arguments: it -- A constant reference to another SccIterator.
*
* Returns: A truth value according to the result of the test.
*
* ------------------------------------------------------------------------- */
{
return (&graph == &(it.graph) && dfs_number > it.dfs_number);
}
/* ========================================================================= */
template<class EdgeContainer, class SccContainer, class Filter>
inline bool SccIterator<EdgeContainer, SccContainer, Filter>::operator>=
(const SccIterator<EdgeContainer, SccContainer, Filter>& it) const
/* ----------------------------------------------------------------------------
*
* Description: `Greater than or equal' relation between two SccIterators. An
* SccIterator is `greater than or equal to' another if and
* only if the iterators relate to the same graph object in
* memory and the first iterator has processed at least as many
* nodes as the second iterator has processed.
*
* Arguments: it -- A constant reference to another SccIterator.
*
* Returns: A truth value according to the result of the test.
*
* ------------------------------------------------------------------------- */
{
return (&graph == &(it.graph) && dfs_number >= it.dfs_number);
}
/* ========================================================================= */
template<class EdgeContainer, class SccContainer, class Filter>
inline const SccContainer&
SccIterator<EdgeContainer, SccContainer, Filter>::operator*() const
/* ----------------------------------------------------------------------------
*
* Description: Dereferencing operator for a SccIterator. Returns the
* collection of nodes which belong to the maximal strongly
* connected component that the iterator currently points to.
*
* Arguments: None.
*
* Returns: A collection of nodes representing some maximal strongly
* connected component.
*
* ------------------------------------------------------------------------- */
{
return current_scc;
}
/* ========================================================================= */
template<class EdgeContainer, class SccContainer, class Filter>
inline const SccContainer*
SccIterator<EdgeContainer, SccContainer, Filter>::operator->() const
/* ----------------------------------------------------------------------------
*
* Description: Dereferencing operator for a SccIterator. Returns the
* collection of nodes which belong to the maximal strongly
* connected component that the iterator currently points to.
*
* Arguments: None.
*
* Returns: A collection of nodes representing some maximal strongly
* connected component.
*
* ------------------------------------------------------------------------- */
{
return &current_scc;
}
/* ========================================================================= */
template<class EdgeContainer, class SccContainer, class Filter>
inline const SccContainer&
SccIterator<EdgeContainer, SccContainer, Filter>::operator++()
/* ----------------------------------------------------------------------------
*
* Description: Prefix increment operator for a SccIterator. Computes the
* next maximal strongly connected component of the graph and
* then returns it.
*
* Arguments: None.
*
* Returns: A collection of nodes representing some maximal strongly
* connected component.
*
* ------------------------------------------------------------------------- */
{
computeNextScc();
return current_scc;
}
/* ========================================================================= */
template<class EdgeContainer, class SccContainer, class Filter>
inline const SccContainer
SccIterator<EdgeContainer, SccContainer, Filter>::operator++(int)
/* ----------------------------------------------------------------------------
*
* Description: Postfix increment operator for a SccIterator. Effectively
* returns the maximal strongly connected component of the graph
* currently pointed to by the iterator and then updates the
* iterator to point to the next strongly connected component.
*
* Arguments: None (the `int' is only required to distinguish this operator
* from the prefix increment operator).
*
* Returns: A collection of nodes representing some maximal strongly
* connected component.
*
* ------------------------------------------------------------------------- */
{
SccContainer old_scc = current_scc;
computeNextScc();
return old_scc;
}
/* ========================================================================= */
template<class EdgeContainer, class SccContainer, class Filter>
inline bool SccIterator<EdgeContainer, SccContainer, Filter>::atEnd() const
/* ----------------------------------------------------------------------------
*
* Description: Tells whether there are still more strongly connected
* components in the graph for the iterator to process.
*
* Arguments: None.
*
* Returns: A truth value.
*
* ------------------------------------------------------------------------- */
{
return (current_node == graph.size());
}
/******************************************************************************
*
* Function definitions for template class
* SccIterator<EdgeContainer, SccContainer, Filter>.
*
*****************************************************************************/
/* ========================================================================= */
template<class EdgeContainer, class SccContainer, class Filter>
void SccIterator<EdgeContainer, SccContainer, Filter>::reset()
/* ----------------------------------------------------------------------------
*
* Description: Initializes the iterator to point to the first maximal
* strongly connected component of the graph with which the
* iterator it associated.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
dfs_number = 0;
for (typename vector<typename Graph<EdgeContainer>::size_type,
ALLOC(typename Graph<EdgeContainer>::size_type) >
::iterator node = dfs_ordering.begin();
node != dfs_ordering.end();
++node)
*node = 0;
while (!node_stack.empty())
node_stack.pop();
while (!scc_stack.empty())
scc_stack.pop();
current_scc.clear();
}
/* ========================================================================= */
template<class EdgeContainer, class SccContainer, class Filter>
void SccIterator<EdgeContainer, SccContainer, Filter>::computeNextScc()
/* ----------------------------------------------------------------------------
*
* Description: Updates the state of the iterator to `point to' the next
* maximal strongly connected component of the graph, using the
* algorithm due to Tarjan [R. Tarjan. Depth-first search and
* linear graph algorithms. SIAM Journal on Computing,
* 1(2):146--160, June 1972] for computing the next maximal
* strongly connected component of the graph.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
current_scc.clear();
if (scc_stack.empty() && node_stack.empty())
{
/*
* If both `scc_stack' and `node_stack' are empty (this holds if we have
* recently finished processing some component of the graph), try to find
* a graph node that has not yet been visited. If no such node is found,
* all nodes have been visited and there are no more strongly connected
* components to be found in the graph.
*/
current_node = 0;
for (typename vector<typename Graph<EdgeContainer>::size_type,
ALLOC(typename Graph<EdgeContainer>::size_type) >
::const_iterator node = dfs_ordering.begin();
node != dfs_ordering.end() && (*node) != 0;
++node)
++current_node;
if (current_node == graph.size())
return;
/*
* Prepare to continue the depth-first search in the unvisited node.
*/
edge = graph[current_node].edges().begin();
scc_stack.push(current_node);
++dfs_number;
dfs_ordering[current_node] = lowlink[current_node] = dfs_number;
}
typename Graph<EdgeContainer>::size_type child_node;
while (1)
{
/*
* If there are still nodes left in the depth-first search backtracking
* stack, pop a node and its next unprocessed outgoing edge off the stack.
* Before continuing the depth-first search in the popped node, update
* its lowlink value if necessary. (This has to be done if the lowlink of
* the current node---a successor of the popped node---is less than the
* lowlink of the popped node but not equal to zero.)
*/
if (!node_stack.empty())
{
typename Graph<EdgeContainer>::size_type father_node
= node_stack.top().first;
edge = node_stack.top().second;
node_stack.pop();
if (lowlink[current_node] < lowlink[father_node]
&& lowlink[current_node] != 0)
lowlink[father_node] = lowlink[current_node];
current_node = father_node;
}
/*
* Scan through the successors of the current node.
*
* If the current nodes has an unvisited successor node (a successor i
* with dfs_ordering[i] == 0), push the current node and its next
* unprocessed edge onto the backtracking stack and then continue the
* search in the successor node. Push also the successor node onto the
* strongly connected component stack.
*
* Otherwise, update the lowlink of the current node to the lowlink of
* its already visited successor if necessary.
*/
while (edge != graph[current_node].edges().end())
{
child_node = (*edge)->targetNode();
++edge;
if (dfs_ordering[child_node] == 0)
{
node_stack.push(make_pair(current_node, edge));
scc_stack.push(child_node);
++dfs_number;
dfs_ordering[child_node] = lowlink[child_node] = dfs_number;
current_node = child_node;
edge = graph[current_node].edges().begin();
}
else if (lowlink[child_node] < lowlink[current_node]
&& lowlink[child_node] != 0)
lowlink[current_node] = lowlink[child_node];
}
/*
* If the least node in the depth-first search order reachable from the
* current node is the current node itself at the end of the previous
* loop, we have found a maximal strongly connected component of the
* graph. In this case, collect the states satisfying `cond' in the
* strongly connected component stack to form the component and exit.
* (Otherwise, return to the start of the outermost while loop and
* continue by popping a state off the depth-first search backtracking
* stack.)
*/
if (dfs_ordering[current_node] == lowlink[current_node])
{
do
{
child_node = scc_stack.top();
scc_stack.pop();
if (cond(&graph[child_node]))
current_scc.insert(child_node);
lowlink[child_node] = 0;
}
while (child_node != current_node);
break;
}
}
}
/******************************************************************************
*
* Inline function definitions for template class NullSccFilter<EdgeContainer>.
*
*****************************************************************************/
/* ========================================================================= */
template<class EdgeContainer>
inline bool NullSccFilter<EdgeContainer>::operator()
(const typename Graph<EdgeContainer>::Node*) const
/* ----------------------------------------------------------------------------
*
* Description: Default test for filtering the nodes in a strongly connected
* graph component. The default is to simply include all nodes
* in the result.
*
* Arguments: A constant pointer to a Graph<EdgeContainer>::Node (required
* only to satisfy the class interface requirements).
*
* Returns: true, so the test will succeed for every node in the
* component.
*
* ------------------------------------------------------------------------- */
{
return true;
}
}
#endif /* !SCCITERATOR_H */

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -42,14 +42,14 @@ extern TestRoundInfo round_info; /* Data structure for
* round.
*/
extern vector<AlgorithmTestResults, /* Test results for each */
ALLOC(AlgorithmTestResults) > /* implementation. */
test_results;
extern vector<TestStatistics, /* Overall test */
ALLOC(TestStatistics) > /* statistics for each */
final_statistics; /* implementation. */
extern vector<AlgorithmTestResults> test_results; /* Test results for each
* implementation.
*/
extern vector<TestStatistics> final_statistics; /* Overall test
* statistics for each
* implementation.
*/
}
#endif /* !SHAREDTESTDATA_H */

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -17,10 +17,6 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifdef __GNUC__
#pragma implementation
#endif /* __GNUC__ */
#include <config.h>
#ifdef HAVE_SSTREAM
#include <sstream>

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -20,10 +20,6 @@
#ifndef SPINWRAPPER_H
#define SPINWRAPPER_H
#ifdef __GNUC__
#pragma interface
#endif /* __GNUC__ */
#include <config.h>
#include <string>
#include "ExternalTranslator.h"

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -17,14 +17,11 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifdef __GNUC__
#pragma implementation
#endif /* __GNUC__ */
#include <config.h>
#include <string>
#include "DispUtil.h"
#include "Exception.h"
#include "IntervalList.h"
#include "SharedTestData.h"
#include "StatDisplay.h"
#include "StringUtil.h"
@ -37,11 +34,51 @@ using namespace ::DispUtil;
using namespace ::SharedTestData;
using namespace ::StringUtil;
/* ========================================================================= */
void printStatTableHeader(ostream& stream, int indent)
/* ----------------------------------------------------------------------------
*
* Description: Displays a table header for test statistics (used in
* verbosity mode 2).
*
* Arguments: stream -- A reference to the output stream to which the
* header should be written.
* indent -- Number of spaces to leave on the left of the
* output.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
Exceptional_ostream estream(&stream, ios::failbit | ios::badbit);
int num_dashes = 39;
estream << string(indent, ' ') + " # F Elapsed Büchi Büchi Acc.";
if (configuration.global_options.do_cons_test
|| configuration.global_options.do_comp_test)
{
num_dashes += 31;
estream << " Product Product Acc.";
if (configuration.global_options.do_cons_test)
{
num_dashes += 3;
estream << " CC";
}
}
estream << '\n' + string(indent + 10, ' ')
+ "time states trans. sets";
if (configuration.global_options.do_cons_test
|| configuration.global_options.do_comp_test)
estream << " states trans. cycles";
estream << "\n" + string(indent, ' ') + string(num_dashes, '-') + '\n';
estream.flush();
}
/* ========================================================================= */
void printBuchiAutomatonStats
(ostream& stream, int indent,
vector<AlgorithmTestResults, ALLOC(AlgorithmTestResults) >::size_type
algorithm,
vector<AlgorithmTestResults>::size_type algorithm,
int result_id)
/* ----------------------------------------------------------------------------
*
@ -52,7 +89,7 @@ void printBuchiAutomatonStats
* Arguments: stream -- A reference to the output stream to which the
* information should be written.
* indent -- Number of spaces to leave on the left of the
* output.
* output in verbosity modes >= 3.
* algorithm -- Identifier of the algorithm used for
* generating the automaton.
* result_id -- Selects between the automata constructed from
@ -67,43 +104,75 @@ void printBuchiAutomatonStats
const AutomatonStats& automaton_stats =
test_results[algorithm].automaton_stats[result_id];
estream << string(indent, ' ');
if (!automaton_stats.buchiAutomatonComputed())
estream << "not computed";
if (configuration.global_options.verbosity <= 2)
{
if (!automaton_stats.buchiAutomatonComputed())
estream << " N/A N/A N/A N/A";
else
{
if (automaton_stats.buchi_generation_time >= 0.0)
{
changeStreamFormatting(stream, 9, 2, ios::fixed | ios::right);
estream << automaton_stats.buchi_generation_time;
restoreStreamFormatting(stream);
}
else
estream << " N/A";
estream << ' ';
changeStreamFormatting(stream, 9, 0, ios::right);
estream << automaton_stats.number_of_buchi_states;
restoreStreamFormatting(stream);
estream << ' ';
changeStreamFormatting(stream, 9, 0, ios::right);
estream << automaton_stats.number_of_buchi_transitions;
restoreStreamFormatting(stream);
estream << ' ';
changeStreamFormatting(stream, 4, 0, ios::right);
estream << automaton_stats.number_of_acceptance_sets;
restoreStreamFormatting(stream);
}
estream << ' ';
}
else
{
estream << "number of states:" + string(6, ' ')
+ toString(automaton_stats.number_of_buchi_states)
+ '\n' + string(indent, ' ') + "number of transitions: "
+ toString(automaton_stats.number_of_buchi_transitions)
+ '\n' + string(indent, ' ') + "acceptance sets:"
+ string(7, ' ')
+ toString(automaton_stats.number_of_acceptance_sets)
+ '\n' + string(indent, ' ') + "computation time:"
+ string(6, ' ');
if (automaton_stats.buchi_generation_time != -1.0)
{
changeStreamFormatting(stream, 9, 2, ios::fixed | ios::left);
estream << automaton_stats.buchi_generation_time;
restoreStreamFormatting(stream);
estream << string(indent, ' ');
estream << " seconds (user time)";
}
if (!automaton_stats.buchiAutomatonComputed())
estream << "not computed";
else
estream << "N/A";
{
estream << "number of states:" + string(6, ' ')
+ toString(automaton_stats.number_of_buchi_states)
+ '\n' + string(indent, ' ') + "number of transitions: "
+ toString(automaton_stats.number_of_buchi_transitions)
+ '\n' + string(indent, ' ') + "acceptance sets:"
+ string(7, ' ')
+ toString(automaton_stats.number_of_acceptance_sets)
+ '\n' + string(indent, ' ') + "computation time:"
+ string(6, ' ');
if (automaton_stats.buchi_generation_time != -1.0)
{
changeStreamFormatting(stream, 9, 2, ios::fixed | ios::left);
estream << automaton_stats.buchi_generation_time;
restoreStreamFormatting(stream);
estream << " seconds (user time)";
}
else
estream << "N/A";
}
estream << '\n';
}
estream << '\n';
estream.flush();
}
/* ========================================================================= */
void printProductAutomatonStats
(ostream& stream, int indent,
vector<AlgorithmTestResults, ALLOC(AlgorithmTestResults) >::size_type
algorithm,
vector<AlgorithmTestResults>::size_type algorithm,
int result_id)
/* ----------------------------------------------------------------------------
*
@ -114,7 +183,7 @@ void printProductAutomatonStats
* Arguments: stream -- A reference to the output stream to which the
* information should be written.
* indent -- Number of spaces to leave on the left of the
* output.
* output in verbosity modes >= 3.
* algorithm -- Identifier of the algorithm used for
* generating the product automaton.
* result_id -- Selects between the automata constructed from
@ -129,51 +198,71 @@ void printProductAutomatonStats
const AutomatonStats& automaton_stats =
test_results[algorithm].automaton_stats[result_id];
estream << string(indent, ' ');
if (!automaton_stats.productAutomatonComputed())
estream << "not computed";
if (configuration.global_options.verbosity <= 2)
{
if (!automaton_stats.productAutomatonComputed())
estream << " N/A N/A";
else
{
changeStreamFormatting(stream, 11, 0, ios::right);
estream << automaton_stats.number_of_product_states;
restoreStreamFormatting(stream);
estream << ' ';
changeStreamFormatting(stream, 11, 0, ios::right);
estream << automaton_stats.number_of_product_transitions;
restoreStreamFormatting(stream);
}
estream << ' ';
}
else
{
estream << "number of states:" + string(6, ' ');
estream << string(indent, ' ');
changeStreamFormatting(stream, 9, 0, ios::left);
estream << automaton_stats.number_of_product_states;
restoreStreamFormatting(stream);
estream << " [";
if (automaton_stats.number_of_product_states != 0)
if (!automaton_stats.productAutomatonComputed())
estream << "not computed";
else
{
changeStreamFormatting(stream, 0, 2, ios::fixed);
estream << static_cast<double>
(automaton_stats.number_of_product_states)
/ static_cast<double>(automaton_stats.number_of_buchi_states)
/ static_cast<double>(round_info.statespace->size())
* 100.0;
estream << "number of states:" + string(6, ' ');
changeStreamFormatting(stream, 9, 0, ios::left);
estream << automaton_stats.number_of_product_states;
restoreStreamFormatting(stream);
estream << "% of worst case ("
<< automaton_stats.number_of_buchi_states
* round_info.statespace->size()
<< ')';
}
else
estream << "empty automaton";
estream << " [";
estream << "]\n" + string(indent, ' ') + "number of transitions: "
+ toString(automaton_stats.number_of_product_transitions);
if (automaton_stats.number_of_product_states != 0)
{
changeStreamFormatting(stream, 0, 2, ios::fixed);
estream << static_cast<double>
(automaton_stats.number_of_product_states)
/ static_cast<double>
(automaton_stats.number_of_buchi_states)
/ static_cast<double>(round_info.statespace->size())
* 100.0;
restoreStreamFormatting(stream);
estream << "% of worst case ("
<< automaton_stats.number_of_buchi_states
* round_info.statespace->size()
<< ')';
}
else
estream << "empty automaton";
estream << "]\n" + string(indent, ' ') + "number of transitions: "
+ toString(automaton_stats.number_of_product_transitions);
}
estream << '\n';
}
estream << '\n';
estream.flush();
}
/* ========================================================================= */
void printAcceptanceCycleStats
(ostream& stream, int indent,
vector<AlgorithmTestResults, ALLOC(AlgorithmTestResults) >::size_type
algorithm,
vector<AlgorithmTestResults>::size_type algorithm,
int result_id)
/* ----------------------------------------------------------------------------
*
@ -185,7 +274,7 @@ void printAcceptanceCycleStats
* Arguments: stream -- A reference to the output stream to which the
* information should be written.
* indent -- Number of spaces to leave on the left of the
* output.
* output in verbosity mode >= 3.
* algorithm -- Identifier of the algorithm used for
* computing the Büchi automaton whose accepting
* cycles are to be considered.
@ -201,49 +290,64 @@ void printAcceptanceCycleStats
const AutomatonStats& automaton_stats =
test_results[algorithm].automaton_stats[result_id];
estream << string(indent, ' ');
if (!automaton_stats.emptiness_check_performed)
estream << "not computed";
else if (configuration.global_options.product_mode == Configuration::LOCAL)
if (configuration.global_options.verbosity <= 2)
{
estream << string("cycle ");
if (automaton_stats.emptiness_check_result[0])
estream << "reachable ";
if (!automaton_stats.emptiness_check_performed)
estream << " N/A";
else
estream << "not reachable";
estream << " (from the initial state)";
{
changeStreamFormatting(stream, 6, 0, ios::right);
estream << automaton_stats.emptiness_check_result.count();
restoreStreamFormatting(stream);
}
estream << ' ';
}
else
{
estream << "cycle reachable from ";
estream << string(indent, ' ');
changeStreamFormatting(stream, 9, 0, ios::left);
estream << automaton_stats.emptiness_check_result.count();
restoreStreamFormatting(stream);
if (!automaton_stats.emptiness_check_performed)
estream << "not computed";
else if (configuration.global_options.product_mode == Configuration::LOCAL)
{
estream << string("cycle ");
estream << " states\n" + string(indent, ' ')
+ "not reachable from ";
if (automaton_stats.emptiness_check_result[0])
estream << "reachable ";
else
estream << "not reachable";
changeStreamFormatting(stream, 9, 0, ios::left);
estream << (round_info.real_emptiness_check_size
- automaton_stats.emptiness_check_result.count());
restoreStreamFormatting(stream);
estream << " (from the initial state)";
}
else
{
estream << "cycle reachable from ";
estream << " states";
changeStreamFormatting(stream, 9, 0, ios::left);
estream << automaton_stats.emptiness_check_result.count();
restoreStreamFormatting(stream);
estream << " states\n" + string(indent, ' ')
+ "not reachable from ";
changeStreamFormatting(stream, 9, 0, ios::left);
estream << (round_info.real_emptiness_check_size
- automaton_stats.emptiness_check_result.count());
restoreStreamFormatting(stream);
estream << " states";
}
estream << '\n';
}
estream << '\n';
estream.flush();
}
/* ========================================================================= */
void printConsistencyCheckStats
(ostream& stream, int indent,
vector<AlgorithmTestResults, ALLOC(AlgorithmTestResults) >::size_type
algorithm)
vector<AlgorithmTestResults>::size_type algorithm)
/* ----------------------------------------------------------------------------
*
* Description: Displays information about the consistency check result for
@ -253,7 +357,7 @@ void printConsistencyCheckStats
* Arguments: stream -- A reference to an output stream to which the
* information should be written.
* indent -- Number of spaces to leave on the left of the
* output.
* output in verbosity mode >= 3.
* algorithm -- Identifier of the algorithm whose consistency
* check result should be displayed.
*
@ -264,100 +368,113 @@ void printConsistencyCheckStats
Exceptional_ostream estream(&stream, ios::failbit | ios::badbit);
const AlgorithmTestResults& test_result = test_results[algorithm];
estream << string(indent, ' ');
if (configuration.global_options.verbosity <= 2)
{
switch (test_result.consistency_check_result)
{
case -1 :
estream << "NA";
break;
if (test_result.consistency_check_result == -1)
estream << "not performed";
case 0 :
estream << " F";
break;
default:
estream << " P";
break;
}
}
else
{
estream << "result:" + string(18, ' ');
estream << string(indent, ' ');
if (test_result.consistency_check_result == 0)
{
estream << "failed ["
+ toString(test_result.failed_consistency_check_comparisons)
+ " (";
changeStreamFormatting(stream, 0, 2, ios::fixed);
estream << ((test_result.consistency_check_comparisons == 0)
? 0.0
: static_cast<double>
(test_result.failed_consistency_check_comparisons)
/ test_result.consistency_check_comparisons * 100.0);
restoreStreamFormatting(stream);
estream << "%) of "
+ toString(test_result.consistency_check_comparisons)
+ " test cases]";
}
if (test_result.consistency_check_result == -1)
estream << "not performed";
else
estream << "passed";
{
estream << "result:" + string(18, ' ');
if (test_result.consistency_check_result == 0)
{
estream << "failed ["
+ toString(test_result.failed_consistency_check_comparisons)
+ " (";
changeStreamFormatting(stream, 0, 2, ios::fixed);
estream << ((test_result.consistency_check_comparisons == 0)
? 0.0
: static_cast<double>
(test_result.failed_consistency_check_comparisons)
/ test_result.consistency_check_comparisons * 100.0);
restoreStreamFormatting(stream);
estream << "%) of "
+ toString(test_result.consistency_check_comparisons)
+ " test cases]";
}
else
estream << "passed";
}
estream << '\n';
}
estream << '\n';
estream.flush();
}
/* ========================================================================= */
void printCrossComparisonStats
(ostream& stream, int indent,
vector<AlgorithmTestResults, ALLOC(AlgorithmTestResults) >::size_type
algorithm)
(ostream& stream, int indent, const IntervalList& algorithms)
/* ----------------------------------------------------------------------------
*
* Description: Displays information about the model checking result cross-
* comparison check, extracting the information from a vector of
* TestStatistics structures stored in the UserInterface object.
*
* Arguments: stream -- A reference to an output stream to which the
* information should be written.
* indent -- Number of spaces to leave on the left of the
* output.
* algorithm -- If less than the number of algorithms, show
* only the results for the algorithm with this
* identifier.
* Arguments: stream -- A reference to an output stream to which the
* information should be written.
* indent -- Number of spaces to leave on the left of the
* output.
* algorithms -- A reference to a constant IntervalList
* storing the numeric identifiers of the
* algorithms for which the statistics should
* be shown.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
Exceptional_ostream estream(&stream, ios::failbit | ios::badbit);
bool no_errors_to_report = true;
if (algorithm < configuration.algorithms.size()
&& !configuration.algorithms[algorithm].enabled)
{
estream << string(indent, ' ') + "not performed\n\n";
estream.flush();
return;
}
estream << string(indent, ' ') + "result:";
bool no_errors_to_report = true, nothing_to_report = true;
const AutomatonStats* alg_1_pos_results;
const AutomatonStats* alg_1_neg_results;
for (vector<AlgorithmTestResults, ALLOC(AlgorithmTestResults) >::size_type
alg_1 = 0;
alg_1 < test_results.size();
alg_1++)
for (IntervalList::const_iterator alg_1 = algorithms.begin();
alg_1 != algorithms.end();
++alg_1)
{
alg_1_pos_results = &test_results[alg_1].automaton_stats[0];
alg_1_neg_results = &test_results[alg_1].automaton_stats[1];
alg_1_pos_results = &test_results[*alg_1].automaton_stats[0];
alg_1_neg_results = &test_results[*alg_1].automaton_stats[1];
for (vector<AlgorithmTestResults, ALLOC(AlgorithmTestResults) >::size_type
alg_2 = alg_1 + 1;
alg_2 < test_results.size();
for (vector<AlgorithmTestResults>::size_type alg_2 = 0;
alg_2 < round_info.number_of_translators;
alg_2++)
{
if ((algorithm >= configuration.algorithms.size()
|| alg_1 == algorithm
|| alg_2 == algorithm)
&& configuration.algorithms[alg_1].enabled
if (*alg_1 != alg_2
&& (alg_2 > *alg_1 || !algorithms.covers(alg_2))
&& configuration.algorithms[*alg_1].enabled
&& configuration.algorithms[alg_2].enabled)
{
bool pos_test, neg_test;
if (nothing_to_report)
{
nothing_to_report = false;
estream << string(indent, ' ') + "result:";
}
for (int counter = 0; counter < 2; counter++)
{
if (counter == 0)
@ -385,89 +502,75 @@ void printCrossComparisonStats
else
estream << "-) ";
estream << ' ';
if (alg_1 == round_info.number_of_translators)
estream << "lbtt";
else
estream << configuration.algorithmString(alg_1);
estream << ", ";
if (alg_2 == round_info.number_of_translators)
estream << "lbtt";
else
estream << configuration.algorithmString(alg_2);
estream << " " + configuration.algorithmString(*alg_1) + ", "
+ configuration.algorithmString(alg_2);
}
}
}
}
}
if (no_errors_to_report)
if (nothing_to_report)
estream << string(indent, ' ') + "not performed";
else if (no_errors_to_report)
estream << string(20, ' ') + "no failures detected";
estream << "\n\n";
estream.flush();
}
/* ========================================================================= */
void printBuchiIntersectionCheckStats
(ostream& stream, int indent,
vector<AlgorithmTestResults, ALLOC(AlgorithmTestResults) >::size_type
algorithm)
(ostream& stream, int indent, const IntervalList& algorithms)
/* ----------------------------------------------------------------------------
*
* Description: Displays information about the Büchi automaton intersection
* emptiness check results, extracting the information from a
* TestStatistics structure stored in the UserInterface object.
*
* Arguments: stream -- A reference to an output stream to which the
* information should be written.
* indent -- Number of spaces to leave on the left of the
* output.
* algorithm -- If less than the number of algorithms, show
* only the results for the algorithm with this
* identifier.
* Arguments: stream -- A reference to an output stream to which the
* information should be written.
* indent -- Number of spaces to leave on the left of the
* output.
* algorithms -- A reference to a constant IntervalList
* storing the numeric identifiers of the
* algorithms for which the statistics should
* be shown.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
Exceptional_ostream estream(&stream, ios::failbit | ios::badbit);
bool no_errors_to_report = true;
if (algorithm < round_info.number_of_translators
&& !configuration.algorithms[algorithm].enabled)
{
estream << string(indent, ' ') + "not performed\n\n";
estream.flush();
return;
}
estream << string(indent, ' ') + "result:";
bool no_errors_to_report = true, nothing_to_report = true;
const AutomatonStats* alg_1_pos_results;
const AutomatonStats* alg_1_neg_results;
for (vector<AlgorithmTestResults, ALLOC(AlgorithmTestResults) >::size_type
alg_1 = 0;
alg_1 < round_info.number_of_translators;
alg_1++)
for (IntervalList::const_iterator alg_1 = algorithms.begin();
alg_1 != algorithms.end();
++alg_1)
{
alg_1_pos_results = &test_results[alg_1].automaton_stats[0];
alg_1_neg_results = &test_results[alg_1].automaton_stats[1];
alg_1_pos_results = &test_results[*alg_1].automaton_stats[0];
alg_1_neg_results = &test_results[*alg_1].automaton_stats[1];
for (vector<AlgorithmTestResults, ALLOC(AlgorithmTestResults) >::size_type
alg_2 = alg_1;
for (vector<AlgorithmTestResults>::size_type alg_2 = 0;
alg_2 < round_info.number_of_translators;
alg_2++)
{
if ((algorithm >= round_info.number_of_translators
|| alg_1 == algorithm
|| alg_2 == algorithm)
&& configuration.algorithms[alg_1].enabled
&& configuration.algorithms[alg_2].enabled)
if (configuration.algorithms[*alg_1].enabled
&& configuration.algorithms[alg_2].enabled
&& (alg_2 >= *alg_1 || !algorithms.covers(alg_2))
&& !configuration.isInternalAlgorithm(*alg_1)
&& !configuration.isInternalAlgorithm(alg_2))
{
bool pos_test, neg_test;
if (nothing_to_report)
{
nothing_to_report = false;
estream << string(indent, ' ') + "result:";
}
for (int counter = -1; counter < 1; counter++)
{
pos_test = (alg_1_pos_results->buchi_intersection_check_stats[alg_2]
@ -482,7 +585,7 @@ void printBuchiIntersectionCheckStats
estream << string(counter == -1 ? "N/A " : "failed") + ' ';
if (alg_1 != alg_2)
if (*alg_1 != alg_2)
{
estream << '(';
if (pos_test)
@ -493,9 +596,9 @@ void printBuchiIntersectionCheckStats
else
estream << " ";
estream << ' ' + configuration.algorithmString(alg_1);
estream << ' ' + configuration.algorithmString(*alg_1);
if (alg_1 != alg_2)
if (*alg_1 != alg_2)
{
estream << ", (";
if (pos_test)
@ -511,18 +614,18 @@ void printBuchiIntersectionCheckStats
}
}
if (no_errors_to_report)
if (nothing_to_report)
estream << string(indent, ' ') + "not performed";
else if (no_errors_to_report)
estream << string(20, ' ') + "no failures detected";
estream << "\n\n";
estream << "\n";
estream.flush();
}
/* ========================================================================= */
void printAllStats
(ostream& stream, int indent,
vector<AlgorithmTestResults, ALLOC(AlgorithmTestResults) >::size_type
algorithm)
vector<AlgorithmTestResults>::size_type algorithm)
/* ----------------------------------------------------------------------------
*
* Description: Displays all test information (Büchi automaton and product
@ -541,30 +644,46 @@ void printAllStats
{
Exceptional_ostream estream(&stream, ios::failbit | ios::badbit);
estream << string(indent, ' ') + configuration.algorithmString(algorithm)
+ '\n';
estream.flush();
if (configuration.global_options.verbosity >= 3)
estream << string(indent, ' ') + configuration.algorithmString(algorithm)
+ '\n';
for (int counter = 0; counter < 2; counter++)
{
estream << string(indent + 2, ' ')
+ (counter == 0 ? "Positive" : "Negated") + " formula:\n"
+ string(indent + 4, ' ') + "Büchi automaton:\n";
if (configuration.global_options.verbosity <= 2)
{
if (counter == 1)
estream << '\n';
estream << string(indent, ' ');
changeStreamFormatting(stream, 2, 0, ios::right);
estream << algorithm << ' ';
restoreStreamFormatting(stream);
estream << (counter == 0 ? '+' : '-') << ' ';
}
else
{
estream << string(indent + 2, ' ')
+ (counter == 0 ? "Positive" : "Negated") + " formula:\n"
+ string(indent + 4, ' ') + "Büchi automaton:\n";
}
printBuchiAutomatonStats(stream, indent + 6, algorithm, counter);
if (configuration.global_options.do_comp_test
|| configuration.global_options.do_cons_test)
{
estream << string(indent + 4, ' ') + "Product automaton:\n";
if (configuration.global_options.verbosity >= 3)
estream << string(indent + 4, ' ') + "Product automaton:\n";
printProductAutomatonStats(stream, indent + 6, algorithm, counter);
estream << string(indent + 4, ' ') + "Accepting cycles:\n";
if (configuration.global_options.verbosity >= 3)
estream << string(indent + 4, ' ') + "Accepting cycles:\n";
printAcceptanceCycleStats(stream, indent + 6, algorithm, counter);
}
}
if (configuration.global_options.do_cons_test)
{
estream << string(indent + 2, ' ') + "Result consistency check:\n";
if (configuration.global_options.verbosity >= 3)
estream << string(indent + 2, ' ') + "Result consistency check:\n";
printConsistencyCheckStats(stream, indent + 4, algorithm);
}
@ -575,8 +694,8 @@ void printAllStats
/* ========================================================================= */
void printCollectiveCrossComparisonStats
(ostream& stream,
vector<TestStatistics, ALLOC(TestStatistics) >::size_type algorithm_y,
vector<TestStatistics, ALLOC(TestStatistics) >::size_type algorithm_x,
vector<TestStatistics>::size_type algorithm_y,
vector<TestStatistics>::size_type algorithm_x,
int data_type)
/* ----------------------------------------------------------------------------
*
@ -630,10 +749,8 @@ void printCollectiveCrossComparisonStats
break;
default :
if (configuration.global_options.statespace_generation_mode
& Configuration::PATH
&& (algorithm_x == round_info.number_of_translators
|| algorithm_y == round_info.number_of_translators))
if (configuration.isInternalAlgorithm(algorithm_x)
|| configuration.isInternalAlgorithm(algorithm_y))
{
estream << string(21, ' ');
return;
@ -768,13 +885,12 @@ void printCollectiveStats(ostream& stream, int indent)
if (round_info.num_processed_formulae > 0
&& configuration.global_options.formula_input_filename.empty())
{
const map<unsigned long int, unsigned long int, less<unsigned long int>,
ALLOC(unsigned long int) >&
const map<unsigned long int, unsigned long int>&
proposition_statistics
= configuration.formula_options.formula_generator.
propositionStatistics();
const map<int, unsigned long int, less<int>, ALLOC(unsigned long int) >
const map<int, unsigned long int>
symbol_statistics
= configuration.formula_options.formula_generator.symbolStatistics();
@ -820,9 +936,8 @@ void printCollectiveStats(ostream& stream, int indent)
number_of_symbols_printed++;
}
for (map<unsigned long int, unsigned long int,
less<unsigned long int>, ALLOC(unsigned long int) >
::const_iterator proposition = proposition_statistics.begin();
for (map<unsigned long int, unsigned long int>::const_iterator
proposition = proposition_statistics.begin();
proposition != proposition_statistics.end();
++proposition)
{
@ -869,8 +984,8 @@ void printCollectiveStats(ostream& stream, int indent)
= "";
number_of_symbols_printed = 0;
for (map<int, unsigned long int, less<int>, ALLOC(unsigned long int) >
::const_iterator op = symbol_statistics.begin();
for (map<int, unsigned long int>::const_iterator
op = symbol_statistics.begin();
op != symbol_statistics.end();
++op)
{
@ -912,6 +1027,8 @@ void printCollectiveStats(ostream& stream, int indent)
if (number_of_symbols_printed % 5 != 0)
{
if (number_of_symbols_printed > 5)
estream << '\n';
estream << ind + " operator " + symbol_name_string + '\n'
+ ind + " # " + symbol_number_string + '\n'
+ ind + " #/formula " + symbol_distribution_string
@ -953,8 +1070,11 @@ void printCollectiveStats(ostream& stream, int indent)
algorithm < round_info.number_of_translators;
++algorithm)
{
if (configuration.isInternalAlgorithm(algorithm))
continue;
estream << '\n' + string((i > 0 ? 4 : 2) + indent, ' ')
+ *(configuration.algorithms[algorithm].name) + '\n';
+ configuration.algorithms[algorithm].name + '\n';
switch (i)
{
@ -967,14 +1087,14 @@ void printCollectiveStats(ostream& stream, int indent)
unsigned long int failures_to_compute_automaton;
unsigned long int automaton_count;
unsigned long int number_of_successful_instances;
unsigned long int total_number_of_states;
unsigned long int total_number_of_transitions;
BIGUINT total_number_of_states;
BIGUINT total_number_of_transitions;
const TestStatistics& stats = final_statistics[algorithm];
estream << string(2 + indent, ' ')
+ string(configuration.algorithms[algorithm].name
->length(), '=');
+ string(configuration.algorithms[algorithm].name.
length(), '=');
for (int k = 0; k < 2; k++)
{
@ -1119,7 +1239,7 @@ void printCollectiveStats(ostream& stream, int indent)
if (k == 0)
{
unsigned long int total_number_of_acceptance_sets;
BIGUINT total_number_of_acceptance_sets;
double buchi_generation_time;
estream << '\n' + string(22 + indent, ' ')
@ -1339,8 +1459,7 @@ void printCollectiveStats(ostream& stream, int indent)
estream << ind + " Result inconsistency statistics\n"
+ ind + " " + string(31, '=') + '\n';
vector<TestStatistics, ALLOC(TestStatistics) >::size_type
algorithm_x, algorithm_y;
vector<TestStatistics>::size_type algorithm_x, algorithm_y;
for (algorithm_x = 0; algorithm_x < number_of_algorithms;
algorithm_x += 2)
@ -1352,7 +1471,7 @@ void printCollectiveStats(ostream& stream, int indent)
if (algorithm_x + i < number_of_algorithms)
{
algorithm_name =
(*(configuration.algorithms[algorithm_x + i].name)).substr(0, 20);
configuration.algorithms[algorithm_x + i].name.substr(0, 20);
estream << "| " + algorithm_name
+ string(21 - algorithm_name.length(), ' ');
}
@ -1362,6 +1481,9 @@ void printCollectiveStats(ostream& stream, int indent)
for (algorithm_y = 0; algorithm_y < number_of_algorithms;
algorithm_y++)
{
if (configuration.isInternalAlgorithm(algorithm_y))
continue;
estream << "\n " + ind + string(26, '-');
for (int i = 0; i < 2; ++i)
@ -1372,7 +1494,7 @@ void printCollectiveStats(ostream& stream, int indent)
estream << '+';
algorithm_name
= (*(configuration.algorithms[algorithm_y].name)).substr(0, 20);
= configuration.algorithms[algorithm_y].name.substr(0, 20);
bool algorithm_name_printed = false;
legend = 1;

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -42,65 +42,60 @@ extern Configuration configuration;
namespace StatDisplay
{
void printStatTableHeader /* Displays a table */
(ostream& stream, int indent); /* header for test
* statistics.
*/
void printBuchiAutomatonStats /* Displays information */
(ostream& stream, /* about a Büchi */
int indent, /* automaton. */
vector<AlgorithmTestResults,
ALLOC(AlgorithmTestResults) >::size_type
vector<AlgorithmTestResults>::size_type
algorithm,
int result_id);
void printProductAutomatonStats /* Displays information */
(ostream& stream, /* about a product */
int indent, /* automaton. */
vector<AlgorithmTestResults,
ALLOC(AlgorithmTestResults) >::size_type
vector<AlgorithmTestResults>::size_type
algorithm,
int result_id);
void printAcceptanceCycleStats /* Displays information */
(ostream& stream, /* about the acceptance */
int indent, /* cycles of a product */
vector<AlgorithmTestResults, /* automaton. */
ALLOC(AlgorithmTestResults) >::size_type
vector<AlgorithmTestResults>::size_type /* automaton. */
algorithm,
int result_id);
void printConsistencyCheckStats /* Displays the result */
(ostream& stream, /* of the consistency */
int indent, /* check for a given */
vector<AlgorithmTestResults, /* algorithm. */
ALLOC(AlgorithmTestResults) >::size_type
vector<AlgorithmTestResults>::size_type /* algorithm. */
algorithm);
void printCrossComparisonStats /* Displays information */
(ostream& stream, /* about the model */
int indent, /* checking result */
vector<AlgorithmTestResults, /* cross-comparison */
ALLOC(AlgorithmTestResults) >::size_type /* check. */
algorithm);
(ostream& stream, int indent, /* about the model */
const IntervalList& algorithms); /* checking result */
/* cross-comparison */
/* check. */
void printBuchiIntersectionCheckStats /* Displays the results */
(ostream& stream, int indent, /* of the Büchi automata */
vector<AlgorithmTestResults, /* intersection */
ALLOC(AlgorithmTestResults) >::size_type /* emptiness checks. */
algorithm);
const IntervalList& algorithms); /* intersection */
/* emptiness checks. */
void printAllStats /* A shorthand for */
(ostream& stream, /* showing all the */
int indent, /* information displayed */
vector<TestStatistics, /* by the previous five */
ALLOC(TestStatistics)>::size_type /* functions. */
algorithm);
vector<TestStatistics>::size_type algorithm); /* by the previous five
* functions.
*/
void printCollectiveCrossComparisonStats /* Displays a single */
(ostream& stream, /* `cell' of the final */
vector<TestStatistics, /* result cross- */
ALLOC(TestStatistics) >::size_type /* comparison table. */
algorithm_y,
vector<TestStatistics,
ALLOC(TestStatistics) >::size_type
algorithm_x,
vector<TestStatistics>::size_type algorithm_y, /* result cross- */
vector<TestStatistics>::size_type algorithm_x, /* comparison table. */
int data_type);
void printCollectiveStats /* Displays average test */

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -17,10 +17,6 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifdef __GNUC__
#pragma implementation
#endif /* __GNUC__ */
#include <config.h>
#include <map>
#include "DispUtil.h"
@ -148,8 +144,7 @@ void StateSpace::clear()
initial_state = 0;
#ifdef HAVE_OBSTACK_H
for (vector<Node*, ALLOC(Node*) >::iterator state = nodes.begin();
state != nodes.end();
for (vector<Node*>::iterator state = nodes.begin(); state != nodes.end();
++state)
static_cast<State*>(*state)->~State();

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -174,9 +174,7 @@ StateSpace* StateSpaceRandomizer::generateConnectedGraph() const
StateSpace::size_type first_unreachable_state = 1, random_node;
multimap<long int, StateSpace::size_type, less<long int>,
ALLOC(StateSpace::size_type) >
reachable_but_unprocessed;
multimap<long int, StateSpace::size_type> reachable_but_unprocessed;
reachable_but_unprocessed.insert(make_pair(0, 0));

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -20,10 +20,6 @@
#ifndef STATESPACERANDOMIZER_H
#define STATESPACERANDOMIZER_H
#ifdef __GNUC__
#pragma interface
#endif /* __GNUC__ */
#include <config.h>
#include "Random.h"
#include "StateSpace.h"

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -17,11 +17,9 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifdef __GNUC__
#pragma implementation
#endif /* __GNUC__ */
#include <config.h>
#include <cctype>
#include <climits>
#include <cstdlib>
#include "StringUtil.h"
@ -63,8 +61,7 @@ string toString(const double d, const int precision, const ios::fmtflags flags)
/* ========================================================================= */
void sliceString
(const string& s, const char* slice_chars,
vector<string, ALLOC(string) >& slices)
(const string& s, const char* slice_chars, vector<string>& slices)
/* ----------------------------------------------------------------------------
*
* Description: Slices a string into a vector of strings, using a given set
@ -104,6 +101,211 @@ void sliceString
while (last_non_slicechar_pos != s.npos && last_slicechar_pos != s.npos);
}
/* ========================================================================= */
string toLowerCase(const string& s)
/* ----------------------------------------------------------------------------
*
* Description: Converts a string to lower case.
*
* Argument: s -- String to process.
*
* Returns: The string in lower case.
*
* ------------------------------------------------------------------------- */
{
string result;
for (string::size_type pos = 0; pos < s.length(); ++pos)
result += tolower(s[pos]);
return result;
}
/* ========================================================================= */
bool interpretSpecialCharacters(const char c, bool& escape, char& quotechar)
/* ----------------------------------------------------------------------------
*
* Description: Updates the values of `escape' and `quotechar' based on their
* original values and the value of `c'. Used for scanning
* through a string possibly containing quotes and escaped
* characters.
*
* Arguments: c -- A character.
* escape -- A truth value telling whether `c' was escaped.
* quotechar -- 0 == `c' was read outside of quotes.
* `'' == `c' was read inside single quotes.
* `"' == `c' was read inside double quotes.
*
* Returns: True if `c' had a special meaning (for example, if it was a
* begin/end quote character) in the state determined by the
* original values of `escape' and `quotechar'.
*
* ------------------------------------------------------------------------- */
{
if (escape)
{
escape = false;
return false;
}
switch (c)
{
case '\\' :
if (quotechar != '\'')
{
escape = true;
return true;
}
break;
case '\'' : case '"' :
if (quotechar == 0)
{
quotechar = c;
return true;
}
else if (c == quotechar)
{
quotechar = 0;
return true;
}
break;
default :
break;
}
return false;
}
/* ========================================================================= */
string unquoteString(const string& s)
/* ----------------------------------------------------------------------------
*
* Description: Removes (unescaped) single and double quotes and escape
* characters from a string.
*
* Argument: s -- String to process.
*
* Returns: A string with the quotes and escape characters removed.
*
* ------------------------------------------------------------------------- */
{
string result;
char quotechar = 0;
bool escape = false;
for (string::size_type pos = 0; pos < s.size(); ++pos)
{
if (!interpretSpecialCharacters(s[pos], escape, quotechar))
result += s[pos];
}
return result;
}
/* ========================================================================= */
string::size_type findInQuotedString
(const string& s, const string& chars, QuoteMode type)
/* ----------------------------------------------------------------------------
*
* Description: Finds a character in a string (respecting quotes).
*
* Arguments: s -- String to process.
* chars -- A sting of characters to be searched in `s'.
* type -- The extent of the search.
* GLOBAL - Apply the search to the entire
* string.
* INSIDE_QUOTES - Restrict the search to
* unescaped characters between
* quotes.
* OUTSIDE_QUOTES - Restrict the search to
* unescaped characters outside
* quotes.
*
* Returns: If `s' contains one of the characters in `chars' in a part
* of the string that matches `type', the position of the
* character in `s', and string::npos otherwise.
*
* ------------------------------------------------------------------------- */
{
char quotechar = 0;
bool escape = false;
for (string::size_type pos = 0; pos < s.size(); ++pos)
{
if ((type == GLOBAL || (!escape &&
((type == INSIDE_QUOTES && quotechar != 0)
|| (type == OUTSIDE_QUOTES && quotechar == 0))))
&& chars.find_first_of(s[pos]) != string::npos)
return pos;
interpretSpecialCharacters(s[pos], escape, quotechar);
}
return string::npos;
}
/* ========================================================================= */
string substituteInQuotedString
(const string& s, const string& chars, const string& substitutions,
QuoteMode type)
/* ----------------------------------------------------------------------------
*
* Description: Substitutes characters in a string with other characters.
*
* Arguments: s -- String to process.
* chars -- A string of characters, each of which
* should be substituted in `s' with the
* character at the corresponding
* position of the string `substitutions'.
* substitutions -- Characters to substitute. The length of
* this string should equal the length of
* `chars'.
* type -- The extent of substitution.
* GLOBAL - Apply the substitutions
* globally (the default).
* INSIDE_QUOTES - Apply the substitutions
* to unescaped characters
* only inside quotes that
* have not been escaped
* with a backslash.
* OUTSIDE_QUOTES - Apply the substitutions
* to unescaped characters
* only outside quotes
* that have not been
* escaped with a
* backslash.
* It is not recommended to substitute the
* special characters ', " and \ with other
* characters if they have special meaning in
* `s'.
*
* Returns: A string with the substitutions.
*
* ------------------------------------------------------------------------- */
{
string result;
char quotechar = 0;
bool escape = false;
for (string::size_type pos = 0; pos < s.size(); ++pos)
{
char c = s[pos];
if (type == GLOBAL || (!escape &&
((type == INSIDE_QUOTES && quotechar != 0)
|| (type == OUTSIDE_QUOTES && quotechar == 0))))
{
string::size_type subst_pos = chars.find_first_of(c);
if (subst_pos != string::npos)
c = substitutions[subst_pos];
}
result += c;
interpretSpecialCharacters(s[pos], escape, quotechar);
}
return result;
}
/* ========================================================================= */
unsigned long int parseNumber(const string& number_string)
/* ----------------------------------------------------------------------------
@ -119,9 +321,11 @@ unsigned long int parseNumber(const string& number_string)
* ------------------------------------------------------------------------- */
{
char* endptr;
unsigned long int number = strtoul(number_string.c_str(), &endptr, 10);
if (*endptr != '\0')
if (*endptr != '\0' || number_string.empty()
|| number_string.find_first_of("-") != string::npos)
throw NotANumberException("expected a nonnegative integer, got `"
+ number_string + "'");
@ -129,98 +333,253 @@ unsigned long int parseNumber(const string& number_string)
}
/* ========================================================================= */
void parseInterval
(const string& token,
set<unsigned long int, less<unsigned long int>, ALLOC(unsigned long int) >&
number_set,
unsigned long int min, unsigned long int max)
int parseInterval
(const string& token, unsigned long int& min, unsigned long int& max)
/* ----------------------------------------------------------------------------
*
* Description: Parses a string for a list of number intervals, storing all
* the numbers into a set.
* Description: Reads the lower and upper bound from an "interval string"
* into two unsigned long integer variables.
*
* Arguments: token -- A reference to a constant string containing
* the list of intervals. A legal list of
* intervals has the following syntax:
* Arguments: token -- A reference to a constant "interval string" of
* the format
* <interval string>
* ::= "*" // 0
* | <ulong> // 1
* | <sep><ulong> // 2
* | <ulong><sep> // 3
* | <ulong><sep><ulong> // 4
* where <ulong> is an unsigned long integer (not
* containing a minus sign), and <sep> is either
* "-" or "...". The meaning of the various cases
* is as follows:
* 0 All integers between 0 and ULONG_MAX.
* 1 A point interval consisting of a single
* value.
* 2 An interval from 0 to a given upper
* bound.
* 3 An interval from a given lower bound to
* ULONG_MAX.
* 4 A bounded interval.
* min, max -- References to two unsigned long integers for
* storing the lower and upper bound of the
* interval.
*
* <interval_list>
* ::= <number>
* | '*' // all numbers in the
* // interval
* // [min, max]
* | '-'<number> // all numbers in the
* // interval
* // [min, number]
* | <number>'-' // all numbers in the
* // interval
* // [number, max]
* | <number>'-'<number>
* | <interval_list>','<interval_list>
*
* number_set -- A reference to a set of unsigned long
* integers for storing the result.
* min -- Minimum bound for the numbers.
* max -- Maximum bound for the numbers.
*
* Note: `min' and `max' are only used to determine the limits
* for only partially defined intervals. The check that
* the explicitly specified values in the interval list
* are within these bounds is left to the caller when
* examining the result set.
*
* Returns: Nothing.
* Returns: A value telling the type of the specified interval, which is
* a bitwise or of the values LEFT_BOUNDED and RIGHT_BOUNDED
* depending on which bounds were given explicitly for the
* interval. (The lower and upper bounds of the interval itself
* are stored in the variables `min' and `max', respectively.)
* The function will throw a NotANumberException if the
* interval string is of an invalid format.
*
* ------------------------------------------------------------------------- */
{
vector<string, ALLOC(string) > intervals;
unsigned long int tmp_min = 0;
unsigned long int tmp_max = ULONG_MAX;
int interval_type = UNBOUNDED;
sliceString(token, ",", intervals);
string::size_type dash_pos;
number_set.clear();
for (vector<string, ALLOC(string) >::const_iterator
interval = intervals.begin();
interval != intervals.end();
++interval)
if (token != "*")
{
if (*interval == "*")
string::size_type pos(token.find_first_of("-"));
if (pos == string::npos)
pos = token.find("...");
string value(token.substr(0, pos));
if (!value.empty())
{
for (unsigned long int i = min; i <= max; i++)
number_set.insert(i);
break;
tmp_min = parseNumber(value);
if (pos == string::npos)
tmp_max = tmp_min;
interval_type |= LEFT_BOUNDED;
}
dash_pos = (*interval).find_first_of("-");
if (pos != string::npos)
value = token.substr(pos + (token[pos] == '-' ? 1 : 3));
if (dash_pos == (*interval).npos)
number_set.insert(parseNumber(*interval));
else
if (!value.empty())
{
if (dash_pos == 0)
tmp_max = parseNumber(value);
interval_type |= RIGHT_BOUNDED;
}
else if (!(interval_type & LEFT_BOUNDED))
throw NotANumberException("invalid format for interval");
}
min = tmp_min;
max = tmp_max;
return interval_type;
}
/* ========================================================================= */
void parseIntervalList
(const string& token, IntervalList& intervals, unsigned long int min,
unsigned long int max, vector<string>* extra_tokens)
/* ----------------------------------------------------------------------------
*
* Description: Parses a string of number intervals into an IntervalList.
*
* Arguments: token -- A reference to a constant comma-separated
* list of interval strings (see documentation
* for the parseInterval function).
* intervals -- A reference to an IntervalList to be used
* for storing the result.
* min -- Absolute lower bound for the numbers.
* Numbers lower than this bound will not be
* stored in the result set.
* max -- Absolute upper bound for the numbers.
* Numbers greater than this bound will not be
* stored in the result set.
* extra_tokens -- If not 0, all tokens that cannot be
* recognized as valid interval strings will
* be stored in the vector of strings to which
* this variable points. Otherwise the
* function will throw a NotANumberException.
*
* Returns: Nothing. Throws an IntervalRangeException if any of the
* intervals in the list does not fit in the closed range
* [min,max].
*
* ------------------------------------------------------------------------- */
{
vector<string> interval_strings;
int interval_type;
intervals.clear();
sliceString(token, ",", interval_strings);
for (vector<string>::const_iterator i = interval_strings.begin();
i != interval_strings.end();
++i)
{
unsigned long int i_start, i_end;
try
{
interval_type = parseInterval(*i, i_start, i_end);
}
catch (const NotANumberException&)
{
if (extra_tokens != 0)
{
unsigned long int number = parseNumber((*interval).substr(1));
for (unsigned long int i = min; i <= number; i++)
number_set.insert(i);
}
else if (dash_pos == (*interval).length() - 1)
{
unsigned long int number =
parseNumber((*interval).substr(0, (*interval).length() - 1));
for (unsigned long int i = number; i <= max; i++)
number_set.insert(i);
extra_tokens->push_back(*i);
continue;
}
else
{
unsigned long int min_bound =
parseNumber((*interval).substr(0, dash_pos));
unsigned long int max_bound =
parseNumber((*interval).substr(dash_pos + 1));
for (unsigned long int i = min_bound; i <= max_bound; i++)
number_set.insert(i);
}
throw;
}
if (interval_type & LEFT_BOUNDED)
{
if (i_start < min || i_start > max)
throw IntervalRangeException(i_start);
}
else if (i_start < min)
i_start = min;
if (interval_type & RIGHT_BOUNDED)
{
if (i_end < min || i_end > max)
throw IntervalRangeException(i_end);
}
else if (i_end > max)
i_end = max;
intervals.merge(i_start, i_end);
}
}
/* ========================================================================= */
void parseTime
(const string& time_string, unsigned long int& hours,
unsigned long int& minutes, unsigned long int& seconds)
/* ----------------------------------------------------------------------------
*
* Description: Parses a "time string", i.e., a string of the form
* ([0-9]+"h")([0-9]+"min")?([0-9]+"s")?
* | ([0-9]+"min")([0-9]+"s")?
* | ([0-9]+"s")
* (where 'h', 'min' and 's' correspond to hours, minutes and
* seconds, respectively) and stores the numbers into three
* unsigned long integers. The case of the unit symbols is not
* relevant.
*
* Arguments: time_string -- String to process.
* hours -- A reference to an unsigned long integer for
* storing the number of hours.
* minutes -- A reference to an unsigned long integer for
* storing the number of minutes.
* seconds -- A reference to an unsigned long integer for
* storing the number of seconds.
*
* Time components left unspecified in `time_string' will get
* the value 0.
*
* Returns: Nothing. Throws an Exception if the given string is not of
* the correct format.
*
* ------------------------------------------------------------------------- */
{
bool hours_present = false, minutes_present = false, seconds_present = false;
hours = minutes = seconds = 0;
if (time_string.empty())
throw Exception("invalid time format");
string::size_type pos1 = 0;
string s;
while (pos1 < time_string.length())
{
string::size_type pos2 = time_string.find_first_not_of("0123456789", pos1);
if (pos2 >= time_string.length())
throw Exception("invalid time format");
unsigned long int val;
try
{
val = parseNumber(time_string.substr(pos1, pos2 - pos1));
}
catch (const NotANumberException&)
{
throw Exception("invalid time format");
}
switch (tolower(time_string[pos2]))
{
case 'h' :
if (hours_present || minutes_present || seconds_present)
throw Exception("invalid time format");
hours_present = true;
hours = val;
break;
case 'm' :
if (minutes_present
|| seconds_present
|| pos2 + 2 >= time_string.length()
|| tolower(time_string[pos2 + 1]) != 'i'
|| tolower(time_string[pos2 + 2]) != 'n')
throw Exception("invalid time format");
minutes_present = true;
minutes = val;
pos2 += 2;
break;
case 's' :
if (seconds_present)
throw Exception("invalid time format");
seconds_present = true;
seconds = val;
break;
default : /* 's' */
throw Exception("invalid time format");
break;
}
pos1 = pos2 + 1;
}
}

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -31,6 +31,7 @@
#include <vector>
#include "LbttAlloc.h"
#include "Exception.h"
#include "IntervalList.h"
using namespace std;
@ -57,22 +58,71 @@ template<typename T> string toString(const T& t); /* Template function for
void sliceString /* Breaks a string into */
(const string& s, const char* slice_chars, /* `slices', using a */
vector<string, ALLOC(string) >& slices); /* given set of
vector<string>& slices); /* given set of
* characters as
* separators.
*/
string toLowerCase(const string& s); /* Converts a string to
* lower case.
*/
string unquoteString(const string& s); /* Removes unescaped quotes
* from a string and
* interprets escaped
* characters.
*/
enum QuoteMode {GLOBAL, INSIDE_QUOTES, /* Enumeration type used */
OUTSIDE_QUOTES}; /* for controlling the
* behavior of the
* substitute function.
*/
string::size_type findInQuotedString /* Finds a character in */
(const string& s, const string& chars, /* a string (respecting */
QuoteMode type = GLOBAL); /* quotes). */
string substituteInQuotedString /* Replaces characters */
(const string& s, const string& chars, /* in a string with */
const string& substitutions, /* other characters. */
QuoteMode type = GLOBAL);
unsigned long int parseNumber /* Converts a string to */
(const string& number_string); /* an unsigned long
* integer.
*/
void parseInterval /* Converts a string of */
(const string& token, /* number intervals to */
set<unsigned long int, less<unsigned long int>, /* the corresponding set */
ALLOC(unsigned long int) >& number_set, /* of unsigned long */
unsigned long int min, /* integers. */
unsigned long int max);
enum IntervalStringType {UNBOUNDED = 0, /* Type for an interval */
LEFT_BOUNDED = 1, /* string (see the */
RIGHT_BOUNDED = 2}; /* documentation of
* the parseInterval
* function in
* StringUtil.cc).
*/
int parseInterval /* Reads the lower and */
(const string& token, /* upper bounds from a */
unsigned long int& min, /* "number interval */
unsigned long int& max); /* string" into two
* unsigned long integer
* variables.
*/
void parseIntervalList /* Converts a list of */
(const string& token, /* number intervals to */
IntervalList& intervals, /* the set of unsigned */
unsigned long int min, /* long integers */
unsigned long int max, /* corresponding to the */
vector<string>* extra_tokens = 0); /* union of the
* intervals.
*/
void parseTime /* Parses a time string. */
(const string& time_string,
unsigned long int& hours,
unsigned long int& minutes,
unsigned long int& seconds);
@ -133,6 +183,38 @@ public:
/******************************************************************************
*
* A class for reporting "out of range" errors for numbers when parsing
* intervals.
*
*****************************************************************************/
class IntervalRangeException : public Exception
{
public:
IntervalRangeException /* Constructor. */
(const unsigned long int number,
const string& message = "number out of range");
/* default copy constructor */
~IntervalRangeException() throw(); /* Destructor. */
IntervalRangeException& operator= /* Assignment operator. */
(const IntervalRangeException& e);
unsigned long int getNumber() const; /* Returns the number
* associated with the
* exception object.
*/
private:
const unsigned long int invalid_number;
};
/******************************************************************************
*
* Inline function definitions for class NotANumberException.
@ -189,6 +271,82 @@ inline NotANumberException& NotANumberException::operator=
return *this;
}
/******************************************************************************
*
* Inline function definitions for class IntervalRangeException.
*
*****************************************************************************/
/* ========================================================================= */
inline IntervalRangeException::IntervalRangeException
(const unsigned long int number, const string& message) :
Exception(message), invalid_number(number)
/* ----------------------------------------------------------------------------
*
* Description: Constructor for class IntervalRangeException. Creates an
* exception object.
*
* Arguments: number -- A constant unsigned long integer specifying a
* number that does not fit in an interval.
* message -- A reference to a constant string containing an
* error message.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
inline IntervalRangeException::~IntervalRangeException() throw()
/* ----------------------------------------------------------------------------
*
* Description: Destructor for class IntervalRangeException.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
inline unsigned long int IntervalRangeException::getNumber() const
/* ----------------------------------------------------------------------------
*
* Description: Returns the number associated with the IntervalRangeException
* object.
*
* Arguments: None.
*
* Returns: The number associated with the object.
*
* ------------------------------------------------------------------------- */
{
return invalid_number;
}
/* ========================================================================= */
inline IntervalRangeException& IntervalRangeException::operator=
(const IntervalRangeException& e)
/* ----------------------------------------------------------------------------
*
* Description: Assignment operator for class IntervalRangeException.
* Copies the contents of an exception object to another.
*
* Arguments: e -- A reference to a constant IntervalRangeException.
*
* Returns: A reference to the object assigned to.
*
* ------------------------------------------------------------------------- */
{
Exception::operator=(e);
return *this;
}
}
#endif /* !STRINGUTIL_H */

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 2004
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
* Copyright (C) 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 2004
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
* Copyright (C) 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -29,6 +29,7 @@
#include "Configuration.h"
#include "Exception.h"
#include "StateSpace.h"
#include "TestStatistics.h"
using namespace std;
@ -53,7 +54,11 @@ void openFile /* Opens a file for */
(const char* filename, ofstream& stream, /* writing. */
ios::openmode mode, int indent = 0);
void removeFile /* Removes a file. */
void openFile /* Opens a file for */
(const char* filename, int& fd, int flags, /* input/output using */
int indent = 0); /* file descriptors. */
void truncateFile /* Truncates a file. */
(const char* filename, int indent = 0);
void printFileContents /* Displays the contents */
@ -90,32 +95,25 @@ void writeFormulaeToFiles(); /* Writes LTL formulas */
void generateBuchiAutomaton /* Generates a Büchi */
(int f, /* automaton from a LTL */
vector<Configuration::AlgorithmInformation, /* formula stored in a */
ALLOC(Configuration::AlgorithmInformation) > /* given file, using a */
::size_type /* given LTL-to-Büchi */
algorithm_id); /* translation algorithm
vector<Configuration::AlgorithmInformation> /* formula stored in a */
::size_type /* given file, using a */
algorithm_id); /* given LTL-to-Büchi
* translation algorithm
* for the conversion.
*/
void generateProductAutomaton /* Computes the */
(int f, /* synchronous product */
vector<Configuration::AlgorithmInformation, /* of a Büchi automaton */
ALLOC(Configuration::AlgorithmInformation) > /* and a state space. */
::size_type
algorithm_id);
void performEmptinessCheck /* Performs an emptiness */
(int f, /* check on a product */
vector<Configuration::AlgorithmInformation, /* automaton. */
ALLOC(Configuration::AlgorithmInformation) >
vector<Configuration::AlgorithmInformation> /* automaton. */
::size_type
algorithm_id);
void performConsistencyCheck /* Performs a */
(vector<Configuration::AlgorithmInformation, /* consistency check on */
ALLOC(Configuration::AlgorithmInformation) > /* the test results */
::size_type /* for a formula and its */
algorithm_id); /* negation. */
(vector<Configuration::AlgorithmInformation> /* consistency check on */
::size_type /* the test results */
algorithm_id); /* for a formula and its
* negation.
*/
void compareResults(); /* Compares the model
* checking results

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -28,9 +28,9 @@
#include "LbttAlloc.h"
#include "Exception.h"
#include "LtlFormula.h"
#include "ProductAutomaton.h"
#include "PathIterator.h"
#include "StateSpace.h"
#include "TempFsysName.h"
using namespace std;
@ -55,7 +55,11 @@ public:
* stream for messages.
*/
ifstream formula_input_file; /* Stream for reading input
istream* formula_input_stream; /* Stream for reading input
* formulae.
*/
ifstream formula_input_file; /* File for reading input
* formulae.
*/
@ -90,6 +94,10 @@ public:
* current round.
*/
bool all_tests_successful; /* True if no errors have
* occurred during testing.
*/
bool skip; /* True if the current
* round is to be skipped.
*/
@ -122,11 +130,6 @@ public:
* paths as state spaces.
*/
const Graph::ProductAutomaton* product_automaton; /* Pointer to the product
* automaton used in the
* current test round.
*/
unsigned long int real_emptiness_check_size; /* Number of states in the
* state space where the
* emptiness check should
@ -150,9 +153,9 @@ public:
* current round.
*/
vector<class ::Ltl::LtlFormula*, /* Formulae used in the */
ALLOC(class ::Ltl::LtlFormula*) > /* current round: */
formulae; /* formulae[0]:
vector<class ::Ltl::LtlFormula*> formulae; /* Formulae used in the
* current round:
* formulae[0]:
* positive formula in
* negation normal
* form
@ -168,7 +171,7 @@ public:
* generated
*/
vector<bool, ALLOC(bool) > formula_in_file; /* The values in this
vector<bool> formula_in_file; /* The values in this
* vector will be set to
* true when the
* corresponding
@ -181,10 +184,10 @@ public:
* formula.
*/
char formula_file_name[2][L_tmpnam + 1]; /* Storage space for the */
char automaton_file_name[L_tmpnam + 1]; /* names of several */
char cout_capture_file[L_tmpnam + 1]; /* temporary files. */
char cerr_capture_file[L_tmpnam + 1];
TempFsysName* formula_file_name[2]; /* Names for temporary */
TempFsysName* automaton_file_name; /* files. */
TempFsysName* cout_capture_file;
TempFsysName* cerr_capture_file;
private:
TestRoundInfo(const TestRoundInfo& info); /* Prevent copying and */
@ -206,14 +209,15 @@ private:
inline TestRoundInfo::TestRoundInfo() :
cout(&std::cout, ios::failbit | ios::badbit), number_of_translators(0),
current_round(1), next_round_to_run(1), next_round_to_stop(1),
error_report_round(0), error(false), skip(false), abort(false),
num_generated_statespaces(0), total_statespace_states(0),
total_statespace_transitions(0), num_processed_formulae(0),
fresh_statespace(false), statespace(0), path_iterator(0),
product_automaton(0), real_emptiness_check_size(0),
error_report_round(0), error(false), all_tests_successful(true),
skip(false), abort(false), num_generated_statespaces(0),
total_statespace_states(0), total_statespace_transitions(0),
num_processed_formulae(0), fresh_statespace(false), statespace(0),
path_iterator(0), real_emptiness_check_size(0),
next_round_to_change_statespace(1), next_round_to_change_formula(1),
fresh_formula(false), formulae(4, static_cast<class ::Ltl::LtlFormula*>(0)),
formula_in_file(2, false)
formula_in_file(2, false), automaton_file_name(0), cout_capture_file(0),
cerr_capture_file(0)
/* ----------------------------------------------------------------------------
*
* Description: Constructor for class TestRoundInfo. Creates a new
@ -225,6 +229,7 @@ inline TestRoundInfo::TestRoundInfo() :
*
* ------------------------------------------------------------------------- */
{
formula_file_name[0] = formula_file_name[1] = 0;
}
/* ========================================================================= */

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -17,10 +17,6 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifdef __GNUC__
#pragma implementation
#endif /* __GNUC__ */
#include <config.h>
#include "TestStatistics.h"
@ -54,8 +50,7 @@ void AlgorithmTestResults::emptinessReset()
automaton_stats[i].emptiness_check_result.clear();
automaton_stats[i].emptiness_check_performed = false;
for (vector<AutomatonStats::CrossComparisonStats,
ALLOC(AutomatonStats::CrossComparisonStats) >::iterator it
for (vector<AutomatonStats::CrossComparisonStats>::iterator it
= automaton_stats[i].cross_comparison_stats.begin();
it != automaton_stats[i].cross_comparison_stats.end();
++it)
@ -91,7 +86,7 @@ void AlgorithmTestResults::fullReset()
automaton_stats[i].number_of_msccs = 0;
automaton_stats[i].buchi_generation_time = 0.0;
for (vector<int, ALLOC(int) >::iterator it
for (vector<int>::iterator it
= automaton_stats[i].buchi_intersection_check_stats.begin();
it != automaton_stats[i].buchi_intersection_check_stats.end();
++it)

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -23,16 +23,16 @@
#include <config.h>
#include <utility>
#include <vector>
#include "EdgeContainer.h"
#include "Graph.h"
#include "LbttAlloc.h"
#include "BuchiAutomaton.h"
#include "Configuration.h"
#include "ProductAutomaton.h"
#include "StateSpace.h"
using namespace std;
using Graph::BuchiAutomaton;
using Graph::StateSpace;
using Graph::ProductAutomaton;
/******************************************************************************
*
@ -43,9 +43,8 @@ using Graph::ProductAutomaton;
struct AutomatonStats
{
explicit AutomatonStats /* Constructor. */
(vector<Configuration::AlgorithmInformation,
ALLOC(Configuration::AlgorithmInformation) >
::size_type number_of_algorithms,
(vector<Configuration::AlgorithmInformation>
::size_type number_of_algorithms,
StateSpace::size_type max_statespace_size);
/* default copy constructor */
@ -107,7 +106,7 @@ struct AutomatonStats
* Büchi automaton.
*/
ProductAutomaton::size_type /* Number of stats in a */
::Graph::Graph<GraphEdgeContainer>::size_type /* Number of stats in a */
number_of_product_states; /* product automaton. */
unsigned long int number_of_product_transitions; /* Number of transitions in
@ -127,9 +126,9 @@ struct AutomatonStats
typedef pair<bool, unsigned long int>
CrossComparisonStats;
vector<CrossComparisonStats, /* Emptiness check */
ALLOC(CrossComparisonStats) > /* cross-comparison */
cross_comparison_stats; /* results. The `first'
vector<CrossComparisonStats> /* Emptiness check */
cross_comparison_stats; /* cross-comparison
* results. The `first'
* element of the pair
* tells whether a cross-
* comparison with a given
@ -142,8 +141,8 @@ struct AutomatonStats
* differ.
*/
vector<int, ALLOC(int) > /* Büchi automaton */
buchi_intersection_check_stats; /* intersection
vector<int> buchi_intersection_check_stats; /* Büchi automaton
* intersection
* emptiness check
* results. The elements
* of the vector tell
@ -173,8 +172,7 @@ struct AutomatonStats
struct AlgorithmTestResults
{
explicit AlgorithmTestResults /* Constructor. */
(vector<Configuration::AlgorithmInformation,
ALLOC(Configuration::AlgorithmInformation) >
(vector<Configuration::AlgorithmInformation>
::size_type
number_of_algorithms,
StateSpace::size_type max_statespace_size);
@ -214,8 +212,8 @@ struct AlgorithmTestResults
* check.
*/
vector<AutomatonStats, ALLOC(AutomatonStats) > /* A two-element vector */
automaton_stats; /* storing test results
vector<AutomatonStats> automaton_stats; /* A two-element vector
* storing test results
* for an algorithm.
*/
};
@ -232,8 +230,7 @@ struct AlgorithmTestResults
struct TestStatistics
{
explicit TestStatistics /* Constructor. */
(vector<TestStatistics,
ALLOC(TestStatistics) >::size_type
(vector<TestStatistics>::size_type
number_of_algorithms);
/* default copy constructor */
@ -270,29 +267,21 @@ struct TestStatistics
* checks performed.
*/
unsigned long int /* Total number of */
total_number_of_buchi_states[2]; /* states in all the
* generated Büchi
* automata.
BIGUINT total_number_of_buchi_states[2]; /* Total number of states
* in all the generated
* Büchi automata.
*/
unsigned long int /* Total number of */
total_number_of_buchi_transitions[2]; /* transitions in all
BIGUINT total_number_of_buchi_transitions[2]; /* Total number of
* transitions in all
* the generated Büchi
* automata.
*/
unsigned long int /* Total number of sets */
total_number_of_acceptance_sets[2]; /* of accepting states
* in all the generated
* Büchi automata.
*/
unsigned long int /* Total number of */
total_number_of_msccs[2]; /* maximal strongly
* connected components
* in the generated
* Büchi automata.
BIGUINT total_number_of_acceptance_sets[2]; /* Total number of sets of
* accepting states in all
* the generated Büchi
* automata.
*/
double total_buchi_generation_time[2]; /* Total time used when
@ -300,36 +289,37 @@ struct TestStatistics
* automata.
*/
unsigned long int /* Total number of */
total_number_of_product_states[2]; /* states in all the
BIGUINT total_number_of_product_states[2]; /* Total number of states
* in all the generated
* product automata.
*/
BIGUINT total_number_of_product_transitions[2]; /* Total number of
* transitions in all the
* generated product
* automata.
*/
unsigned long int /* Total number of */
total_number_of_product_transitions[2]; /* transitions in all the
* generated product
* automata.
vector<unsigned long int> /* Number of failed */
cross_comparison_mismatches; /* result cross-
* comparisons.
*/
vector<unsigned long int, /* Number of failed */
ALLOC(unsigned long int) > /* result cross- */
cross_comparison_mismatches; /* comparisons. */
vector<unsigned long int, /* Number of failed */
ALLOC(unsigned long int) > /* result cross- */
initial_cross_comparison_mismatches; /* comparisons in the
vector<unsigned long int> /* Number of failed */
initial_cross_comparison_mismatches; /* result cross-
* comparisons in the
* initial state of the
* state space.
*/
vector<unsigned long int, /* Number of result */
ALLOC(unsigned long int) > /* cross-comparisons */
cross_comparisons_performed; /* performed. */
vector<unsigned long int> /* Number of result */
cross_comparisons_performed; /* cross-comparisons
* performed.
*/
vector<unsigned long int, /* Number of failed */
ALLOC(unsigned long int) > /* Büchi automaton */
buchi_intersection_check_failures; /* emptiness checks
vector<unsigned long int> /* Number of failed */
buchi_intersection_check_failures; /* Büchi automaton
* emptiness checks
* against the automata
* constructed from the
* negated formula
@ -337,9 +327,9 @@ struct TestStatistics
* algorithms.
*/
vector<unsigned long int, /* Number of Büchi */
ALLOC(unsigned long int) > /* automaton emptiness */
buchi_intersection_checks_performed; /* checks performed
vector<unsigned long int> /* Number of Büchi */
buchi_intersection_checks_performed; /* automaton emptiness
* checks performed
* against the automata
* constructed from the
* negated formula using
@ -357,9 +347,7 @@ struct TestStatistics
/* ========================================================================= */
inline AutomatonStats::AutomatonStats
(vector<Configuration::AlgorithmInformation,
ALLOC(Configuration::AlgorithmInformation) >::size_type
number_of_algorithms,
(vector<Configuration::AlgorithmInformation>::size_type number_of_algorithms,
StateSpace::size_type max_statespace_size) :
buchi_automaton(0), number_of_buchi_states(0),
number_of_buchi_transitions(0), number_of_acceptance_sets(0),
@ -481,9 +469,7 @@ AutomatonStats::buchiIntersectionCheckPerformed(unsigned long int algorithm)
/* ========================================================================= */
inline AlgorithmTestResults::AlgorithmTestResults
(vector<Configuration::AlgorithmInformation,
ALLOC(Configuration::AlgorithmInformation) >::size_type
number_of_algorithms,
(vector<Configuration::AlgorithmInformation>::size_type number_of_algorithms,
StateSpace::size_type max_statespace_size) :
consistency_check_result(-1), consistency_check_comparisons(0),
failed_consistency_check_comparisons(0),
@ -528,8 +514,7 @@ inline AlgorithmTestResults::~AlgorithmTestResults()
/* ========================================================================= */
inline TestStatistics::TestStatistics
(vector<TestStatistics, ALLOC(TestStatistics) >::size_type
number_of_algorithms) :
(vector<TestStatistics>::size_type number_of_algorithms) :
consistency_check_failures(0), consistency_checks_performed(0),
cross_comparison_mismatches(number_of_algorithms, 0),
initial_cross_comparison_mismatches(number_of_algorithms, 0),
@ -556,7 +541,6 @@ inline TestStatistics::TestStatistics
total_number_of_buchi_states[i] = 0;
total_number_of_buchi_transitions[i] = 0;
total_number_of_acceptance_sets[i] = 0;
total_number_of_msccs[i] = 0;
total_number_of_product_states[i] = 0;
total_number_of_product_transitions[i] = 0;
total_buchi_generation_time[i] = 0.0;

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -17,10 +17,6 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifdef __GNUC__
#pragma implementation
#endif /* __GNUC__ */
#include <config.h>
#include <csignal>
#include <cstdio>
@ -32,7 +28,6 @@
#include <strstream>
#endif /* HAVE_SSTREAM */
#include "DispUtil.h"
#include "ProductAutomaton.h"
#include "SharedTestData.h"
#include "StatDisplay.h"
#include "StringUtil.h"
@ -50,6 +45,13 @@
#include <readline/history.h>
#endif /* HAVE_READLINE */
#ifdef HAVE_ISATTY
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif /* HAVE_UNISTD_H */
#endif /* HAVE_ISATTY */
/******************************************************************************
*
@ -84,7 +86,7 @@ void executeUserCommands()
* ------------------------------------------------------------------------ */
{
string input_line;
vector<string, ALLOC(string) > input_tokens;
vector<string> input_tokens;
TokenType token;
bool formula_type = true;
@ -115,9 +117,6 @@ void executeUserCommands()
{
#endif /* HAVE_READLINE */
ProductAutomaton* product_automaton = 0;
pair<unsigned long int, bool> last_computed_product_automaton;
signal(SIGPIPE, SIG_IGN);
while (1)
@ -131,47 +130,86 @@ void executeUserCommands()
input_line = line;
else
{
round_info.cout << '\n';
round_info.cout.flush();
}
#else
round_info.cout << prompt;
round_info.cout.flush();
getline(cin, input_line, '\n');
if (cin.eof())
{
round_info.cout << '\n';
round_info.cout.flush();
cin.clear();
#endif /* HAVE_READLINE */
#ifdef HAVE_ISATTY
/*
* If standard input is not bound to a terminal, act on EOF as if the
* `continue' command had been issued. Otherwise act as if an empty
* line was given as input.
*/
if (!isatty(STDIN_FILENO))
input_line = "continue";
else
{
round_info.cout << '\n';
round_info.cout.flush();
}
#else
input_line = "continue";
round_info.cout << input_line << '\n';
round_info.cout.flush();
#endif /* HAVE_ISATTY */
}
#ifdef HAVE_ISATTY
if (!isatty(STDIN_FILENO))
{
round_info.cout << input_line << '\n';
round_info.cout.flush();
}
#endif /* HAVE_ISATTY */
#ifdef HAVE_READLINE
if (line != static_cast<char*>(0) /* line may be 0 on EOF */
&& input_line.find_first_not_of(" \t") != string::npos)
{
add_history(line);
free(line);
}
#endif /* HAVE_READLINE */
/*
* If the input line contains an unescaped pipe symbol ('|') outside
* quotes, extract an external command from the line.
*/
external_command = "";
string::size_type pipe_pos = input_line.find_first_of('|');
if (pipe_pos != string::npos)
string::size_type pos
= findInQuotedString(input_line, "|", OUTSIDE_QUOTES);
if (pos != string::npos)
{
string::size_type nonspace_pos
= input_line.find_first_not_of(" \t", pipe_pos + 1);
= input_line.find_first_not_of(" \t", pos + 1);
if (nonspace_pos != string::npos)
{
external_command = input_line.substr(nonspace_pos);
input_line = input_line.substr(0, pipe_pos);
input_line = input_line.substr(0, pos);
}
}
sliceString(input_line, " \t", input_tokens);
sliceString(substituteInQuotedString(input_line, " \t", "\n\n",
OUTSIDE_QUOTES),
"\n",
input_tokens);
user_break = false;
if (!input_tokens.empty() || !external_command.empty())
{
round_info.cout << '\n';
round_info.cout.flush();
}
if (!input_tokens.empty())
{
#ifdef HAVE_READLINE
add_history(line);
free(line);
#endif /* HAVE_READLINE */
round_info.cout << '\n';
round_info.cout.flush();
token = parseCommand(input_tokens[0]);
if (token == CONTINUE || token == SKIP)
@ -192,9 +230,7 @@ void executeUserCommands()
{
bool all_algorithms_disabled = true;
for (vector<Configuration::AlgorithmInformation,
ALLOC(Configuration::AlgorithmInformation) >
::const_iterator
for (vector<Configuration::AlgorithmInformation>::const_iterator
algorithm = configuration.algorithms.begin();
algorithm != configuration.algorithms.end();
++algorithm)
@ -379,8 +415,7 @@ void executeUserCommands()
case BUCHIANALYZE :
verifyArgumentCount(input_tokens, 2, 2);
printAutomatonAnalysisResults(*output_stream, indent,
parseNumber(input_tokens[1]),
parseNumber(input_tokens[2]));
input_tokens);
if (output_file != 0)
round_info.cout << " Büchi automaton intersection emptiness "
"check analysis";
@ -403,8 +438,8 @@ void executeUserCommands()
break;
case FORMULA :
verifyArgumentCount(input_tokens, 0, 0);
printFormula(*output_stream, indent, formula_type);
verifyArgumentCount(input_tokens, 0, 1);
printFormula(*output_stream, indent, formula_type, input_tokens);
if (output_file != 0)
round_info.cout << string(" ") + (formula_type
? "Formula"
@ -431,8 +466,7 @@ void executeUserCommands()
case RESULTANALYZE :
verifyArgumentCount(input_tokens, 2, 3);
printCrossComparisonAnalysisResults
(*output_stream, indent, formula_type, input_tokens,
product_automaton, last_computed_product_automaton);
(*output_stream, indent, formula_type, input_tokens);
if (output_file != 0)
round_info.cout << " Model checking result cross-comparison "
"analysis";
@ -474,8 +508,8 @@ void executeUserCommands()
break;
default :
throw CommandErrorException("Unknown command (`"
+ input_tokens[0] + "').");
throw CommandErrorException("Unknown command (`" + input_tokens[0]
+ "').");
}
if (output_string != 0)
@ -486,21 +520,17 @@ void executeUserCommands()
FILE* output_pipe = popen(external_command.c_str(), "w");
if (output_pipe == NULL)
throw ExecFailedException(external_command);
int status = fputs(outstring.c_str(), output_pipe);
if (status != EOF)
fflush(output_pipe);
fputs(outstring.c_str(), output_pipe);
pclose(output_pipe);
round_info.cout << '\n';
round_info.cout.flush();
if (status == EOF)
throw IOException("Error writing to pipe.");
}
else if (output_file != 0)
else
{
round_info.cout << string(redirection_info.second
? " appended"
: " written")
+ " to `" + redirection_info.first + "'.\n\n";
if (output_file != 0)
round_info.cout << string(redirection_info.second
? " appended"
: " written")
+ " to `" + redirection_info.first + "'.\n";
round_info.cout << '\n';
round_info.cout.flush();
}
}
@ -533,16 +563,6 @@ void executeUserCommands()
}
}
if (product_automaton != 0)
{
::DispUtil::printText
("<cleaning up memory allocated for product automaton>", 4, 2);
delete product_automaton;
::DispUtil::printText(" ok\n", 4);
}
#ifdef HAVE_READLINE
}
catch (...)
@ -555,7 +575,7 @@ void executeUserCommands()
#endif /* HAVE_READLINE */
signal(SIGPIPE, SIG_DFL);
}
}
/* ========================================================================= */
TokenType parseCommand(const string& token)
@ -570,19 +590,6 @@ TokenType parseCommand(const string& token)
*
* ------------------------------------------------------------------------- */
{
/*
* gcc versions prior to version 3 do not conform to the C++ standard in their
* support for the string::compare functions. Use a macro to fix this if
* necessary.
*/
#ifdef __GNUC__
#if __GNUC__ < 3
#define compare(start,end,str,dummy) compare(str,start,end)
#endif
#endif
TokenType token_type = UNKNOWN;
string::size_type len = token.length();
bool ambiguous = false;
@ -679,8 +686,19 @@ TokenType parseCommand(const string& token)
break;
case 'i' :
if (token.compare(1, len - 1, "nconsistencies", len - 1) == 0)
token_type = INCONSISTENCIES;
if (len < 2)
ambiguous = true;
else if (token[1] == 'm')
{
if (token.compare(2, len - 2, "plementations", len - 2) == 0)
token_type = ALGORITHMS;
}
else if (token[1] == 'n')
{
if (token.compare(2, len - 2, "consistencies", len - 2) == 0)
token_type = INCONSISTENCIES;
}
break;
case 'q' :
@ -760,6 +778,11 @@ TokenType parseCommand(const string& token)
}
break;
case 't' :
if (token.compare(1, len - 1, "ranslators", len - 1) == 0)
token_type = ALGORITHMS;
break;
case 'v' :
if (token.compare(1, len - 1, "erbosity", len - 1) == 0)
token_type = VERBOSITY;
@ -770,19 +793,12 @@ TokenType parseCommand(const string& token)
throw CommandErrorException("Ambiguous command.");
return token_type;
#ifdef __GNUC__
#if __GNUC__ < 3
#undef compare
#endif
#endif
}
/* ========================================================================= */
void verifyArgumentCount
(const vector<string, ALLOC(string) >& command,
vector<string, ALLOC(string) >::size_type min_arg_count,
vector<string, ALLOC(string) >::size_type max_arg_count)
(const vector<string>& command, vector<string>::size_type min_arg_count,
vector<string>::size_type max_arg_count)
/* ----------------------------------------------------------------------------
*
* Description: Verifies that the number of arguments given for a user
@ -805,8 +821,7 @@ void verifyArgumentCount
}
/* ========================================================================= */
pair<string, bool> parseRedirection
(vector<string, ALLOC(string) >& input_tokens)
pair<string, bool> parseRedirection(vector<string>& input_tokens)
/* ----------------------------------------------------------------------------
*
* Description: Tests whether the last argument to a user command specifies
@ -840,13 +855,13 @@ pair<string, bool> parseRedirection
if (token.length() > 2)
{
append = true;
filename = token.substr(2);
filename = unquoteString(token.substr(2));
input_tokens.pop_back();
}
}
else
{
filename = token.substr(1);
filename = unquoteString(token.substr(1));
input_tokens.pop_back();
}
}
@ -855,10 +870,9 @@ pair<string, bool> parseRedirection
{
string& token = *(input_tokens.rbegin() + 1);
if (token[0] == '>' && (token.length() == 1
|| (token.length() == 2 && token[1] == '>')))
if (token == ">" || token == ">>")
{
filename = input_tokens.back();
filename = unquoteString(input_tokens.back());
append = (token.length() == 2);
input_tokens.pop_back();
input_tokens.pop_back();
@ -870,7 +884,7 @@ pair<string, bool> parseRedirection
}
/* ========================================================================= */
bool parseFormulaType(vector<string, ALLOC(string) >& input_tokens)
bool parseFormulaType(vector<string>& input_tokens)
/* ----------------------------------------------------------------------------
*
* Description: Tests whether the first argument of a command specifies a
@ -894,8 +908,7 @@ bool parseFormulaType(vector<string, ALLOC(string) >& input_tokens)
{
formula_type = (input_tokens[1] != "-");
if (input_tokens[1].length() == 1
&& (input_tokens[1][0] == '+' || input_tokens[1][0] == '-'))
if (input_tokens[1] == "+" || input_tokens[1] == "-")
input_tokens.erase(input_tokens.begin());
}

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -65,22 +65,19 @@ TokenType parseCommand(const string& token); /* Translates a command
*/
void verifyArgumentCount /* Checks that the */
(const vector<string, ALLOC(string) >& /* number of arguments */
arguments, /* for a command is */
vector<string, ALLOC(string) >::size_type /* within given limits. */
min_arg_count,
vector<string, ALLOC(string) >::size_type
max_arg_count);
(const vector<string>& arguments, /* number of arguments */
vector<string>::size_type min_arg_count, /* for a command is */
vector<string>::size_type max_arg_count); /* within given limits. */
pair<string, bool> parseRedirection /* Checks whether an */
(vector<string, ALLOC(string) >& input_tokens); /* user command given
(vector<string>& input_tokens); /* user command given
* will require
* redirecting its
* output to a file.
*/
bool parseFormulaType /* Checks whether an */
(vector<string, ALLOC(string) >& input_tokens); /* user command
(vector<string>& input_tokens); /* user command
* specified a positive
* or a negative
* formula.

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -23,13 +23,17 @@
#include <config.h>
#include <deque>
#include <iostream>
#include <map>
#include <string>
#include <vector>
#include <utility>
#include "LbttAlloc.h"
#include "BuchiAutomaton.h"
#include "Configuration.h"
#include "ProductAutomaton.h"
#include "EdgeContainer.h"
#include "Graph.h"
#include "IntervalList.h"
#include "Product.h"
#include "StateSpace.h"
using namespace std;
@ -45,119 +49,102 @@ extern Configuration configuration;
namespace UserCommands
{
void computeProductAutomaton /* Computes a product */
(ProductAutomaton*& product_automaton, /* automaton. */
const BuchiAutomaton& buchi_automaton,
pair<unsigned long int, bool>& last_automaton,
const pair<unsigned long int, bool>&
new_automaton);
unsigned long int parseAlgorithmId /* Parses an */
(const string& id); /* implementation
* identifier.
*/
void parseAlgorithmId /* Parses a list of */
(const string& ids, IntervalList& algorithms); /* implementation
* identifiers.
*/
void printAlgorithmList /* Displays a list of */
(ostream& stream, int indent); /* algorithms used in
* the tests.
*/
void synchronizePrefixAndCycle /* Synchronizes a prefix */
(deque<Graph::Graph<GraphEdgeContainer> /* with a cycle in a */
::size_type, /* sequence of graph */
ALLOC(Graph::Graph<GraphEdgeContainer> /* state identifiers. */
::size_type) >&
prefix,
deque<Graph::Graph<GraphEdgeContainer>
::size_type,
ALLOC(Graph::Graph<GraphEdgeContainer>
::size_type) >&
cycle);
void printCrossComparisonAnalysisResults /* Analyzes a */
(ostream& stream, int indent, /* contradiction between */
bool formula_type, /* test results of two */
const vector<string, ALLOC(string) >& /* implementations. */
input_tokens,
ProductAutomaton*& product_automaton,
pair<unsigned long int, bool>&
last_product_automaton);
const vector<string>& input_tokens); /* implementations. */
void printConsistencyAnalysisResults /* Analyzes a */
(ostream& stream, int indent, /* contradicition in the */
const vector<string, ALLOC(string) >& /* model checking result */
input_tokens); /* consistency check for
const vector<string>& input_tokens); /* model checking result
* consistency check for
* an implementation.
*/
void printAutomatonAnalysisResults /* Analyzes a */
(ostream& stream, int indent, /* contradiction in the */
unsigned long int algorithm1, /* Büchi automata */
unsigned long int algorithm2); /* intersection
const vector<string>& input_tokens); /* Büchi automata
* intersection
* emptiness check.
*/
void printPath /* Displays information */
(ostream& stream, int indent, /* about a single */
const deque<StateSpace::size_type, /* system execution. */
ALLOC(StateSpace::size_type) >&
prefix,
const deque<StateSpace::size_type,
ALLOC(StateSpace::size_type) >&
cycle,
const StateSpace::Path& prefix, /* system execution. */
const StateSpace::Path& cycle,
const StateSpace& path);
void printAcceptingCycle /* Displays information */
(ostream& stream, int indent, /* a single automaton */
vector<Configuration::AlgorithmInformation, /* execution. */
ALLOC(Configuration::AlgorithmInformation) >
vector<Configuration::AlgorithmInformation> /* execution. */
::size_type
algorithm_id,
const deque<StateSpace::size_type,
ALLOC(StateSpace::size_type) >&
prefix,
const deque<StateSpace::size_type,
ALLOC(StateSpace::size_type) >&
cycle,
const BuchiAutomaton& automaton);
const BuchiAutomaton::Path& aut_prefix,
const BuchiAutomaton::Path& aut_cycle,
const BuchiAutomaton& automaton,
const StateSpace::Path& path_prefix,
const StateSpace::Path& path_cycle,
const StateSpace& statespace);
void printBuchiAutomaton /* Displays information */
(ostream& stream, int indent, /* about a Büchi */
bool formula_type, /* automaton. */
vector<string, ALLOC(string) >& input_tokens,
vector<string>& input_tokens,
Graph::GraphOutputFormat fmt);
void evaluateFormula /* Displays information */
(ostream& stream, int indent, /* about existence of */
bool formula_type, /* accepting system */
vector<string, ALLOC(string) >& input_tokens); /* executions. */
vector<string>& input_tokens); /* executions. */
void printFormula /* Displays a formula */
(ostream& stream, int indent, /* used for testing. */
bool formula_type);
bool formula_type,
const vector<string>& input_tokens);
void printCommandHelp /* Displays help about */
(ostream& stream, int indent, /* user commands. */
const vector<string, ALLOC(string) >&
input_tokens);
const vector<string>& input_tokens);
void printInconsistencies /* Lists the system */
(ostream& stream, int indent, /* states failing the */
vector<string, ALLOC(string) >& input_tokens); /* consistency check
vector<string>& input_tokens); /* consistency check
* for an algorihm.
*/
void printTestResults /* Displays the test */
(ostream& stream, int indent, /* results of the last */
vector<string, ALLOC(string) >& input_tokens); /* round performed. */
vector<string>& input_tokens); /* round performed. */
void printStateSpace /* Displays information */
(ostream& stream, int indent, /* about a state space. */
vector<string, ALLOC(string) >& input_tokens,
vector<string>& input_tokens,
Graph::GraphOutputFormat fmt);
void changeVerbosity /* Displays or changes */
(const vector<string, ALLOC(string) >& /* the verbosity of */
input_tokens); /* output. */
(const vector<string>& input_tokens); /* the verbosity of
* output.
*/
void changeAlgorithmState /* Enables or disables a */
(vector<string, ALLOC(string) >& input_tokens, /* set of algorithms */
bool enable); /* used in the tests. */
(vector<string>& input_tokens, bool enable); /* set of algorithms
* used in the tests.
*/
}

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -21,6 +21,9 @@
#include <csignal>
#include <cstdlib>
#include <ctime>
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif /* HAVE_SYS_TYPES_H */
#include <iostream>
#include <vector>
#ifdef HAVE_READLINE
@ -28,6 +31,11 @@
#include <readline/readline.h>
#include <readline/history.h>
#endif /* HAVE_READLINE */
#ifdef HAVE_ISATTY
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif /* HAVE_UNISTD_H */
#endif /* HAVE_ISATTY */
#include "LbttAlloc.h"
#include "Configuration.h"
#include "DispUtil.h"
@ -36,6 +44,7 @@
#include "Random.h"
#include "SharedTestData.h"
#include "StatDisplay.h"
#include "TempFsysName.h"
#include "TestOperations.h"
#include "TestRoundInfo.h"
#include "TestStatistics.h"
@ -43,17 +52,6 @@
using namespace std;
/******************************************************************************
*
* Handler for the SIGINT signal.
*
*****************************************************************************/
RETSIGTYPE breakHandler(int)
{
user_break = true;
}
/******************************************************************************
@ -92,12 +90,12 @@ TestRoundInfo round_info; /* Data structure for
* round.
*/
vector<AlgorithmTestResults, /* Test results for each */
ALLOC(AlgorithmTestResults) > /* individual algorithm. */
test_results;
vector<AlgorithmTestResults> test_results; /* Test results for each
* individual algorithm.
*/
vector<TestStatistics, ALLOC(TestStatistics) > /* Overall test */
final_statistics; /* statistics for each
vector<TestStatistics> final_statistics; /* Overall test
* statistics for each
* algorithm.
*/
@ -105,13 +103,124 @@ vector<TestStatistics, ALLOC(TestStatistics) > /* Overall test */
/******************************************************************************
*
* Functions for allocating and deallocating temporary file names.
*
*****************************************************************************/
static void allocateTempFilenames()
{
using SharedTestData::round_info;
round_info.formula_file_name[0] = new TempFsysName;
round_info.formula_file_name[0]->allocate("lbtt");
round_info.formula_file_name[1] = new TempFsysName;
round_info.formula_file_name[1]->allocate("lbtt");
round_info.automaton_file_name = new TempFsysName;
round_info.automaton_file_name->allocate("lbtt");
round_info.cout_capture_file = new TempFsysName;
round_info.cout_capture_file->allocate("lbtt");
round_info.cerr_capture_file = new TempFsysName;
round_info.cerr_capture_file->allocate("lbtt");
}
static void deallocateTempFilenames()
{
using SharedTestData::round_info;
if (round_info.formula_file_name[0] != 0)
{
delete round_info.formula_file_name[0];
round_info.formula_file_name[0] = 0;
}
if (round_info.formula_file_name[1] != 0)
{
delete round_info.formula_file_name[1];
round_info.formula_file_name[1] = 0;
}
if (round_info.automaton_file_name != 0)
{
delete round_info.automaton_file_name;
round_info.automaton_file_name = 0;
}
if (round_info.cout_capture_file != 0)
{
delete round_info.cout_capture_file;
round_info.cout_capture_file = 0;
}
if (round_info.cerr_capture_file != 0)
{
delete round_info.cerr_capture_file;
round_info.cerr_capture_file = 0;
}
}
/******************************************************************************
*
* Handler for the SIGINT signal.
*
*****************************************************************************/
static void breakHandler(int)
{
user_break = true;
}
/******************************************************************************
*
* Default handler for signals that terminate the process.
*
*****************************************************************************/
pid_t translator_process = 0; /* Process group for translator process */
static void abortHandler(int signum)
{
deallocateTempFilenames();
if (translator_process != 0 && kill(translator_process, 0) == 0)
kill(-translator_process, SIGTERM);
struct sigaction s;
s.sa_handler = SIG_DFL;
sigemptyset(&s.sa_mask);
s.sa_flags = 0;
sigaction(signum, &s, static_cast<struct sigaction*>(0));
raise(signum);
}
/******************************************************************************
*
* Function for installing signal handlers.
*
*****************************************************************************/
static void installSignalHandler(int signum, void (*handler)(int))
{
struct sigaction s;
sigaction(signum, static_cast<struct sigaction*>(0), &s);
if (s.sa_handler != SIG_IGN)
{
s.sa_handler = handler;
sigemptyset(&s.sa_mask);
s.sa_flags = 0;
sigaction(signum, &s, static_cast<struct sigaction*>(0));
}
}
/******************************************************************************
*
* Test loop.
*
*****************************************************************************/
int testLoop()
bool testLoop()
{
using namespace DispUtil;
using namespace SharedTestData;
@ -119,9 +228,6 @@ int testLoop()
using namespace StringUtil;
using namespace TestOperations;
/* Return code. Will be set to 1 if any of the test fails. */
int exit_status = 0;
const Configuration::GlobalConfiguration& global_options
= configuration.global_options;
@ -139,13 +245,6 @@ int testLoop()
? round_info.next_round_to_run
: global_options.number_of_rounds + 1);
if (tmpnam(round_info.formula_file_name[0]) == 0
|| tmpnam(round_info.formula_file_name[1]) == 0
|| tmpnam(round_info.automaton_file_name) == 0
|| tmpnam(round_info.cout_capture_file) == 0
|| tmpnam(round_info.cerr_capture_file) == 0)
throw Exception("unable to allocate names for temporary files");
/*
* If a name for the error log file was given in the configuration, create
* the file.
@ -173,9 +272,9 @@ int testLoop()
try
{
round_info.transcript_file << "lbtt " PACKAGE_VERSION
" error log file, created on "
+ string(ctime(&current_time))
+ '\n';
" error log file, created on "
+ string(ctime(&current_time))
+ '\n';
configuration.print(round_info.transcript_file);
}
@ -187,16 +286,24 @@ int testLoop()
/*
* If a formula file name was given in the configuration, open the file for
* reading.
* reading. The special filename "-" refers to the standard input.
*/
try
{
if (!global_options.formula_input_filename.empty())
openFile(global_options.formula_input_filename.c_str(),
round_info.formula_input_file,
ios::in,
0);
{
if (global_options.formula_input_filename == "-")
round_info.formula_input_stream = &cin;
else
{
openFile(global_options.formula_input_filename.c_str(),
round_info.formula_input_file,
ios::in,
0);
round_info.formula_input_stream = &round_info.formula_input_file;
}
}
}
catch (const FileOpenException& e)
{
@ -224,19 +331,6 @@ int testLoop()
formula_random_state[i] = static_cast<short int>(LRAND(0, LONG_MAX));
#endif /* HAVE_RAND48 */
/*
* If using paths as state spaces, include the internal model checking
* algorithm in the set of algorithms.
*/
if (global_options.statespace_generation_mode & Configuration::PATH)
{
Configuration::AlgorithmInformation lbtt_info
= {new string("lbtt"), new string(), new string(), true};
configuration.algorithms.push_back(lbtt_info);
}
/*
* Intialize the vector for storing the test results for each
* implementation and the vector for collecting overall test statistics for
@ -265,30 +359,18 @@ int testLoop()
for (round_info.current_round = 1;
!round_info.abort
&& round_info.current_round <= global_options.number_of_rounds;
&& round_info.current_round <= global_options.number_of_rounds;
++round_info.current_round)
{
user_break = false;
round_info.error = false;
round_info.skip
= (round_info.current_round < round_info.next_round_to_run);
if (!round_info.skip)
{
if (!printText(string("Round ") + toString(round_info.current_round)
+ " of " + toString(global_options.number_of_rounds)
+ "\n\n",
2))
{
if (global_options.verbosity == 1)
{
if (round_info.current_round > 1)
round_info.cout << ' ';
round_info.cout << round_info.current_round;
round_info.cout.flush();
}
}
}
printText(string("Round ") + toString(round_info.current_round)
+ " of " + toString(global_options.number_of_rounds) + "\n\n",
2);
try
{
@ -299,7 +381,7 @@ int testLoop()
round_info.fresh_statespace
= ((global_options.do_comp_test || global_options.do_cons_test)
&& round_info.next_round_to_change_statespace
== round_info.current_round);
== round_info.current_round);
if (round_info.fresh_statespace)
{
@ -307,13 +389,13 @@ int testLoop()
seed48(statespace_random_state);
for (int i = 0; i < 3; i++)
statespace_random_state[i] = static_cast<short int>
(LRAND(0, LONG_MAX));
(LRAND(0, LONG_MAX));
#else
SRAND(global_options.statespace_random_seed);
configuration.global_options.statespace_random_seed
= LRAND(0, RAND_MAX);
#endif /* HAVE_RAND48 */
if (global_options.statespace_change_interval == 0)
round_info.next_round_to_change_statespace
= global_options.number_of_rounds + 1;
@ -321,8 +403,7 @@ int testLoop()
round_info.next_round_to_change_statespace
+= global_options.statespace_change_interval;
for (vector<AlgorithmTestResults, ALLOC(AlgorithmTestResults) >
::iterator it = test_results.begin();
for (vector<AlgorithmTestResults>::iterator it = test_results.begin();
it != test_results.end();
++it)
it->emptinessReset();
@ -352,7 +433,7 @@ int testLoop()
*/
round_info.fresh_formula
= (round_info.next_round_to_change_formula
= (round_info.next_round_to_change_formula
== round_info.current_round);
if (round_info.fresh_formula)
@ -375,8 +456,7 @@ int testLoop()
round_info.formula_in_file[0] = round_info.formula_in_file[1] = false;
for (vector<AlgorithmTestResults, ALLOC(AlgorithmTestResults) >
::iterator it = test_results.begin();
for (vector<AlgorithmTestResults>::iterator it = test_results.begin();
it != test_results.end();
++it)
it->fullReset();
@ -387,8 +467,8 @@ int testLoop()
{
try
{
generateFormulae(round_info.formula_input_file.is_open()
? &round_info.formula_input_file
generateFormulae(!global_options.formula_input_filename.empty()
? round_info.formula_input_stream
: 0);
}
catch (const FormulaGenerationException&)
@ -402,7 +482,7 @@ int testLoop()
if (user_break)
{
printText("[User break]\n\n", 2, 4);
printText("[User break]\n\n", 1, 4);
throw UserBreakException();
}
@ -417,12 +497,17 @@ int testLoop()
if (global_options.statespace_generation_mode & Configuration::PATH
&& (global_options.do_cons_test || global_options.do_comp_test)
&& (!test_results[round_info.number_of_translators].
automaton_stats[0].emptiness_check_performed))
&& (!test_results[round_info.number_of_translators - 1].
automaton_stats[0].emptiness_check_performed)
&& configuration.algorithms[round_info.number_of_translators - 1].
enabled)
verifyFormulaOnPath();
if (!round_info.error)
{
{
if (global_options.verbosity == 2)
::StatDisplay::printStatTableHeader(round_info.cout, 4);
unsigned long int num_enabled_implementations = 0;
for (unsigned long int algorithm_id = 0;
@ -434,81 +519,61 @@ int testLoop()
num_enabled_implementations++;
if (configuration.isInternalAlgorithm(algorithm_id))
continue;
printText(configuration.algorithmString(algorithm_id) + '\n',
2, 4);
3, 4);
for (int counter = 0; counter < 2; counter++)
{
if (user_break)
{
printText("[User break]\n\n", 2, 4);
printText("[User break]\n\n", 1, 4);
throw UserBreakException();
}
printText(string(counter == 1 ? "Negated" : "Positive")
+ " formula:\n",
2,
6);
if (global_options.verbosity == 1
|| global_options.verbosity == 2)
{
if (counter == 1)
round_info.cout << '\n';
if (global_options.verbosity == 1)
round_info.cout << round_info.current_round << ' ';
else
round_info.cout << string(4, ' ');
changeStreamFormatting(cout, 2, 0, ios::right);
round_info.cout << algorithm_id << ' ';
restoreStreamFormatting(cout);
round_info.cout << (counter == 0 ? '+' : '-') << ' ';
round_info.cout.flush();
}
else
printText(string(counter == 1 ? "Negated" : "Positive")
+ " formula:\n",
3,
6);
try
{
try
{
round_info.product_automaton = 0;
/*
* Generate a Büchi automaton using the current algorithm.
* `counter' determines the formula which is to be
* translated into an automaton; 0 denotes the positive and
* 1 the negated formula.
*/
generateBuchiAutomaton(counter, algorithm_id);
if (global_options.do_cons_test || global_options.do_comp_test)
{
/*
* Generate a Büchi automaton using the current algorithm.
* `counter' determines the formula which is to be
* translated into an automaton; 0 denotes the positive and
* 1 the negated formula.
* Find the system states from which an accepting
* execution cycle can be reached by checking the product
* automaton for emptiness.
*/
generateBuchiAutomaton(counter, algorithm_id);
if (global_options.do_cons_test
|| global_options.do_comp_test)
{
/*
* Compute the product of the Büchi automaton with the
* state space.
*/
generateProductAutomaton(counter, algorithm_id);
/*
* Find the system states from which an accepting
* execution cycle can be reached by checking the product
* automaton for emptiness.
*/
performEmptinessCheck(counter, algorithm_id);
/*
* If a product automaton was computed in this test round
* (it might have not if the emptiness checking result was
* already available), release the memory allocated for
* the product automaton.
*/
if (round_info.product_automaton != 0)
{
printText("<deallocating memory>", 4, 8);
delete round_info.product_automaton;
round_info.product_automaton = 0;
printText(" ok\n", 4);
}
}
}
catch (...)
{
if (round_info.product_automaton != 0)
{
delete round_info.product_automaton;
round_info.product_automaton = 0;
}
throw;
performEmptinessCheck(counter, algorithm_id);
}
}
catch (const BuchiAutomatonGenerationException&)
@ -544,7 +609,13 @@ int testLoop()
emptiness_check_performed)
performConsistencyCheck(algorithm_id);
printText("\n", 2);
printText("\n", 1);
}
if (global_options.verbosity == 2)
{
round_info.cout << '\n';
round_info.cout.flush();
}
if (num_enabled_implementations > 0)
@ -556,10 +627,7 @@ int testLoop()
* results obtained using the different algorithms.
*/
if (num_enabled_implementations >= 2
|| (num_enabled_implementations == 1
&& global_options.statespace_generation_mode
& Configuration::PATH))
if (num_enabled_implementations >= 2)
compareResults();
}
@ -590,33 +658,22 @@ int testLoop()
round_info.next_round_to_stop = round_info.current_round;
}
if (round_info.error)
exit_status = 1;
/*
* Determine from the program configuration and the error status whether
* the testing should be paused to wait for user commands.
*/
if (round_info.error)
round_info.all_tests_successful = false;
if (round_info.error
&& global_options.interactive == Configuration::ONERROR)
round_info.next_round_to_stop = round_info.current_round;
if (round_info.next_round_to_stop == round_info.current_round)
{
if (global_options.verbosity == 1)
{
round_info.cout << '\n';
round_info.cout.flush();
}
::UserCommandInterface::executeUserCommands();
}
}
for (int i = 0; i < 2; i++)
removeFile(round_info.formula_file_name[i], 2);
if (round_info.path_iterator != 0)
delete round_info.path_iterator;
else if (round_info.statespace != 0)
@ -628,8 +685,7 @@ int testLoop()
::Ltl::LtlFormula::destruct(round_info.formulae[f]);
}
for (vector<AlgorithmTestResults, ALLOC(AlgorithmTestResults) >
::iterator it = test_results.begin();
for (vector<AlgorithmTestResults>::iterator it = test_results.begin();
it != test_results.end();
++it)
it->fullReset();
@ -661,19 +717,19 @@ int testLoop()
time(&current_time);
round_info.transcript_file << "lbtt error log closed on "
+ string(ctime(&current_time))
+ string(ctime(&current_time))
<< endl;
round_info.transcript_file.close();
}
if (global_options.verbosity >= 1)
if (global_options.verbosity >= 2)
printCollectiveStats(cout, 0);
if (round_info.formula_input_file.is_open())
round_info.formula_input_file.close();
return exit_status;
return round_info.all_tests_successful;
}
@ -686,7 +742,7 @@ int testLoop()
int main(int argc, char* argv[])
{
try
try
{
configuration.read(argc, argv);
}
@ -697,15 +753,35 @@ int main(int argc, char* argv[])
cerr << ":" << configuration.global_options.cfg_filename << ":"
<< e.line_info;
cerr << ": " << e.what() << endl;
exit(-1);
exit(2);
}
#ifdef HAVE_ISATTY
if (configuration.global_options.formula_input_filename == "-"
&& !isatty(STDIN_FILENO))
{
configuration.global_options.interactive = Configuration::NEVER;
configuration.global_options.handle_breaks = false;
}
#endif /* HAVE_ISATTY */
if (configuration.global_options.verbosity >= 3)
configuration.print(cout);
user_break = false;
if (configuration.global_options.interactive != Configuration::NEVER)
signal(SIGINT, breakHandler);
installSignalHandler(SIGHUP, abortHandler);
installSignalHandler(SIGINT,
configuration.global_options.handle_breaks
? breakHandler
: abortHandler);
installSignalHandler(SIGQUIT, abortHandler);
installSignalHandler(SIGABRT, abortHandler);
installSignalHandler(SIGPIPE, abortHandler);
installSignalHandler(SIGALRM, abortHandler);
installSignalHandler(SIGTERM, abortHandler);
installSignalHandler(SIGUSR1, abortHandler);
installSignalHandler(SIGUSR2, abortHandler);
#ifdef HAVE_OBSTACK_H
obstack_alloc_failed_handler = &ObstackAllocator::failure;
@ -715,18 +791,28 @@ int main(int argc, char* argv[])
using_history();
#endif /* HAVE_READLINE */
try
try
{
return testLoop();
allocateTempFilenames();
if (!testLoop())
{
deallocateTempFilenames();
return 1;
}
}
catch (const Exception& e)
{
cerr << argv[0] << ": " << e.what() << endl;
exit(-1);
deallocateTempFilenames();
cerr << endl << argv[0] << ": " << e.what() << endl;
exit(3);
}
catch (const bad_alloc&)
{
cerr << argv[0] << ": out of memory" << endl;
exit(-1);
deallocateTempFilenames();
cerr << endl << argv[0] << ": out of memory" << endl;
exit(3);
}
deallocateTempFilenames();
return 0;
}

View file

@ -180,11 +180,11 @@ int main(int argc, char** argv)
case OPT_VERSION :
cout << "lbtt-translate " PACKAGE_VERSION "\n"
"lbtt-translate is free software; you may change and "
"redistribute it under the\n"
"terms of the GNU General Public License. lbtt-translate "
"comes with NO WARRANTY.\n"
"See the file COPYING for details.\n";
"lbtt-translate is free software; you may change and "
"redistribute it under the\n"
"terms of the GNU General Public License. lbtt-translate "
"comes with NO WARRANTY.\n"
"See the file COPYING for details.\n";
exit(0);
break;

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -20,10 +20,6 @@
#ifndef TRANSLATE_H
#define TRANSLATE_H
#ifdef __GNUC__
#pragma interface
#endif /* __GNUC__ */
#include <config.h>
#include <string>