fix status of lbtt's subtree. Apparently it was messed up during the cvsimport
This commit is contained in:
parent
17f76e371f
commit
91df6cab77
77 changed files with 16272 additions and 6019 deletions
|
|
@ -1 +1 @@
|
||||||
lbtt was written by Heikki Tauriainen <heikki.tauriainen@hut.fi>
|
Heikki Tauriainen <heikki.tauriainen@tkk.fi>
|
||||||
|
|
|
||||||
|
|
@ -16,13 +16,13 @@
|
||||||
Update description of the --formulafile command line option.
|
Update description of the --formulafile command line option.
|
||||||
(Configuration::print): Do not display a file name when reading
|
(Configuration::print): Do not display a file name when reading
|
||||||
formulas from standard input.
|
formulas from standard input.
|
||||||
|
|
||||||
* src/SpotWrapper.h, src/SpotWrapper.cc: Merge files from
|
* src/SpotWrapper.h, src/SpotWrapper.cc: Merge files from
|
||||||
Spot 0.2 (contributed by Alexandre Duret-Lutz); remove #pragma
|
Spot 0.2 (contributed by Alexandre Duret-Lutz); remove #pragma
|
||||||
definitions.
|
definitions.
|
||||||
* src/ExternalTranslator.h, src/Makefile.in, src/translate.cc:
|
* src/ExternalTranslator.h, src/Makefile.in, src/translate.cc:
|
||||||
Merge changes from Spot 0.2 (contributed by Alexandre Duret-Lutz).
|
Merge changes from Spot 0.2 (contributed by Alexandre Duret-Lutz).
|
||||||
|
|
||||||
* doc/lbtt.texi: Fix typo in URL of the FormulaOptions block
|
* doc/lbtt.texi: Fix typo in URL of the FormulaOptions block
|
||||||
generator. Update version, add documentation and references about
|
generator. Update version, add documentation and references about
|
||||||
support for Spot. Describe the new semantics of the --formulafile
|
support for Spot. Describe the new semantics of the --formulafile
|
||||||
|
|
@ -124,7 +124,7 @@
|
||||||
log file.
|
log file.
|
||||||
|
|
||||||
* configure.ac: Add test for the setsid library function.
|
* configure.ac: Add test for the setsid library function.
|
||||||
|
|
||||||
2004-07-31 Heikki Tauriainen <heikki.tauriainen@hut.fi>
|
2004-07-31 Heikki Tauriainen <heikki.tauriainen@hut.fi>
|
||||||
|
|
||||||
* src/Product.h (ProductEdge::edge_1, ProductEdge::edge_2):
|
* src/Product.h (ProductEdge::edge_1, ProductEdge::edge_2):
|
||||||
|
|
@ -178,7 +178,7 @@
|
||||||
* doc/texinfo.tex: New upstream version.
|
* doc/texinfo.tex: New upstream version.
|
||||||
* doc/lbtt.texi: Update to edition 1.1.0.
|
* doc/lbtt.texi: Update to edition 1.1.0.
|
||||||
* NEWS: Update.
|
* NEWS: Update.
|
||||||
|
|
||||||
2004-07-02 Heikki Tauriainen <heikki.tauriainen@hut.fi>
|
2004-07-02 Heikki Tauriainen <heikki.tauriainen@hut.fi>
|
||||||
|
|
||||||
* src/UserCommandReader.cc (parseCommand): Recognize
|
* src/UserCommandReader.cc (parseCommand): Recognize
|
||||||
|
|
@ -257,13 +257,13 @@
|
||||||
New files for providing specializations of the general product
|
New files for providing specializations of the general product
|
||||||
computation operation applicable to Büchi automata and state
|
computation operation applicable to Büchi automata and state
|
||||||
spaces.
|
spaces.
|
||||||
|
|
||||||
* src/Makefile.am: Add BuchiProduct.h, BuchiProduct.cc,
|
* src/Makefile.am: Add BuchiProduct.h, BuchiProduct.cc,
|
||||||
Product.h, SccCollection.h and StateSpaceProduct.h to
|
Product.h, SccCollection.h and StateSpaceProduct.h to
|
||||||
lbtt_SOURCES.
|
lbtt_SOURCES.
|
||||||
Remove ProductAutomaton.h, ProductAutomaton.cc and
|
Remove ProductAutomaton.h, ProductAutomaton.cc and
|
||||||
SccIterator.h from lbtt_SOURCES.
|
SccIterator.h from lbtt_SOURCES.
|
||||||
|
|
||||||
* src/Graph.h.in (Graph::EdgeContainerType, Graph::Path): New
|
* src/Graph.h.in (Graph::EdgeContainerType, Graph::Path): New
|
||||||
type definitions.
|
type definitions.
|
||||||
(Graph::PathElement): New class.
|
(Graph::PathElement): New class.
|
||||||
|
|
@ -337,7 +337,7 @@
|
||||||
(printAcceptingCycle): Update parameter list and documentation.
|
(printAcceptingCycle): Update parameter list and documentation.
|
||||||
Display all relevant information about an accepting execution
|
Display all relevant information about an accepting execution
|
||||||
of a Büchi automaton.
|
of a Büchi automaton.
|
||||||
|
|
||||||
2004-05-18 Heikki Tauriainen <heikki.tauriainen@hut.fi>
|
2004-05-18 Heikki Tauriainen <heikki.tauriainen@hut.fi>
|
||||||
|
|
||||||
* configure.ac (YACC): Do not add `-d' here.
|
* configure.ac (YACC): Do not add `-d' here.
|
||||||
|
|
@ -365,7 +365,7 @@
|
||||||
|
|
||||||
* src/NeverClaim-lex.ll: Add %option nounput to avoid a
|
* src/NeverClaim-lex.ll: Add %option nounput to avoid a
|
||||||
compiler warning.
|
compiler warning.
|
||||||
|
|
||||||
* src/ExternalTranslator.h: Include the TempFsysName.h header.
|
* src/ExternalTranslator.h: Include the TempFsysName.h header.
|
||||||
(ExternalTranslator::TempFileObject): Remove.
|
(ExternalTranslator::TempFileObject): Remove.
|
||||||
(ExternalTranslator::registerTempFileObject): Change
|
(ExternalTranslator::registerTempFileObject): Change
|
||||||
|
|
@ -475,7 +475,7 @@
|
||||||
command line option.
|
command line option.
|
||||||
(printCommandHelp): Update the description of the `formula'
|
(printCommandHelp): Update the description of the `formula'
|
||||||
command.
|
command.
|
||||||
|
|
||||||
* src/UserCommandReader.cc (executeUserCommands): Accept one
|
* src/UserCommandReader.cc (executeUserCommands): Accept one
|
||||||
optional parameter for the `formula' command. Pass the input
|
optional parameter for the `formula' command. Pass the input
|
||||||
tokens as an additional parameter in the printFormula call.
|
tokens as an additional parameter in the printFormula call.
|
||||||
|
|
@ -505,7 +505,7 @@
|
||||||
* src/TempFsysName.h, src/TempFsysName.cc New files.
|
* src/TempFsysName.h, src/TempFsysName.cc New files.
|
||||||
* src/Makefile.am: Add TempFsysName.h and TempFsysName.cc to
|
* src/Makefile.am: Add TempFsysName.h and TempFsysName.cc to
|
||||||
lbtt_SOURCES.
|
lbtt_SOURCES.
|
||||||
|
|
||||||
* src/TestRoundInfo.h: Include the TempFsysName.h header.
|
* src/TestRoundInfo.h: Include the TempFsysName.h header.
|
||||||
(TestRoundInfo::formula_file_name[])
|
(TestRoundInfo::formula_file_name[])
|
||||||
(TestRoundInfo::automaton_file_name)
|
(TestRoundInfo::automaton_file_name)
|
||||||
|
|
@ -513,7 +513,7 @@
|
||||||
TempFsysName*.
|
TempFsysName*.
|
||||||
(TestRoundInfo::TestRoundInfo): Initialize temporary file
|
(TestRoundInfo::TestRoundInfo): Initialize temporary file
|
||||||
name pointers to 0.
|
name pointers to 0.
|
||||||
|
|
||||||
* src/main.cc: Include the TempFsysName.h header.
|
* src/main.cc: Include the TempFsysName.h header.
|
||||||
(allocateTempFilenames, deallocateTempFilenames): New functions.
|
(allocateTempFilenames, deallocateTempFilenames): New functions.
|
||||||
(abortHandler): New signal handler.
|
(abortHandler): New signal handler.
|
||||||
|
|
@ -858,7 +858,7 @@
|
||||||
after colon in output. Return 3 if an unexpected exception
|
after colon in output. Return 3 if an unexpected exception
|
||||||
occurred. In this case print an additional newline before the
|
occurred. In this case print an additional newline before the
|
||||||
error message.
|
error message.
|
||||||
|
|
||||||
2004-02-19 Heikki Tauriainen <heikki.tauriainen@hut.fi>
|
2004-02-19 Heikki Tauriainen <heikki.tauriainen@hut.fi>
|
||||||
|
|
||||||
* src/StringUtil.h: Include the IntervalList.h header.
|
* src/StringUtil.h: Include the IntervalList.h header.
|
||||||
|
|
@ -926,7 +926,7 @@
|
||||||
Reformat the automata file format section to avoid overfull lines
|
Reformat the automata file format section to avoid overfull lines
|
||||||
in dvi generation.
|
in dvi generation.
|
||||||
Fix description of the Algorithm block used with lbtt-translate.
|
Fix description of the Algorithm block used with lbtt-translate.
|
||||||
|
|
||||||
* doc/testprocedure.txt, doc/intersectioncheck.txt: Add initial
|
* doc/testprocedure.txt, doc/intersectioncheck.txt: Add initial
|
||||||
newlines.
|
newlines.
|
||||||
|
|
||||||
|
|
|
||||||
180
lbtt/NEWS
180
lbtt/NEWS
|
|
@ -1,5 +1,5 @@
|
||||||
lbtt NEWS -- history of user-visible changes. 01 Oct 2002
|
lbtt NEWS -- history of user-visible changes. 30 Aug 2005
|
||||||
Copyright (C) 2002 Heikki Tauriainen
|
Copyright (C) 2005 Heikki Tauriainen
|
||||||
|
|
||||||
Permission is granted to anyone to make or distribute verbatim copies
|
Permission is granted to anyone to make or distribute verbatim copies
|
||||||
of this document as received, in any medium, provided that the
|
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
|
provided also that they carry prominent notices stating who last
|
||||||
changed them.
|
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
|
Version 1.0.1
|
||||||
|
|
||||||
|
|
|
||||||
22
lbtt/README
22
lbtt/README
|
|
@ -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
|
expressed in propositional linear temporal logic (LTL) into
|
||||||
Büchi automata. The goal of the tool is to assist in the
|
Büchi automata. The goal of the tool is to assist implementing
|
||||||
correct implementation of LTL-to-Büchi translation algorithms
|
LTL-to-Büchi translation algorithms correctly by providing an
|
||||||
by providing an automated testing environment for LTL-to-Büchi
|
automated testing environment for LTL-to-Büchi translators.
|
||||||
translators. Additionally, the testing environment can be used
|
Additionally, the testing environment can be used for very basic
|
||||||
for very basic profiling of different LTL-to-Büchi translators
|
profiling of different LTL-to-Büchi translators to evaluate their
|
||||||
to evaluate their performance.
|
performance.
|
||||||
|
|
||||||
The latest version of the program is available at
|
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
|
lbtt is free software, you may change and redistribute it under
|
||||||
the terms of the GNU General Public License. lbtt comes with
|
the terms of the GNU General Public License. lbtt comes with
|
||||||
NO WARRANTY. See the file COPYING for details.
|
NO WARRANTY. See the file COPYING for details.
|
||||||
|
|
||||||
|
|
||||||
Quick installation instructions:
|
Brief installation instructions:
|
||||||
--------------------------------
|
--------------------------------
|
||||||
|
|
||||||
The basic procedure to build lbtt, the associated tools
|
The basic procedure to build lbtt, the associated tools
|
||||||
|
|
@ -82,4 +82,4 @@ Documentation:
|
||||||
|
|
||||||
The documentation is also available in various formats
|
The documentation is also available in various formats
|
||||||
at the program's home page at
|
at the program's home page at
|
||||||
<http://www.tcs.hut.fi/%7Ehtauriai/lbtt/>.
|
<http://www.tcs.hut.fi/Software/lbtt/>.
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
# Process this file with autoconf to produce a configure script.
|
# Process this file with autoconf to produce a configure script.
|
||||||
|
|
||||||
AC_PREREQ([2.59])
|
AC_PREREQ([2.59])
|
||||||
AC_INIT([lbtt], [1.1.1], [heikki.tauriainen@hut.fi])
|
AC_INIT([lbtt], [1.2.0], [heikki.tauriainen@tkk.fi])
|
||||||
AC_REVISION([Revision: 1.5])
|
AC_REVISION([Revision: 1.8])
|
||||||
AC_CONFIG_SRCDIR([src/main.cc])
|
AC_CONFIG_SRCDIR([src/main.cc])
|
||||||
AC_CONFIG_HEADERS([config.h])
|
AC_CONFIG_HEADERS([config.h])
|
||||||
AM_INIT_AUTOMAKE
|
AM_INIT_AUTOMAKE
|
||||||
|
|
@ -124,52 +124,6 @@ AC_CHECK_HEADERS(
|
||||||
|
|
||||||
# Checks for typedefs, structures, and compiler characteristics.
|
# 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_LANG(C)
|
||||||
|
|
||||||
AC_CHECK_TYPES(
|
AC_CHECK_TYPES(
|
||||||
|
|
@ -191,7 +145,7 @@ AC_C_INLINE
|
||||||
# Checks for library functions.
|
# Checks for library functions.
|
||||||
|
|
||||||
AC_CHECK_FUNCS(
|
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_MSG_ERROR([missing one of the library functions required for compilation])])
|
||||||
AC_CHECK_FUNCS([strsignal isatty getopt_long])
|
AC_CHECK_FUNCS([strsignal isatty getopt_long])
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
|
||||||
,,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
,,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||||
: LTL formula `f' :_____ : Negated LTL formula `!f' :
|
: LTL formula `f' :_____ : Negated LTL formula `!f' :
|
||||||
'''''''T''''''T'''' \ ___'''''''T'''''''''''T''''''''
|
'''''''T''''''T'''' \ ___'''''''T'''''''''''T''''''''
|
||||||
|
|
|
||||||
1268
lbtt/doc/lbtt.texi
1268
lbtt/doc/lbtt.texi
File diff suppressed because it is too large
Load diff
|
|
@ -1,3 +1,4 @@
|
||||||
|
|
||||||
,,,,,,,,,,,,,,,
|
,,,,,,,,,,,,,,,
|
||||||
: State space :
|
: State space :
|
||||||
'''''''''''''''
|
'''''''''''''''
|
||||||
|
|
|
||||||
7482
lbtt/doc/texinfo.tex
Normal file
7482
lbtt/doc/texinfo.tex
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 1999, 2000, 2001, 2002
|
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* 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.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
#pragma implementation
|
|
||||||
#endif /* __GNUC__ */
|
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#ifdef HAVE_SSTREAM
|
#ifdef HAVE_SSTREAM
|
||||||
#include <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)
|
for (i = 0; i < bsize && bits[i] == 0; ++i)
|
||||||
;
|
;
|
||||||
|
|
||||||
if (i == max_count)
|
if (i == bsize)
|
||||||
return max_count;
|
return max_count;
|
||||||
|
|
||||||
unsigned char c = bits[i];
|
unsigned char c = bits[i];
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 1999, 2000, 2001, 2002
|
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
|
@ -20,10 +20,6 @@
|
||||||
#ifndef BITARRAY_H
|
#ifndef BITARRAY_H
|
||||||
#define BITARRAY_H
|
#define BITARRAY_H
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
#pragma interface
|
|
||||||
#endif /* __GNUC__ */
|
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <string>
|
#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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 1999, 2000, 2001, 2002
|
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 1999, 2000, 2001, 2002
|
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* 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.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
#pragma implementation
|
|
||||||
#endif /* __GNUC__ */
|
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <stack>
|
#include <stack>
|
||||||
|
|
@ -96,7 +92,9 @@ BuchiAutomaton::BuchiAutomaton(const BuchiAutomaton& automaton) :
|
||||||
++transition)
|
++transition)
|
||||||
connect(state,
|
connect(state,
|
||||||
static_cast<const BuchiTransition*>(*transition)->targetNode(),
|
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(),
|
operator[](state).acceptanceSets().copy(automaton[state].acceptanceSets(),
|
||||||
number_of_acceptance_sets);
|
number_of_acceptance_sets);
|
||||||
|
|
@ -133,7 +131,9 @@ BuchiAutomaton& BuchiAutomaton::operator=(const BuchiAutomaton& automaton)
|
||||||
++transition)
|
++transition)
|
||||||
connect(state,
|
connect(state,
|
||||||
static_cast<const BuchiTransition*>(*transition)->targetNode(),
|
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
|
operator[](state).acceptanceSets().copy
|
||||||
(automaton[state].acceptanceSets(), number_of_acceptance_sets);
|
(automaton[state].acceptanceSets(), number_of_acceptance_sets);
|
||||||
|
|
@ -194,113 +194,13 @@ BuchiAutomaton::size_type BuchiAutomaton::expand(size_type node_count)
|
||||||
return nodes.size() - 1;
|
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)
|
void BuchiAutomaton::read(istream& input_stream)
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* Description: Reads an automaton description (which may represent a
|
* Description: Reads an automaton description (which may represent a
|
||||||
* generalized Büchi automaton) from a stream and stores it
|
* generalized Büchi automaton) from a stream and stores it
|
||||||
* into the automaton object, converting it to a regular
|
* into the automaton object.
|
||||||
* Büchi automaton if necessary.
|
|
||||||
*
|
*
|
||||||
* Argument: input_stream -- A reference to an input stream.
|
* Argument: input_stream -- A reference to an input stream.
|
||||||
*
|
*
|
||||||
|
|
@ -316,20 +216,63 @@ void BuchiAutomaton::read(istream& input_stream)
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
/*
|
/* Read the number of states in the generalized Büchi automaton. */
|
||||||
* Read in the number of states in the generalized Büchi automaton.
|
|
||||||
*/
|
|
||||||
|
|
||||||
einput_stream >> number_of_states;
|
einput_stream >> number_of_states;
|
||||||
|
|
||||||
/*
|
/* If the automaton is empty, do nothing. */
|
||||||
* If the automaton is empty, do nothing.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (number_of_states == 0)
|
if (number_of_states == 0)
|
||||||
return;
|
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
|
* 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)].
|
* to the interval [0...(number of states - 1)].
|
||||||
*/
|
*/
|
||||||
|
|
||||||
map<long int, size_type, less<long int>, ALLOC(size_type) >
|
map<long int, size_type> state_number_map;
|
||||||
state_number_map;
|
|
||||||
pair<long int, size_type> state_mapping(0, 0);
|
pair<long int, size_type> state_mapping(0, 0);
|
||||||
|
|
||||||
pair<map<long int, size_type, less<long int>, ALLOC(size_type) >
|
pair<map<long int, size_type>::const_iterator, bool> state_finder;
|
||||||
::const_iterator,
|
|
||||||
bool>
|
|
||||||
state_finder;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Also the acceptance set numbers will be mapped to the interval
|
* Also the acceptance set numbers will be mapped to the interval
|
||||||
* [0...(number of acceptance sets - 1)].
|
* [0...(number of acceptance sets - 1)].
|
||||||
*/
|
*/
|
||||||
|
|
||||||
map<long int, unsigned long int, less<long int>, ALLOC(unsigned long int) >
|
map<long int, unsigned long int> acceptance_set_map;
|
||||||
acceptance_set_map;
|
|
||||||
pair<long int, unsigned long int> acceptance_set_mapping(0, 0);
|
pair<long int, unsigned long int> acceptance_set_mapping(0, 0);
|
||||||
|
|
||||||
pair<map<long int, unsigned long int, less<long int>,
|
pair<map<long int, unsigned long int>::const_iterator, bool>
|
||||||
ALLOC(unsigned long int) >::const_iterator,
|
|
||||||
bool>
|
|
||||||
acceptance_set_finder;
|
acceptance_set_finder;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -450,36 +386,41 @@ void BuchiAutomaton::read(istream& input_stream)
|
||||||
operator[](current_state).acceptanceSets().clear
|
operator[](current_state).acceptanceSets().clear
|
||||||
(number_of_acceptance_sets);
|
(number_of_acceptance_sets);
|
||||||
|
|
||||||
while (1)
|
if (acceptance_sets_on_states)
|
||||||
{
|
{
|
||||||
einput_stream >> acceptance_set_mapping.first;
|
while (1)
|
||||||
|
|
||||||
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)
|
einput_stream >> acceptance_set_mapping.first;
|
||||||
throw AutomatonParseException("number of acceptance sets "
|
|
||||||
"does not match automaton state "
|
|
||||||
"definitions");
|
|
||||||
|
|
||||||
acceptance_set = acceptance_set_mapping.second;
|
if (acceptance_set_mapping.first == -1)
|
||||||
++acceptance_set_mapping.second;
|
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
|
* 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
|
* 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
|
* transition and connect the current state to the target using the
|
||||||
* guard formula.
|
* guard formula.
|
||||||
*/
|
*/
|
||||||
|
|
@ -505,6 +446,42 @@ void BuchiAutomaton::read(istream& input_stream)
|
||||||
state_mapping.second++;
|
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
|
try
|
||||||
{
|
{
|
||||||
guard = ::Ltl::LtlFormula::read(input_stream);
|
guard = ::Ltl::LtlFormula::read(input_stream);
|
||||||
|
|
@ -520,7 +497,7 @@ void BuchiAutomaton::read(istream& input_stream)
|
||||||
throw AutomatonParseException("illegal operators in guard formula");
|
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);
|
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
|
void BuchiAutomaton::print
|
||||||
(ostream& stream, const int indent, const GraphOutputFormat fmt) const
|
(ostream& stream, const int indent, const GraphOutputFormat fmt) const
|
||||||
|
|
@ -880,7 +566,7 @@ void BuchiAutomaton::print
|
||||||
<< " transitions.\n" + string(indent, ' ')
|
<< " transitions.\n" + string(indent, ' ')
|
||||||
+ "The automaton has "
|
+ "The automaton has "
|
||||||
<< number_of_acceptance_sets
|
<< number_of_acceptance_sets
|
||||||
<< " sets of accepting states.\n" + string(indent, ' ')
|
<< " acceptance sets.\n" + string(indent, ' ')
|
||||||
+ "The reachable part of the automaton contains\n"
|
+ "The reachable part of the automaton contains\n"
|
||||||
+ string(indent + 4, ' ')
|
+ string(indent + 4, ' ')
|
||||||
<< reachable_part_statistics.first
|
<< reachable_part_statistics.first
|
||||||
|
|
@ -941,7 +627,8 @@ void BuchiAutomaton::print
|
||||||
++transition)
|
++transition)
|
||||||
{
|
{
|
||||||
estream << string(indent + 2, ' ') + 'n' << state;
|
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";
|
estream << ";\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -964,16 +651,23 @@ void BuchiAutomaton::print
|
||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
void BuchiAutomaton::BuchiTransition::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
|
* Description: Writes information about a transition between two states of
|
||||||
* a Büchi automaton.
|
* a Büchi automaton.
|
||||||
*
|
*
|
||||||
* Arguments: stream -- A reference to an output stream.
|
* Arguments: stream -- A reference to an output
|
||||||
* indent -- Number of spaces to leave to the left of output.
|
* stream.
|
||||||
* fmt -- Determines the format of output.
|
* 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.
|
* Returns: Nothing.
|
||||||
*
|
*
|
||||||
* ------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------- */
|
||||||
|
|
@ -981,11 +675,9 @@ void BuchiAutomaton::BuchiTransition::print
|
||||||
Exceptional_ostream estream(&stream, ios::failbit | ios::badbit);
|
Exceptional_ostream estream(&stream, ios::failbit | ios::badbit);
|
||||||
|
|
||||||
if (fmt == NORMAL)
|
if (fmt == NORMAL)
|
||||||
{
|
|
||||||
estream << string(indent, ' ') + "Transition to state "
|
estream << string(indent, ' ') + "Transition to state "
|
||||||
<< targetNode()
|
<< targetNode()
|
||||||
<< " [ guard: " << *guard_formula << " ]\n";
|
<< " [ acc.: ";
|
||||||
}
|
|
||||||
else if (fmt == DOT)
|
else if (fmt == DOT)
|
||||||
{
|
{
|
||||||
string formula(StringUtil::toString(*guard_formula));
|
string formula(StringUtil::toString(*guard_formula));
|
||||||
|
|
@ -1006,9 +698,33 @@ void BuchiAutomaton::BuchiTransition::print
|
||||||
else
|
else
|
||||||
estream << formula[i];
|
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();
|
estream.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1073,7 +789,8 @@ void BuchiAutomaton::BuchiState::print
|
||||||
GraphEdgeContainer::const_iterator edge;
|
GraphEdgeContainer::const_iterator edge;
|
||||||
|
|
||||||
for (edge = edges().begin(); edge != edges().end(); ++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
|
} else
|
||||||
estream << string(indent, ' ') + "No transitions to other states.\n";
|
estream << string(indent, ' ') + "No transitions to other states.\n";
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
|
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
|
@ -21,6 +21,7 @@
|
||||||
#define BUCHIAUTOMATON_H
|
#define BUCHIAUTOMATON_H
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
#include <cstdlib>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
@ -38,8 +39,7 @@ namespace Graph
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
*
|
*
|
||||||
* A class for representing Büchi automata with a single set of accepting
|
* A class for representing generalized Büchi automata.
|
||||||
* states.
|
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
@ -139,15 +139,19 @@ public:
|
||||||
void connect /* Connects two states */
|
void connect /* Connects two states */
|
||||||
(const size_type father, /* of the automaton with */
|
(const size_type father, /* of the automaton with */
|
||||||
const size_type child); /* an unguarded
|
const size_type child); /* an unguarded
|
||||||
* transition.
|
* transition with no
|
||||||
|
* associated acceptance
|
||||||
|
* sets.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void connect /* Connects two states */
|
void connect /* Connects two states */
|
||||||
(const size_type father, const size_type child, /* of the automaton with */
|
(const size_type father, const size_type child, /* of the automaton with */
|
||||||
::Ltl::LtlFormula& guard); /* a transition guarded */
|
::Ltl::LtlFormula& guard, /* a transition guarded */
|
||||||
void connect /* by a propositional */
|
const BitArray& acc_sets); /* by a propositional */
|
||||||
(const size_type father, const size_type child, /* formula. */
|
void connect /* formula. */
|
||||||
::Ltl::LtlFormula* guard);
|
(const size_type father, const size_type child,
|
||||||
|
::Ltl::LtlFormula* guard,
|
||||||
|
const BitArray& acc_sets);
|
||||||
|
|
||||||
/* `disconnect' inherited from Graph<GraphEdgeContainer> */
|
/* `disconnect' inherited from Graph<GraphEdgeContainer> */
|
||||||
|
|
||||||
|
|
@ -167,12 +171,6 @@ public:
|
||||||
* automaton.
|
* 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
|
void read(istream& input_stream); /* Reads the automaton
|
||||||
* from a stream.
|
* from a stream.
|
||||||
*/
|
*/
|
||||||
|
|
@ -181,17 +179,10 @@ public:
|
||||||
(ostream& stream = cout, /* about the automaton */
|
(ostream& stream = cout, /* about the automaton */
|
||||||
const int indent = 0, /* to a stream in */
|
const int indent = 0, /* to a stream in */
|
||||||
const GraphOutputFormat fmt = NORMAL) const; /* various formats
|
const GraphOutputFormat fmt = NORMAL) const; /* various formats
|
||||||
* (determined by the
|
* (determined by the
|
||||||
* `fmt' argument).
|
* `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
|
class AutomatonParseException; /* Class for reporting
|
||||||
|
|
@ -227,14 +218,12 @@ class BuchiAutomaton::BuchiTransition : public Graph<GraphEdgeContainer>::Edge
|
||||||
public:
|
public:
|
||||||
BuchiTransition /* Constructor. */
|
BuchiTransition /* Constructor. */
|
||||||
(const size_type target,
|
(const size_type target,
|
||||||
::Ltl::LtlFormula* formula);
|
::Ltl::LtlFormula* formula,
|
||||||
|
const BitArray& acc_sets,
|
||||||
|
unsigned long int num_acc_sets);
|
||||||
|
|
||||||
~BuchiTransition(); /* Destructor. */
|
~BuchiTransition(); /* Destructor. */
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
/* `targetNode' inherited from Graph<GraphEdgeContainer>::Edge */
|
/* `targetNode' inherited from Graph<GraphEdgeContainer>::Edge */
|
||||||
|
|
||||||
bool enabled /* These functions test */
|
bool enabled /* These functions test */
|
||||||
|
|
@ -249,14 +238,24 @@ public:
|
||||||
* propositional formula
|
* propositional formula
|
||||||
* guarding the transition.
|
* 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 */
|
void print /* Writes information */
|
||||||
(ostream& stream = cout, /* about the transition */
|
(ostream& stream, /* about the transition */
|
||||||
const int indent = 0, /* to a stream in */
|
const int indent, /* to a stream in */
|
||||||
const GraphOutputFormat fmt = NORMAL) const; /* various formats
|
const GraphOutputFormat fmt, /* various formats */
|
||||||
* (determined by the
|
const unsigned long int /* (determined by the */
|
||||||
* `fmt' argument).
|
number_of_acceptance_sets) const; /* `fmt' argument). */
|
||||||
*/
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BuchiTransition(const BuchiTransition&); /* Prevent copying and */
|
BuchiTransition(const BuchiTransition&); /* Prevent copying and */
|
||||||
|
|
@ -281,6 +280,11 @@ private:
|
||||||
* formula guarding the
|
* formula guarding the
|
||||||
* transition.
|
* 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
|
* Description: Connects two states of a BuchiAutomaton to each other with an
|
||||||
* unguarded transition (actually, a transition with a guard
|
* 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.
|
* Arguments: father -- Source state identifier.
|
||||||
* child -- Target 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
|
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
|
* Description: Connects two states of a BuchiAutomaton to each other, using
|
||||||
* a LtlFormula (which is actually a propositional formula) to
|
* a LtlFormula (which is actually a propositional formula) to
|
||||||
* guard the transition between the states.
|
* guard the transition between the states.
|
||||||
*
|
*
|
||||||
* Arguments: father -- Source state.
|
* Arguments: father -- Source state.
|
||||||
* child -- Target state.
|
* child -- Target state.
|
||||||
* guard -- A reference to an LtlFormula (a propositional
|
* guard -- A reference to an LtlFormula (a propositional
|
||||||
* formula) guarding the transition.
|
* formula) guarding the transition.
|
||||||
|
* acc_sets -- A reference to a BitArray giving the
|
||||||
|
* acceptance sets associated with the transition.
|
||||||
*
|
*
|
||||||
* Returns: Nothing.
|
* Returns: Nothing.
|
||||||
*
|
*
|
||||||
* ------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------- */
|
||||||
{
|
{
|
||||||
connect(father, child, guard.clone());
|
connect(father, child, guard.clone(), acc_sets);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
inline void BuchiAutomaton::connect
|
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
|
* Description: Connects two states of a BuchiAutomaton to each other, using
|
||||||
* a LtlFormula (which is actually a propositional formula) to
|
* a LtlFormula (which is actually a propositional formula) to
|
||||||
* guard the transition between the states.
|
* guard the transition between the states.
|
||||||
*
|
*
|
||||||
* Arguments: father -- Source state.
|
* Arguments: father -- Source state.
|
||||||
* child -- Target state.
|
* child -- Target state.
|
||||||
* guard -- A pointer to an LtlFormula (a propositional
|
* guard -- A pointer to an LtlFormula (a propositional
|
||||||
* formula) guarding the transition. The transition
|
* formula) guarding the transition. The
|
||||||
* will "own" the guard formula.
|
* transition will "own" the guard formula.
|
||||||
|
* acc_sets -- A reference to a BitArray giving the acceptance
|
||||||
|
* sets associated with the transition.
|
||||||
*
|
*
|
||||||
* Returns: Nothing.
|
* 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
|
try
|
||||||
{
|
{
|
||||||
|
|
@ -512,39 +526,28 @@ inline istream& operator>>(istream& stream, BuchiAutomaton& automaton)
|
||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
inline BuchiAutomaton::BuchiTransition::BuchiTransition
|
inline BuchiAutomaton::BuchiTransition::BuchiTransition
|
||||||
(const size_type target, ::Ltl::LtlFormula* formula) :
|
(const size_type target, ::Ltl::LtlFormula* formula,
|
||||||
Edge(target), guard_formula(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.
|
* Description: Constructor for class BuchiAutomaton::BuchiTransition.
|
||||||
* Initializes a new transition to a BuchiState, guarded by an
|
* Initializes a new transition to a BuchiState, guarded by an
|
||||||
* LtlFormula (which is actually a propositional formula).
|
* LtlFormula (which is actually a propositional formula).
|
||||||
*
|
*
|
||||||
* Arguments: target -- Identifier of the target state of the automaton.
|
* Arguments: target -- Identifier of the target state of the
|
||||||
* formula -- A pointer to a propositional formula guarding
|
* automaton.
|
||||||
* the transition.
|
* formula -- A pointer to a propositional formula guarding
|
||||||
*
|
* the transition.
|
||||||
* Returns: Nothing.
|
* acc_sets -- A reference to a constant BitArray containing
|
||||||
*
|
* the acceptance sets associated with the
|
||||||
* ------------------------------------------------------------------------- */
|
* transition.
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ========================================================================= */
|
|
||||||
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.
|
|
||||||
*
|
*
|
||||||
* Returns: Nothing.
|
* Returns: Nothing.
|
||||||
*
|
*
|
||||||
* ------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------- */
|
||||||
{
|
{
|
||||||
|
acceptance_sets.copy(acc_sets, num_acc_sets);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
|
|
@ -688,6 +691,59 @@ inline ::Ltl::LtlFormula& BuchiAutomaton::BuchiTransition::guard() const
|
||||||
return *guard_formula;
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
|
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
|
@ -28,8 +28,7 @@ namespace Graph
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
map< ::Ltl::LtlFormula*, BuchiProduct::SatisfiabilityMapping,
|
map< ::Ltl::LtlFormula*, BuchiProduct::SatisfiabilityMapping>
|
||||||
less< ::Ltl::LtlFormula*>, ALLOC(BuchiProduct::SatisfiabilityMapping) >
|
|
||||||
BuchiProduct::sat_cache;
|
BuchiProduct::sat_cache;
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -73,8 +72,7 @@ bool BuchiProduct::synchronizable
|
||||||
guard_1 = swap_guard;
|
guard_1 = swap_guard;
|
||||||
}
|
}
|
||||||
|
|
||||||
map<LtlFormula*, SatisfiabilityMapping, less<LtlFormula*>,
|
map<LtlFormula*, SatisfiabilityMapping>::iterator
|
||||||
ALLOC(SatisfiabilityMapping) >::iterator
|
|
||||||
sat_cache_element = sat_cache.find(guard_1);
|
sat_cache_element = sat_cache.find(guard_1);
|
||||||
|
|
||||||
if (sat_cache_element == sat_cache.end())
|
if (sat_cache_element == sat_cache.end())
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
|
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
|
@ -142,18 +142,16 @@ private:
|
||||||
* automata.
|
* automata.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef map< ::Ltl::LtlFormula*, bool, /* Type definition for */
|
typedef map< ::Ltl::LtlFormula*, bool> /* Type definition for */
|
||||||
less< ::Ltl::LtlFormula*>, /* storing information */
|
SatisfiabilityMapping; /* storing information
|
||||||
ALLOC(bool) > /* about the */
|
* about the
|
||||||
SatisfiabilityMapping; /* satisfiability of the
|
* satisfiability of the
|
||||||
* guards of product
|
* guards of product
|
||||||
* transitions.
|
* transitions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static map< ::Ltl::LtlFormula*, /* Result cache for */
|
static map< ::Ltl::LtlFormula*, /* Result cache for */
|
||||||
SatisfiabilityMapping, /* satisfiability tests. */
|
SatisfiabilityMapping> /* satisfiability tests. */
|
||||||
less< ::Ltl::LtlFormula*>,
|
|
||||||
ALLOC(SatisfiabilityMapping) >
|
|
||||||
sat_cache;
|
sat_cache;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 1999, 2000, 2001, 2002
|
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
|
@ -19,11 +19,6 @@
|
||||||
|
|
||||||
%{
|
%{
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include <cmath>
|
|
||||||
#include <climits>
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <cstring>
|
|
||||||
#include <string>
|
|
||||||
#include "Configuration.h"
|
#include "Configuration.h"
|
||||||
#include "Config-parse.h"
|
#include "Config-parse.h"
|
||||||
|
|
||||||
|
|
@ -34,225 +29,102 @@ extern int config_file_line_number;
|
||||||
%option case-insensitive
|
%option case-insensitive
|
||||||
%option never-interactive
|
%option never-interactive
|
||||||
%option noyywrap
|
%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. */ }
|
<*>[ \t]* { /* Skip whitespace everywhere. */ }
|
||||||
"#"[^\n]* { /* Skip comments. */ }
|
<*>"#".*$ { /* 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++;
|
config_file_line_number++;
|
||||||
}
|
}
|
||||||
|
|
||||||
"{" { return CFG_LBRACE; }
|
"{" { BEGIN(ATTR); 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; }
|
|
||||||
|
|
||||||
|
algorithm|implementation|translator { return CFG_ALGORITHM; }
|
||||||
globaloptions { return CFG_GLOBALOPTIONS; }
|
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; }
|
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; }
|
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 {
|
[^ \t\n]+ { return CFG_UNKNOWN; }
|
||||||
yylval.truth_value = true;
|
|
||||||
return CFG_TRUTH_VALUE;
|
<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 {
|
<VAL>{OKVAL}*(\'{SQSTR}|\"{DQSTR})(\\)? {
|
||||||
yylval.truth_value = false;
|
throw Configuration::ConfigurationException
|
||||||
return CFG_TRUTH_VALUE;
|
(config_file_line_number,
|
||||||
}
|
"unmatched quotes");
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<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
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
|
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
|
@ -21,6 +21,7 @@
|
||||||
#define CONFIGURATION_H
|
#define CONFIGURATION_H
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
#include <cstdio>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
@ -35,8 +36,6 @@
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
*
|
*
|
||||||
* A class for storing program configuration information.
|
* A class for storing program configuration information.
|
||||||
|
|
@ -63,21 +62,29 @@ public:
|
||||||
struct AlgorithmInformation; /* See below. */
|
struct AlgorithmInformation; /* See below. */
|
||||||
|
|
||||||
string algorithmString /* Formats the the id */
|
string algorithmString /* Formats the the id */
|
||||||
(vector<AlgorithmInformation, /* of an algorithm and */
|
(vector<AlgorithmInformation>::size_type /* of an algorithm and */
|
||||||
ALLOC(AlgorithmInformation) >::size_type/* the name of the */
|
algorithm_id) const; /* the name of the
|
||||||
algorithm_id) const; /* algorithm into a
|
* algorithm into a
|
||||||
* string.
|
* 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 */
|
static void showCommandLineHelp /* Prints the list of */
|
||||||
(const char* program_name); /* command line options. */
|
(const char* program_name); /* command line options. */
|
||||||
|
|
||||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||||
|
|
||||||
enum InteractionMode {NEVER, ALWAYS, ONERROR}; /* Enumeration constants
|
enum InteractionMode {NEVER, ALWAYS, ONERROR, /* Enumeration constants */
|
||||||
* affecting the behaviour
|
ONBREAK}; /* affecting the
|
||||||
* of the program as
|
* behavior of the
|
||||||
* regards user control.
|
* program as regards
|
||||||
|
* user control.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
enum FormulaMode {NORMAL, NNF}; /* Enumeration constants
|
enum FormulaMode {NORMAL, NNF}; /* Enumeration constants
|
||||||
|
|
@ -109,19 +116,23 @@ public:
|
||||||
* parameters).
|
* 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
|
* required for running
|
||||||
* the algorithm.
|
* the executable. See
|
||||||
*/
|
* the documentation for
|
||||||
|
* the registerAlgorithm
|
||||||
string* extra_parameters; /* Additional command-line
|
* function (in
|
||||||
* parameters required for
|
* Configuration.cc) for
|
||||||
* running the executable.
|
* more information.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
vector<string>::size_type num_parameters; /* Number of command-line
|
||||||
|
* parameters.
|
||||||
|
*/
|
||||||
|
|
||||||
bool enabled; /* Determines whether the
|
bool enabled; /* Determines whether the
|
||||||
* algorithm is enabled
|
* algorithm is enabled
|
||||||
* (whether it will be used
|
* (whether it will be used
|
||||||
|
|
@ -169,6 +180,12 @@ public:
|
||||||
* commands.
|
* 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.
|
unsigned long int number_of_rounds; /* Number of test rounds.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -278,6 +295,10 @@ public:
|
||||||
* formula generation
|
* formula generation
|
||||||
* algorithms.
|
* algorithms.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
unsigned int translator_timeout; /* Timeout (in seconds) for
|
||||||
|
* translators.
|
||||||
|
*/
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FormulaConfiguration /* A structure for storing
|
struct FormulaConfiguration /* A structure for storing
|
||||||
|
|
@ -290,11 +311,12 @@ public:
|
||||||
* LTL formula symbols.
|
* LTL formula symbols.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
map<int, int, less<int>, ALLOC(int) > /* Priorities for LTL */
|
map<int, int> symbol_priority; /* Priorities for LTL
|
||||||
symbol_priority; /* formula symbols. */
|
* formula symbols.
|
||||||
|
*/
|
||||||
|
|
||||||
map<int, double, less<int>, ALLOC(double) > /* Expected numbers of */
|
map<int, double> symbol_distribution; /* Expected numbers of
|
||||||
symbol_distribution; /* occurrence for the
|
* occurrence for the
|
||||||
* different formula
|
* different formula
|
||||||
* operators.
|
* operators.
|
||||||
*/
|
*/
|
||||||
|
|
@ -354,12 +376,18 @@ public:
|
||||||
|
|
||||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||||
|
|
||||||
vector<AlgorithmInformation, /* A vector containing */
|
vector<AlgorithmInformation> algorithms; /* A vector containing
|
||||||
ALLOC(AlgorithmInformation) > algorithms; /* information about the
|
* information about the
|
||||||
* algorithms used in
|
* algorithms used in
|
||||||
* the tests.
|
* the tests.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
map<string, unsigned long int> algorithm_names; /* Mapping between
|
||||||
|
* algorithm names and
|
||||||
|
* their numeric
|
||||||
|
* identifiers.
|
||||||
|
*/
|
||||||
|
|
||||||
GlobalConfiguration global_options; /* General configuration
|
GlobalConfiguration global_options; /* General configuration
|
||||||
* information.
|
* information.
|
||||||
*/
|
*/
|
||||||
|
|
@ -376,15 +404,6 @@ public:
|
||||||
* algorithms.
|
* 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
|
class ConfigurationException : public Exception /* A class for reporting
|
||||||
|
|
@ -419,6 +438,9 @@ public:
|
||||||
|
|
||||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||||
|
|
||||||
|
private:
|
||||||
|
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||||
|
|
||||||
struct IntegerRange /* Data structure for
|
struct IntegerRange /* Data structure for
|
||||||
* representing integer-
|
* representing integer-
|
||||||
* valued ranges of certain
|
* valued ranges of certain
|
||||||
|
|
@ -426,11 +448,11 @@ public:
|
||||||
* options.
|
* 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
|
* displayed if the value
|
||||||
* is not within the
|
* is not within the
|
||||||
* specified range.
|
* 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
|
static const struct IntegerRange
|
||||||
VERBOSITY_RANGE, ROUND_COUNT_RANGE, GENERATION_RANGE, PRIORITY_RANGE,
|
DEFAULT_RANGE, VERBOSITY_RANGE,
|
||||||
PROPOSITION_COUNT_RANGE, FORMULA_SIZE_RANGE, FORMULA_MAX_SIZE_RANGE,
|
ROUND_COUNT_RANGE, RANDOM_SEED_RANGE,
|
||||||
STATESPACE_SIZE_RANGE, STATESPACE_MAX_SIZE_RANGE;
|
ATOMIC_PRIORITY_RANGE, OPERATOR_PRIORITY_RANGE;
|
||||||
|
|
||||||
private:
|
/* Command line options. */
|
||||||
enum CommandLineOptionType /* Command line options. */
|
|
||||||
{OPT_COMPARISONTEST = 10000, OPT_CONFIGFILE,
|
enum CommandLineOptionType
|
||||||
|
{OPT_HELP = 'h', OPT_VERSION = 'V',
|
||||||
|
|
||||||
|
OPT_COMPARISONTEST = 10000, OPT_CONFIGFILE,
|
||||||
OPT_CONSISTENCYTEST, OPT_DISABLE, OPT_ENABLE,
|
OPT_CONSISTENCYTEST, OPT_DISABLE, OPT_ENABLE,
|
||||||
OPT_FORMULACHANGEINTERVAL, OPT_FORMULAFILE,
|
OPT_FORMULACHANGEINTERVAL,
|
||||||
OPT_FORMULARANDOMSEED, OPT_HELP = 'h',
|
OPT_FORMULAFILE, OPT_FORMULARANDOMSEED,
|
||||||
OPT_GLOBALPRODUCT = 20000, OPT_INTERACTIVE,
|
OPT_GLOBALPRODUCT, OPT_INTERACTIVE,
|
||||||
OPT_INTERSECTIONTEST, OPT_LOGFILE,
|
OPT_INTERSECTIONTEST, OPT_LOGFILE,
|
||||||
OPT_MODELCHECK, OPT_NOCOMPARISONTEST,
|
OPT_MODELCHECK, OPT_PROFILE, OPT_QUIET,
|
||||||
OPT_NOCONSISTENCYTEST, OPT_NOINTERSECTIONTEST,
|
OPT_ROUNDS, OPT_SHOWCONFIG,
|
||||||
OPT_NOPAUSE, OPT_PAUSE, OPT_PAUSEONERROR,
|
OPT_SHOWOPERATORDISTRIBUTION, OPT_SKIP,
|
||||||
OPT_PROFILE, OPT_QUIET, OPT_ROUNDS,
|
OPT_STATESPACECHANGEINTERVAL,
|
||||||
OPT_SHOWCONFIG, OPT_SHOWOPERATORDISTRIBUTION,
|
OPT_STATESPACERANDOMSEED,
|
||||||
OPT_SKIP, OPT_STATESPACECHANGEINTERVAL,
|
OPT_TRANSLATORTIMEOUT, OPT_VERBOSITY,
|
||||||
OPT_STATESPACERANDOMSEED, OPT_VERBOSITY,
|
|
||||||
OPT_VERSION,
|
|
||||||
|
|
||||||
OPT_LOCALPRODUCT,
|
OPT_LOCALPRODUCT,
|
||||||
|
|
||||||
|
|
@ -476,7 +497,6 @@ private:
|
||||||
OPT_FORMULAPROPOSITIONS, OPT_FORMULASIZE,
|
OPT_FORMULAPROPOSITIONS, OPT_FORMULASIZE,
|
||||||
OPT_GENERATENNF, OPT_GLOBALLYPRIORITY,
|
OPT_GENERATENNF, OPT_GLOBALLYPRIORITY,
|
||||||
OPT_IMPLICATIONPRIORITY, OPT_NEXTPRIORITY,
|
OPT_IMPLICATIONPRIORITY, OPT_NEXTPRIORITY,
|
||||||
OPT_NOABBREVIATEDOPERATORS,
|
|
||||||
OPT_NOGENERATENNF, OPT_NOOUTPUTNNF,
|
OPT_NOGENERATENNF, OPT_NOOUTPUTNNF,
|
||||||
OPT_NOTPRIORITY, OPT_ORPRIORITY,
|
OPT_NOTPRIORITY, OPT_ORPRIORITY,
|
||||||
OPT_OUTPUTNNF, OPT_PROPOSITIONPRIORITY,
|
OPT_OUTPUTNNF, OPT_PROPOSITIONPRIORITY,
|
||||||
|
|
@ -492,17 +512,18 @@ private:
|
||||||
OPT_STATESPACEPROPOSITIONS,
|
OPT_STATESPACEPROPOSITIONS,
|
||||||
OPT_STATESPACESIZE, OPT_TRUTHPROBABILITY};
|
OPT_STATESPACESIZE, OPT_TRUTHPROBABILITY};
|
||||||
|
|
||||||
typedef map<pair<int, int>, double, /* Type definitions for */
|
typedef map<pair<int, int>, double> /* Type definitions for */
|
||||||
less<pair<int, int> >, /* the result cache used */
|
ProbabilityMapElement; /* the result cache used */
|
||||||
ALLOC(double) > /* for computing the */
|
/* for computing the */
|
||||||
ProbabilityMapElement; /* probability */
|
typedef map<int, ProbabilityMapElement> /* probability */
|
||||||
typedef map<int, ProbabilityMapElement, /* distribution of LTL */
|
ProbabilityMap; /* distribution of LTL
|
||||||
less<int>, /* formula operators. */
|
* formula operators.
|
||||||
ALLOC(ProbabilityMapElement) >
|
*/
|
||||||
ProbabilityMap;
|
|
||||||
|
|
||||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||||
|
|
||||||
|
friend int yyparse();
|
||||||
|
|
||||||
Configuration(const Configuration& cfg); /* Prevent copying and */
|
Configuration(const Configuration& cfg); /* Prevent copying and */
|
||||||
Configuration& operator= /* assignment of */
|
Configuration& operator= /* assignment of */
|
||||||
(const Configuration& cfg); /* Configuration
|
(const Configuration& cfg); /* Configuration
|
||||||
|
|
@ -514,10 +535,59 @@ private:
|
||||||
* to default values.
|
* to default values.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
long int parseCommandLineInteger /* Converts an integer */
|
void registerAlgorithm /* Adds a new algorithm */
|
||||||
(const string& option, const string& value) /* to a string with */
|
(const string& name, const string& path, /* to the configuration. */
|
||||||
const; /* some additional
|
const string& parameters, bool enabled,
|
||||||
* validity checks.
|
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 */
|
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.
|
* Inline function definitions for class Configuration::ConfigurationException.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
|
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
|
@ -32,10 +32,10 @@
|
||||||
namespace DispUtil
|
namespace DispUtil
|
||||||
{
|
{
|
||||||
|
|
||||||
stack<StreamFormatting, /* Stack for storing the */
|
stack<StreamFormatting, deque<StreamFormatting> > /* Stack for storing the */
|
||||||
deque<StreamFormatting, /* previous states of an */
|
stream_formatting_stack; /* previous states of an
|
||||||
ALLOC(StreamFormatting) > > /* output stream. */
|
* output stream.
|
||||||
stream_formatting_stack;
|
*/
|
||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
void changeStreamFormatting
|
void changeStreamFormatting
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 1999, 2000, 2001, 2002
|
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
|
@ -20,10 +20,6 @@
|
||||||
#ifndef DISPUTIL_H
|
#ifndef DISPUTIL_H
|
||||||
#define DISPUTIL_H
|
#define DISPUTIL_H
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
#pragma interface
|
|
||||||
#endif /* __GNUC__ */
|
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
@ -62,6 +58,16 @@ void printTextBlock /* Writes an indented */
|
||||||
* a stream.
|
* 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
|
* e.g. the justification
|
||||||
* of output.
|
* 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);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 1999, 2000, 2001, 2002
|
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
|
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
|
@ -23,6 +23,7 @@
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <exception>
|
#include <exception>
|
||||||
|
#include <istream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
@ -299,6 +300,16 @@ public:
|
||||||
template<class T> /* Operator for reading */
|
template<class T> /* Operator for reading */
|
||||||
Exceptional_istream &operator>>(T &t); /* from the stream. */
|
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-
|
operator istream&(); /* Casts the exception-
|
||||||
* aware input stream into
|
* aware input stream into
|
||||||
* a regular input stream.
|
* 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&()
|
inline Exceptional_istream::operator istream&()
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
|
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
|
@ -18,12 +18,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include <csignal>
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
#include <cstring>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/wait.h>
|
|
||||||
#ifdef HAVE_FCNTL_H
|
#ifdef HAVE_FCNTL_H
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#endif /* HAVE_FCNTL_H */
|
#endif /* HAVE_FCNTL_H */
|
||||||
|
|
@ -64,25 +63,30 @@ ExternalTranslator::~ExternalTranslator()
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
ExternalTranslator::TempFileObject&
|
const char* ExternalTranslator::registerTempFileObject
|
||||||
ExternalTranslator::registerTempFileObject
|
(const string& filename, const TempFsysName::NameType type,
|
||||||
(const string& filename, TempFileObject::Type type)
|
const bool literal)
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* Description: Registers a temporary file or directory such that it will be
|
* Description: Registers a temporary file or directory such that it will be
|
||||||
* automatically deleted when the ExternalTranslator object is
|
* automatically deleted when the ExternalTranslator object is
|
||||||
* destroyed.
|
* 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
|
* type -- Type of the object (TempFileObject::FILE or
|
||||||
* TempFileObject::DIRECTORY).
|
* 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));
|
TempFsysName* name = new TempFsysName;
|
||||||
return *temporary_file_objects.top();
|
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;
|
string translated_formula;
|
||||||
translateFormula(formula, translated_formula);
|
translateFormula(formula, translated_formula);
|
||||||
|
|
||||||
std::cout << translated_formula << std::endl;
|
|
||||||
|
|
||||||
ofstream input_file;
|
ofstream input_file;
|
||||||
input_file.open(external_program_input_file.getName().c_str(),
|
input_file.open(external_program_input_file, ios::out | ios::trunc);
|
||||||
ios::out | ios::trunc);
|
|
||||||
if (!input_file.good())
|
if (!input_file.good())
|
||||||
throw FileCreationException(string("`")
|
throw FileCreationException(string("`") + external_program_input_file
|
||||||
+ external_program_input_file.getName()
|
|
||||||
+ "'");
|
+ "'");
|
||||||
|
|
||||||
Exceptional_ostream einput_file(&input_file, ios::failbit | ios::badbit);
|
Exceptional_ostream einput_file(&input_file, ios::failbit | ios::badbit);
|
||||||
|
|
@ -125,106 +127,11 @@ void ExternalTranslator::translate
|
||||||
input_file.close();
|
input_file.close();
|
||||||
|
|
||||||
string command_line = string(command_line_arguments[2])
|
string command_line = string(command_line_arguments[2])
|
||||||
+ commandLine(external_program_input_file.getName(),
|
+ commandLine(external_program_input_file,
|
||||||
external_program_output_file.getName());
|
external_program_output_file);
|
||||||
|
|
||||||
int exitcode = system(command_line.c_str());
|
if (!execSuccess(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))
|
|
||||||
throw ExecFailedException(command_line_arguments[2]);
|
throw ExecFailedException(command_line_arguments[2]);
|
||||||
|
|
||||||
parseAutomaton(external_program_output_file.getName(), filename);
|
parseAutomaton(external_program_output_file, 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 1999, 2000, 2001, 2002
|
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* 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.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
#pragma implementation
|
|
||||||
#endif /* __GNUC__ */
|
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include "FormulaRandomizer.h"
|
#include "FormulaRandomizer.h"
|
||||||
#include "Random.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;
|
LtlFormula* formula;
|
||||||
long int x;
|
long int x;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
|
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
|
@ -21,6 +21,7 @@
|
||||||
#define FORMULARANDOMIZER_H
|
#define FORMULARANDOMIZER_H
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
#include <map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include "LbttAlloc.h"
|
#include "LbttAlloc.h"
|
||||||
|
|
@ -86,16 +87,16 @@ public:
|
||||||
* `reset'.
|
* `reset'.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const map<unsigned long int, unsigned long int, /* Get the numbers of */
|
const map<unsigned long int, unsigned long int>& /* Get the numbers of */
|
||||||
less<unsigned long int>, /* different atomic */
|
propositionStatistics() const; /* different atomic
|
||||||
ALLOC(unsigned long int) >& /* propositions */
|
* propositions
|
||||||
propositionStatistics() const; /* generated since the
|
* generated since the
|
||||||
* last call to `reset'.
|
* last call to `reset'.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const map<int, unsigned long int, less<int>, /* Get the numbers of */
|
const map<int, unsigned long int>& /* Get the numbers of */
|
||||||
ALLOC(unsigned long int) >& /* different symbols */
|
symbolStatistics() const; /* different symbols
|
||||||
symbolStatistics() const; /* generated since the
|
* generated since the
|
||||||
* last call to `reset'.
|
* last call to `reset'.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -123,21 +124,20 @@ private:
|
||||||
|
|
||||||
typedef pair<int, int> IntegerPair;
|
typedef pair<int, int> IntegerPair;
|
||||||
|
|
||||||
vector<IntegerPair, ALLOC(IntegerPair) > /* Operand symbols and */
|
vector<IntegerPair> /* Operand symbols and */
|
||||||
propositional_symbol_priorities; /* their priorities in
|
propositional_symbol_priorities; /* their priorities in
|
||||||
* random formulae.
|
* random formulae.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
vector<IntegerPair, ALLOC(IntegerPair) > /* Operators and their */
|
vector<IntegerPair> short_formula_operators; /* Operators and their
|
||||||
short_formula_operators; /* priorities in random
|
* priorities in random
|
||||||
* formulae of size
|
* formulae of size two.
|
||||||
* two.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
vector<IntegerPair, ALLOC(IntegerPair) > /* Operators and their */
|
vector<IntegerPair> long_formula_operators; /* Operators and their
|
||||||
long_formula_operators; /* priorities in random
|
* priorities in random
|
||||||
* formulae of size
|
* formulae of size greater
|
||||||
* greater than two.
|
* than two.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
unsigned long int number_of_generated_formulas; /* Number of generated
|
unsigned long int number_of_generated_formulas; /* Number of generated
|
||||||
|
|
@ -145,14 +145,15 @@ private:
|
||||||
* last call to `reset'.
|
* last call to `reset'.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
map<unsigned long int, unsigned long int, /* Number of different */
|
map<unsigned long int, unsigned long int> /* Number of different */
|
||||||
less<unsigned long int>, /* atomic propositions */
|
proposition_statistics; /* atomic propositions
|
||||||
ALLOC(unsigned long int) > /* generated since the */
|
* generated since the
|
||||||
proposition_statistics; /* last call to `reset' */
|
* last call to `reset'
|
||||||
|
*/
|
||||||
|
|
||||||
map<int, unsigned long int, less<int>, /* Number of different */
|
map<int, unsigned long int> symbol_statistics; /* Number of different
|
||||||
ALLOC(unsigned long int) > /* formula symbols */
|
* formula symbols
|
||||||
symbol_statistics; /* generated since the
|
* generated since the
|
||||||
* last call to `reset'.
|
* 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>,
|
inline const map<unsigned long int, unsigned long int>&
|
||||||
ALLOC(unsigned long int) >&
|
|
||||||
FormulaRandomizer::propositionStatistics() const
|
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
|
FormulaRandomizer::symbolStatistics() const
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 1999, 2000, 2001, 2002
|
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
|
@ -21,13 +21,11 @@
|
||||||
#define FORMULAWRITER_H
|
#define FORMULAWRITER_H
|
||||||
|
|
||||||
#include "Exception.h"
|
#include "Exception.h"
|
||||||
|
#include "LtlFormula.h"
|
||||||
|
|
||||||
namespace Ltl
|
namespace Ltl
|
||||||
{
|
{
|
||||||
|
|
||||||
class LtlFormula;
|
|
||||||
class Atom;
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
*
|
*
|
||||||
* A function template class for writing the formula to a stream.
|
* A function template class for writing the formula to a stream.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
|
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
|
@ -186,25 +186,38 @@ public:
|
||||||
* graph nodes.
|
* graph nodes.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
class PathElement; /* A class for representing
|
||||||
|
* (node, edge) pairs
|
||||||
|
*/
|
||||||
|
|
||||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
vector<Node*, ALLOC(Node*) > nodes; /* Nodes of the graph.
|
vector<Node*> nodes; /* Nodes of the graph.
|
||||||
* Derived classes can
|
* Derived classes can
|
||||||
* access this vector
|
* access this vector
|
||||||
* directly.
|
* directly.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef typename /* Type definition for */
|
typedef typename vector<Node*>::size_type /* Type definition for */
|
||||||
vector<Node*, ALLOC(Node*) >::size_type /* the size of the */
|
size_type; /* the size of the
|
||||||
size_type; /* graph. The size can
|
* graph. The size can
|
||||||
* be no greater than
|
* be no greater than
|
||||||
* the maximum size of
|
* the maximum size of
|
||||||
* the vector containing
|
* the vector containing
|
||||||
* the graph nodes.
|
* 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
|
typedef pair<size_type, size_type> StateIdPair; /* Type definition for a
|
||||||
* pair of state
|
* pair of state
|
||||||
* identifiers in a graph.
|
* identifiers in a graph.
|
||||||
|
|
@ -323,8 +336,8 @@ public:
|
||||||
|
|
||||||
/* default assignment operator */
|
/* default assignment operator */
|
||||||
|
|
||||||
Graph<EdgeContainer>::size_type targetNode() /* Returns the index of */
|
size_type targetNode() const; /* Returns the index of */
|
||||||
const; /* the target node of
|
/* the target node of
|
||||||
* the directed edge.
|
* the directed edge.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -353,7 +366,7 @@ protected:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Graph<EdgeContainer>::size_type target_node; /* Identifier of the edge's
|
size_type target_node; /* Identifier of the edge's
|
||||||
* target node.
|
* 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.
|
* An exception class for reporting errors when indexing graph nodes.
|
||||||
|
|
@ -434,8 +503,7 @@ public:
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
class EdgeList : public list<Graph<EdgeList>::Edge*,
|
class EdgeList : public list<Graph<EdgeList>::Edge*>
|
||||||
ALLOC(Graph<EdgeList>::Edge*) >
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
EdgeList(); /* Constructor. */
|
EdgeList(); /* Constructor. */
|
||||||
|
|
@ -450,14 +518,12 @@ public:
|
||||||
* the end of the list.
|
* the end of the list.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
list<Graph<EdgeList>::Edge*, /* Functions for finding */
|
list<Graph<EdgeList>::Edge*>::const_iterator /* Functions for finding */
|
||||||
ALLOC(Graph<EdgeList>::Edge*) > /* an element in the */
|
find(const Graph<EdgeList>::Edge* edge) const; /* an element in the
|
||||||
::const_iterator /* list. */
|
* list.
|
||||||
find(const Graph<EdgeList>::Edge* edge) const;
|
*/
|
||||||
|
|
||||||
list<Graph<EdgeList>::Edge*,
|
list<Graph<EdgeList>::Edge*>::iterator
|
||||||
ALLOC(Graph<EdgeList>::Edge*) >
|
|
||||||
::iterator
|
|
||||||
find(const Graph<EdgeList>::Edge* edge);
|
find(const Graph<EdgeList>::Edge* edge);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -472,8 +538,7 @@ public:
|
||||||
|
|
||||||
#ifdef HAVE_SLIST
|
#ifdef HAVE_SLIST
|
||||||
|
|
||||||
class EdgeSlist : public slist<Graph<EdgeSlist>::Edge*,
|
class EdgeSlist : public slist<Graph<EdgeSlist>::Edge*>
|
||||||
ALLOC(Graph<EdgeSlist>::Edge*) >
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
EdgeSlist(); /* Constructor. */
|
EdgeSlist(); /* Constructor. */
|
||||||
|
|
@ -489,14 +554,12 @@ public:
|
||||||
* list.
|
* list.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
slist<Graph<EdgeSlist>::Edge*, /* Functions for finding */
|
slist<Graph<EdgeSlist>::Edge*>::const_iterator /* Functions for finding */
|
||||||
ALLOC(Graph<EdgeSlist>::Edge*) > /* an element in the */
|
find(const Graph<EdgeSlist>::Edge* edge) const; /* an element in the
|
||||||
::const_iterator /* list. */
|
* list.
|
||||||
find(const Graph<EdgeSlist>::Edge* edge) const;
|
*/
|
||||||
|
|
||||||
slist<Graph<EdgeSlist>::Edge*,
|
slist<Graph<EdgeSlist>::Edge*>::iterator
|
||||||
ALLOC(Graph<EdgeSlist>::Edge*) >
|
|
||||||
::iterator
|
|
||||||
find(const Graph<EdgeSlist>::Edge* edge);
|
find(const Graph<EdgeSlist>::Edge* edge);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -510,8 +573,7 @@ public:
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
class EdgeVector : public vector<Graph<EdgeVector>::Edge*,
|
class EdgeVector : public vector<Graph<EdgeVector>::Edge*>
|
||||||
ALLOC(Graph<EdgeVector>::Edge*) >
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
EdgeVector(); /* Constructor. */
|
EdgeVector(); /* Constructor. */
|
||||||
|
|
@ -527,15 +589,11 @@ public:
|
||||||
* to edges.
|
* to edges.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
vector<Graph<EdgeVector>::Edge*, /* Functions for finding */
|
vector<Graph<EdgeVector>::Edge*>::const_iterator /* Functions for finding */
|
||||||
ALLOC(Graph<EdgeVector>::Edge*) > /* an element in the */
|
find(const Graph<EdgeVector>::Edge* edge) /* an element in the */
|
||||||
::const_iterator /* container. */
|
const; /* container. */
|
||||||
find(const Graph<EdgeVector>::Edge* edge)
|
|
||||||
const;
|
|
||||||
|
|
||||||
vector<Graph<EdgeVector>::Edge*,
|
vector<Graph<EdgeVector>::Edge*>::iterator
|
||||||
ALLOC(Graph<EdgeVector>::Edge*) >
|
|
||||||
::iterator
|
|
||||||
find(const Graph<EdgeVector>::Edge* edge);
|
find(const Graph<EdgeVector>::Edge* edge);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -548,8 +606,7 @@ public:
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
class EdgeSet : public set<Graph<EdgeSet>::Edge*,
|
class EdgeSet : public set<Graph<EdgeSet>::Edge*,
|
||||||
Graph<EdgeSet>::Edge::ptr_less,
|
Graph<EdgeSet>::Edge::ptr_less>
|
||||||
ALLOC(Graph<EdgeSet>::Edge*) >
|
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -562,8 +619,7 @@ class EdgeSet : public set<Graph<EdgeSet>::Edge*,
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
class EdgeMultiSet : public multiset<Graph<EdgeMultiSet>::Edge*,
|
class EdgeMultiSet : public multiset<Graph<EdgeMultiSet>::Edge*,
|
||||||
Graph<EdgeMultiSet>::Edge::ptr_less,
|
Graph<EdgeMultiSet>::Edge::ptr_less>
|
||||||
ALLOC(Graph<EdgeMultiSet>::Edge*) >
|
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -689,7 +745,7 @@ Graph<EdgeContainer>::Graph(const size_type initial_number_of_nodes) :
|
||||||
{
|
{
|
||||||
nodes.reserve(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 != nodes.end();
|
||||||
++node)
|
++node)
|
||||||
*node = new Node();
|
*node = new Node();
|
||||||
|
|
@ -711,8 +767,7 @@ Graph<EdgeContainer>::Graph(const Graph<EdgeContainer>& graph)
|
||||||
* ------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------- */
|
||||||
{
|
{
|
||||||
nodes.reserve(graph.nodes.size());
|
nodes.reserve(graph.nodes.size());
|
||||||
for (typename vector<Node*, ALLOC(Node*) >::const_iterator
|
for (typename vector<Node*>::const_iterator node = graph.nodes.begin();
|
||||||
node = graph.nodes.begin();
|
|
||||||
node != graph.nodes.end(); ++node)
|
node != graph.nodes.end(); ++node)
|
||||||
nodes.push_back(new Node(**node));
|
nodes.push_back(new Node(**node));
|
||||||
}
|
}
|
||||||
|
|
@ -738,8 +793,7 @@ Graph<EdgeContainer>& Graph<EdgeContainer>::operator=
|
||||||
clear();
|
clear();
|
||||||
|
|
||||||
nodes.reserve(graph.nodes.size());
|
nodes.reserve(graph.nodes.size());
|
||||||
for (typename vector<Node*, ALLOC(Node*) >::const_iterator
|
for (typename vector<Node*>::const_iterator node = graph.nodes.begin();
|
||||||
node = graph.nodes.begin();
|
|
||||||
node != graph.nodes.end();
|
node != graph.nodes.end();
|
||||||
++node)
|
++node)
|
||||||
nodes.push_back(new Node(**node));
|
nodes.push_back(new Node(**node));
|
||||||
|
|
@ -782,8 +836,7 @@ void Graph<EdgeContainer>::clear()
|
||||||
*
|
*
|
||||||
* ------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------- */
|
||||||
{
|
{
|
||||||
for (typename vector<Node*, ALLOC(Node*) >::reverse_iterator
|
for (typename vector<Node*>::reverse_iterator node = nodes.rbegin();
|
||||||
node = nodes.rbegin();
|
|
||||||
node != nodes.rend();
|
node != nodes.rend();
|
||||||
++node)
|
++node)
|
||||||
delete *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.first = nodes.size();
|
||||||
result.second = 0;
|
result.second = 0;
|
||||||
|
|
||||||
for (typename vector<Node*, ALLOC(Node*) >::const_iterator
|
for (typename vector<Node*>::const_iterator node = nodes.begin();
|
||||||
node = nodes.begin();
|
|
||||||
node != nodes.end(); ++node)
|
node != nodes.end(); ++node)
|
||||||
result.second += (*node)->edges().size();
|
result.second += (*node)->edges().size();
|
||||||
|
|
||||||
|
|
@ -964,7 +1016,7 @@ Graph<EdgeContainer>::subgraphStats(const size_type index) const
|
||||||
if (index >= s)
|
if (index >= s)
|
||||||
throw NodeIndexException();
|
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);
|
BitArray visited_nodes(s);
|
||||||
visited_nodes.clear(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.
|
* 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*) >
|
inline list<Graph<EdgeList>::Edge*>::const_iterator
|
||||||
::const_iterator
|
|
||||||
EdgeList::find(const Graph<EdgeList>::Edge* edge) const
|
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
|
* between the actual values of the edges (not the
|
||||||
* pointers).
|
* 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
|
* 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.
|
* 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)
|
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
|
* between the actual values of the edges (not the
|
||||||
* pointers).
|
* 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
|
* 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.
|
* 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*) >
|
inline slist<Graph<EdgeSlist>::Edge*>::const_iterator
|
||||||
::const_iterator
|
|
||||||
EdgeSlist::find(const Graph<EdgeSlist>::Edge* edge) const
|
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
|
* between the actual values of the edges (not the
|
||||||
* pointers).
|
* 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
|
* 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.
|
* 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*) >
|
inline slist<Graph<EdgeSlist>::Edge*>::iterator
|
||||||
::iterator
|
|
||||||
EdgeSlist::find(const Graph<EdgeSlist>::Edge* edge)
|
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
|
* between the actual values of the edges (not the
|
||||||
* pointers).
|
* pointers).
|
||||||
*
|
*
|
||||||
* Returns: A slist<Graph<EdgeSlist>::Edge*, ALLOC>::iterator
|
* Returns: A slist<Graph<EdgeSlist>::Edge*>::iterator
|
||||||
* pointing to the edge in the list or
|
* 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.
|
* 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*) >
|
inline vector<Graph<EdgeVector>::Edge*>::const_iterator
|
||||||
::const_iterator
|
|
||||||
EdgeVector::find(const Graph<EdgeVector>::Edge* edge) const
|
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
|
* between the actual values of the edges (not the
|
||||||
* pointers).
|
* 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
|
* 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.
|
* 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*) >
|
inline vector<Graph<EdgeVector>::Edge*>::iterator
|
||||||
::iterator
|
|
||||||
EdgeVector::find(const Graph<EdgeVector>::Edge* edge)
|
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
|
* between the actual values of the edges (not the
|
||||||
* pointers).
|
* pointers).
|
||||||
*
|
*
|
||||||
* Returns: A vector<Graph<EdgeVector>::Edge*, ALLOC>::iterator
|
* Returns: A vector<Graph<EdgeVector>::Edge*>::iterator
|
||||||
* pointing to the edge in the container or
|
* 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.
|
* is not found in the container.
|
||||||
*
|
*
|
||||||
* ------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------- */
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2004
|
* Copyright (C) 2004, 2005
|
||||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* 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)
|
if (min > max)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
list<Interval, ALLOC(Interval) >::iterator interval;
|
list<Interval>::iterator interval;
|
||||||
for (interval = intervals.begin();
|
for (interval = intervals.begin();
|
||||||
interval != intervals.end() && interval->second + 1 < min;
|
interval != intervals.end() && interval->second + 1 < min;
|
||||||
++interval)
|
++interval)
|
||||||
|
|
@ -68,14 +68,14 @@ void IntervalList::merge(unsigned long int min, unsigned long int max)
|
||||||
if (interval->second < max)
|
if (interval->second < max)
|
||||||
{
|
{
|
||||||
interval->second = max;
|
interval->second = max;
|
||||||
list<Interval, ALLOC(Interval) >::iterator interval2 = interval;
|
list<Interval>::iterator interval2 = interval;
|
||||||
++interval2;
|
++interval2;
|
||||||
while (interval2 != intervals.end()
|
while (interval2 != intervals.end()
|
||||||
&& interval2->first <= interval->second + 1)
|
&& interval2->first <= interval->second + 1)
|
||||||
{
|
{
|
||||||
if (interval->second < interval2->second)
|
if (interval->second < interval2->second)
|
||||||
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;
|
++interval2;
|
||||||
intervals.erase(interval_to_erase);
|
intervals.erase(interval_to_erase);
|
||||||
}
|
}
|
||||||
|
|
@ -97,7 +97,7 @@ void IntervalList::remove(unsigned long int min, unsigned long int max)
|
||||||
if (min > max)
|
if (min > max)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
list<Interval, ALLOC(Interval) >::iterator interval;
|
list<Interval>::iterator interval;
|
||||||
for (interval = intervals.begin();
|
for (interval = intervals.begin();
|
||||||
interval != intervals.end() && interval->second < min;
|
interval != intervals.end() && interval->second < min;
|
||||||
++interval)
|
++interval)
|
||||||
|
|
@ -126,7 +126,7 @@ void IntervalList::remove(unsigned long int min, unsigned long int max)
|
||||||
}
|
}
|
||||||
else /* min <= imin <= imax <= max */
|
else /* min <= imin <= imax <= max */
|
||||||
{
|
{
|
||||||
list<Interval, ALLOC(Interval) >::iterator interval_to_erase = interval;
|
list<Interval>::iterator interval_to_erase = interval;
|
||||||
++interval;
|
++interval;
|
||||||
intervals.erase(interval_to_erase);
|
intervals.erase(interval_to_erase);
|
||||||
}
|
}
|
||||||
|
|
@ -148,7 +148,7 @@ bool IntervalList::covers(unsigned long int min, unsigned long int max) const
|
||||||
if (min > max)
|
if (min > max)
|
||||||
return true; /* empty interval is always covered */
|
return true; /* empty interval is always covered */
|
||||||
|
|
||||||
list<Interval, ALLOC(Interval) >::const_iterator interval;
|
list<Interval>::const_iterator interval;
|
||||||
for (interval = intervals.begin();
|
for (interval = intervals.begin();
|
||||||
interval != intervals.end() && min > interval->second;
|
interval != intervals.end() && min > interval->second;
|
||||||
++interval)
|
++interval)
|
||||||
|
|
@ -173,8 +173,7 @@ string IntervalList::toString() const
|
||||||
* ------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------- */
|
||||||
{
|
{
|
||||||
string s;
|
string s;
|
||||||
for (list<Interval, ALLOC(Interval) >::const_iterator
|
for (list<Interval>::const_iterator interval = intervals.begin();
|
||||||
interval = intervals.begin();
|
|
||||||
interval != intervals.end();
|
interval != intervals.end();
|
||||||
++interval)
|
++interval)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2004
|
* Copyright (C) 2004, 2005
|
||||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
|
@ -74,13 +74,15 @@ public:
|
||||||
unsigned long int operator++(int); /* Postfix increment. */
|
unsigned long int operator++(int); /* Postfix increment. */
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const list<Interval, ALLOC(Interval) >* /* The interval list */
|
const list<Interval>* interval_list; /* The interval list
|
||||||
interval_list; /* associated with the */
|
* associated with the
|
||||||
/* iterator. */
|
* iterator.
|
||||||
|
*/
|
||||||
|
|
||||||
list<Interval, ALLOC(Interval) > /* An iterator pointing */
|
list<Interval>::const_iterator interval; /* An iterator pointing at
|
||||||
::const_iterator interval; /* at the current */
|
* the current intrerval
|
||||||
/* interval list. */
|
* list.
|
||||||
|
*/
|
||||||
|
|
||||||
unsigned long int element; /* Element currently
|
unsigned long int element; /* Element currently
|
||||||
* pointed to by the
|
* pointed to by the
|
||||||
|
|
@ -143,8 +145,7 @@ public:
|
||||||
* iterators.
|
* iterators.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef list<Interval, ALLOC(Interval) > /* Size type. */
|
typedef list<Interval>::size_type size_type; /* Size type. */
|
||||||
::size_type size_type;
|
|
||||||
|
|
||||||
size_type size() const; /* Tell the number of
|
size_type size() const; /* Tell the number of
|
||||||
* disjoint intervals in
|
* disjoint intervals in
|
||||||
|
|
@ -170,7 +171,7 @@ public:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private:
|
private:
|
||||||
list<Interval, ALLOC(Interval) > intervals; /* List of intervals. */
|
list<Interval> intervals; /* List of intervals. */
|
||||||
|
|
||||||
friend class const_iterator;
|
friend class const_iterator;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 1999, 2000, 2001, 2002
|
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
|
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
|
@ -22,12 +22,6 @@
|
||||||
|
|
||||||
#include <config.h>
|
#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
|
#ifdef HAVE_OBSTACK_H
|
||||||
|
|
||||||
/* GNU libc 2.3.2's copy of obstack.h uses a definition of __INT_TO_PTR
|
/* GNU libc 2.3.2's copy of obstack.h uses a definition of __INT_TO_PTR
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2004
|
* Copyright (C) 2004, 2005
|
||||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
|
@ -44,9 +44,9 @@ static LtlFormula* result; /* This variable stores the
|
||||||
* ltl_parse.
|
* ltl_parse.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static std::set<LtlFormula*, less<LtlFormula*>, /* Intermediate results. */
|
static std::set<LtlFormula*> intermediate_results; /* Intermediate results.
|
||||||
ALLOC(LtlFormula*) > /* (This set is used */
|
* (This set is used
|
||||||
intermediate_results; /* for keeping track of
|
* for keeping track of
|
||||||
* the subformulas of a
|
* the subformulas of a
|
||||||
* partially constructed
|
* partially constructed
|
||||||
* formula in case the
|
* formula in case the
|
||||||
|
|
@ -426,8 +426,8 @@ LtlFormula* parseFormula(istream& stream)
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
for (std::set<LtlFormula*, less<LtlFormula*>, ALLOC(LtlFormula*) >
|
for (std::set<LtlFormula*>::const_iterator
|
||||||
::const_iterator f = intermediate_results.begin();
|
f = intermediate_results.begin();
|
||||||
f != intermediate_results.end();
|
f != intermediate_results.end();
|
||||||
++f)
|
++f)
|
||||||
LtlFormula::destruct(*f);
|
LtlFormula::destruct(*f);
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 1999, 2000, 2001, 2002
|
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* 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.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
#pragma implementation
|
|
||||||
#endif /* __GNUC__ */
|
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include "FormulaWriter.h"
|
#include "FormulaWriter.h"
|
||||||
#include "LtlFormula.h"
|
#include "LtlFormula.h"
|
||||||
|
|
@ -28,10 +24,8 @@
|
||||||
namespace Ltl
|
namespace Ltl
|
||||||
{
|
{
|
||||||
|
|
||||||
map<LtlFormula*, unsigned long int, /* Shared storage for */
|
set<LtlFormula*, LtlFormula::ptr_less> /* Shared storage for */
|
||||||
LtlFormula::ptr_less, /* LTL formulae. */
|
LtlFormula::formula_storage; /* LTL formulae. */
|
||||||
ALLOC(unsigned long int) >
|
|
||||||
LtlFormula::formula_storage;
|
|
||||||
|
|
||||||
unsigned long int /* Upper limit for the */
|
unsigned long int /* Upper limit for the */
|
||||||
LtlFormula::eval_proposition_id_limit; /* atomic proposition
|
LtlFormula::eval_proposition_id_limit; /* atomic proposition
|
||||||
|
|
@ -42,8 +36,6 @@ unsigned long int /* Upper limit for the */
|
||||||
* truth assignment).
|
* truth assignment).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
*
|
*
|
||||||
* Function for obtaining the infix symbol associated with a given
|
* Function for obtaining the infix symbol associated with a given
|
||||||
|
|
@ -147,12 +139,10 @@ public:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private:
|
private:
|
||||||
stack<LtlFormula*,
|
stack<LtlFormula*, deque<LtlFormula*> >
|
||||||
deque<LtlFormula*, ALLOC(LtlFormula*) > >
|
|
||||||
formula_stack;
|
formula_stack;
|
||||||
|
|
||||||
stack<bool, deque<bool, ALLOC(bool) > >
|
stack<bool, deque<bool> > negation_stack;
|
||||||
negation_stack;
|
|
||||||
|
|
||||||
NnfConverter(const NnfConverter&); /* Prevent copying and */
|
NnfConverter(const NnfConverter&); /* Prevent copying and */
|
||||||
NnfConverter& operator=(const NnfConverter&); /* assignment of
|
NnfConverter& operator=(const NnfConverter&); /* assignment of
|
||||||
|
|
@ -203,8 +193,7 @@ class SubformulaCollector
|
||||||
public:
|
public:
|
||||||
SubformulaCollector /* Constructor. */
|
SubformulaCollector /* Constructor. */
|
||||||
(stack<const LtlFormula*,
|
(stack<const LtlFormula*,
|
||||||
deque<const LtlFormula*,
|
deque<const LtlFormula*> >&
|
||||||
ALLOC(const LtlFormula*) > >&
|
|
||||||
result_stack);
|
result_stack);
|
||||||
|
|
||||||
~SubformulaCollector(); /* Destructor. */
|
~SubformulaCollector(); /* Destructor. */
|
||||||
|
|
@ -216,8 +205,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
stack<const LtlFormula*, /* Stack of subformulae. */
|
stack<const LtlFormula*, /* Stack of subformulae. */
|
||||||
deque<const LtlFormula*,
|
deque<const LtlFormula*> >&
|
||||||
ALLOC(const LtlFormula*) > >&
|
|
||||||
subformula_stack;
|
subformula_stack;
|
||||||
|
|
||||||
SubformulaCollector(const SubformulaCollector&); /* Prevent copying and */
|
SubformulaCollector(const SubformulaCollector&); /* Prevent copying and */
|
||||||
|
|
@ -389,9 +377,7 @@ inline void FormulaSizeCounter::operator()(const LtlFormula*, int)
|
||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
inline SubformulaCollector::SubformulaCollector
|
inline SubformulaCollector::SubformulaCollector
|
||||||
(stack<const LtlFormula*, deque<const LtlFormula*,
|
(stack<const LtlFormula*, deque<const LtlFormula*> >& result_stack) :
|
||||||
ALLOC(const LtlFormula*) > >&
|
|
||||||
result_stack) :
|
|
||||||
subformula_stack(result_stack)
|
subformula_stack(result_stack)
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
|
|
@ -773,9 +759,7 @@ unsigned long int LtlFormula::size() const
|
||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
void LtlFormula::collectSubformulae
|
void LtlFormula::collectSubformulae
|
||||||
(stack<const LtlFormula*, deque<const LtlFormula*,
|
(stack<const LtlFormula*, deque<const LtlFormula*> >& result_stack) const
|
||||||
ALLOC(const LtlFormula*) > >&
|
|
||||||
result_stack) const
|
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* Description: Collects the subformulae of a LtlFormula into a stack. After
|
* 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;
|
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
|
void LtlFormula::print(Exceptional_ostream& estream, OutputMode mode) const
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
|
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
|
@ -23,7 +23,7 @@
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <map>
|
#include <set>
|
||||||
#include <stack>
|
#include <stack>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "LbttAlloc.h"
|
#include "LbttAlloc.h"
|
||||||
|
|
@ -188,13 +188,6 @@ public:
|
||||||
* input stream.
|
* 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 */
|
void print /* Writes the formula to */
|
||||||
(ostream& stream = cout, /* an output stream. */
|
(ostream& stream = cout, /* an output stream. */
|
||||||
OutputMode mode = LTL_INFIX) const;
|
OutputMode mode = LTL_INFIX) const;
|
||||||
|
|
@ -250,6 +243,10 @@ protected:
|
||||||
unsigned int is_constant : 1; /* operators and atomic */
|
unsigned int is_constant : 1; /* operators and atomic */
|
||||||
} info_flags; /* propositions. */
|
} info_flags; /* propositions. */
|
||||||
|
|
||||||
|
unsigned long int refcount; /* Number of references to
|
||||||
|
* `this' LtlFormula.
|
||||||
|
*/
|
||||||
|
|
||||||
static LtlFormula& /* Updates the shared */
|
static LtlFormula& /* Updates the shared */
|
||||||
insertToStorage(LtlFormula* f); /* formula storage with
|
insertToStorage(LtlFormula* f); /* formula storage with
|
||||||
* a new formula.
|
* a new formula.
|
||||||
|
|
@ -264,21 +261,18 @@ private:
|
||||||
|
|
||||||
void collectSubformulae /* Builds a stack of the */
|
void collectSubformulae /* Builds a stack of the */
|
||||||
(stack<const LtlFormula*, /* subformulae of the */
|
(stack<const LtlFormula*, /* subformulae of the */
|
||||||
deque<const LtlFormula*, /* formula. */
|
deque<const LtlFormula*> >& /* formula. */
|
||||||
ALLOC(const LtlFormula*) > >&
|
|
||||||
result_stack) const;
|
result_stack) const;
|
||||||
|
|
||||||
typedef pair<bool, const LtlFormula*> /* Shorthand type */
|
typedef pair<bool, const LtlFormula*> /* Shorthand type */
|
||||||
FormulaStackElement; /* definitions for the */
|
FormulaStackElement; /* definitions for the */
|
||||||
typedef stack<FormulaStackElement, /* propositional */
|
typedef stack<FormulaStackElement, /* propositional */
|
||||||
deque<FormulaStackElement, /* satisfiability */
|
deque<FormulaStackElement> > /* satisfiability */
|
||||||
ALLOC(FormulaStackElement) > >/* checking algorithm. */
|
FormulaStack; /* checking algorithm. */
|
||||||
FormulaStack;
|
|
||||||
typedef pair<FormulaStack, Bitset>
|
typedef pair<FormulaStack, Bitset>
|
||||||
TableauStackElement;
|
TableauStackElement;
|
||||||
typedef stack<TableauStackElement,
|
typedef stack<TableauStackElement,
|
||||||
deque<TableauStackElement,
|
deque<TableauStackElement> >
|
||||||
ALLOC(TableauStackElement) > >
|
|
||||||
TableauStack;
|
TableauStack;
|
||||||
|
|
||||||
bool sat_eval /* Helper function for */
|
bool sat_eval /* Helper function for */
|
||||||
|
|
@ -288,9 +282,8 @@ private:
|
||||||
* formula.
|
* formula.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static map<LtlFormula*, unsigned long int, /* Shared storage for */
|
static set<LtlFormula*, ptr_less> /* Shared storage for */
|
||||||
ptr_less, ALLOC(unsigned long int) > /* LTL formulae. */
|
formula_storage; /* LTL formulae. */
|
||||||
formula_storage;
|
|
||||||
|
|
||||||
static unsigned long int /* Upper limit for the */
|
static unsigned long int /* Upper limit for the */
|
||||||
eval_proposition_id_limit; /* atomic proposition
|
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.
|
* A class for atomic propositions.
|
||||||
|
|
@ -474,7 +477,7 @@ private:
|
||||||
* to satisfy the
|
* to satisfy the
|
||||||
* LtlFormula member
|
* LtlFormula member
|
||||||
* function interface.
|
* 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
|
* 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,
|
if (--f->refcount == 0)
|
||||||
ALLOC(unsigned long int) >::iterator
|
|
||||||
deleter;
|
|
||||||
|
|
||||||
deleter = formula_storage.find(f);
|
|
||||||
if (--deleter->second == 0)
|
|
||||||
{
|
{
|
||||||
formula_storage.erase(deleter);
|
formula_storage.erase(f);
|
||||||
delete f;
|
delete f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1147,7 +1143,7 @@ inline LtlFormula* LtlFormula::clone()
|
||||||
*
|
*
|
||||||
* ------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------- */
|
||||||
{
|
{
|
||||||
formula_storage.find(this)->second++;
|
++refcount;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1241,8 +1237,7 @@ inline LtlFormula* LtlFormula::read(istream& stream)
|
||||||
*
|
*
|
||||||
* ------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------- */
|
||||||
{
|
{
|
||||||
Exceptional_istream estream(&stream, ios::badbit | ios::failbit);
|
return parseFormula(stream);
|
||||||
return read(estream);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
|
|
@ -1303,8 +1298,6 @@ inline Exceptional_ostream& operator<<
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
inline LtlFormula& LtlFormula::insertToStorage(LtlFormula* f)
|
inline LtlFormula& LtlFormula::insertToStorage(LtlFormula* f)
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
|
|
@ -1317,19 +1310,15 @@ inline LtlFormula& LtlFormula::insertToStorage(LtlFormula* f)
|
||||||
*
|
*
|
||||||
* ------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------- */
|
||||||
{
|
{
|
||||||
map<LtlFormula*, unsigned long int, LtlFormula::ptr_less,
|
set<LtlFormula*, ptr_less>::iterator inserter = formula_storage.find(f);
|
||||||
ALLOC(unsigned long int) >::iterator
|
|
||||||
inserter;
|
|
||||||
|
|
||||||
inserter = formula_storage.find(f);
|
|
||||||
if (inserter != formula_storage.end())
|
if (inserter != formula_storage.end())
|
||||||
{
|
{
|
||||||
delete f;
|
delete f;
|
||||||
inserter->second++;
|
++(*inserter)->refcount;
|
||||||
return *(inserter->first);
|
return **inserter;
|
||||||
}
|
}
|
||||||
|
|
||||||
formula_storage.insert(make_pair(f, 1));
|
formula_storage.insert(f);
|
||||||
return *f;
|
return *f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1571,8 +1560,7 @@ inline Atom& Atom::construct(long int a)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
inline Atom::Atom(long int a) :
|
inline Atom::Atom(long int a) : atom(a)
|
||||||
LtlFormula(), atom(a)
|
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* Description: Constructor for class Atom. Creates a new propositional atom.
|
* 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>
|
template<class Operator>
|
||||||
inline UnaryFormula<Operator>::UnaryFormula(LtlFormula* f) :
|
inline UnaryFormula<Operator>::UnaryFormula(LtlFormula* f) : subformula(f)
|
||||||
LtlFormula(), subformula(f)
|
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* Description: Constructs an LTL formula with a unary operator.
|
* Description: Constructs an LTL formula with a unary operator.
|
||||||
|
|
@ -2189,7 +2176,7 @@ BinaryFormula<Operator>::construct(LtlFormula& f1, LtlFormula* f2)
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
template<class Operator>
|
template<class Operator>
|
||||||
inline BinaryFormula<Operator>::BinaryFormula(LtlFormula* f1, LtlFormula* f2) :
|
inline BinaryFormula<Operator>::BinaryFormula(LtlFormula* f1, LtlFormula* f2) :
|
||||||
LtlFormula(), subformula1(f1), subformula2(f2)
|
subformula1(f1), subformula2(f2)
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* Description: Constructs a binary LTL formula.
|
* Description: Constructs a binary LTL formula.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 1999, 2000, 2001, 2002
|
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* 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 never-interactive
|
||||||
%option noyywrap
|
%option noyywrap
|
||||||
|
%option nounput
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 1999, 2000, 2001, 2002
|
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 1999, 2000, 2001, 2002
|
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* 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.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
#pragma implementation
|
|
||||||
#endif /* __GNUC__ */
|
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
@ -66,8 +62,7 @@ void NeverClaimAutomaton::clear()
|
||||||
*
|
*
|
||||||
* ------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------- */
|
||||||
{
|
{
|
||||||
for (vector<StateInfo*, ALLOC(StateInfo*) >::iterator
|
for (vector<StateInfo*>::iterator state = state_list.begin();
|
||||||
state = state_list.begin();
|
|
||||||
state != state_list.end();
|
state != state_list.end();
|
||||||
++state)
|
++state)
|
||||||
delete (*state);
|
delete (*state);
|
||||||
|
|
@ -158,8 +153,7 @@ void NeverClaimAutomaton::write(const char* output_filename)
|
||||||
* `-1'.
|
* `-1'.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
for (vector<StateInfo*, ALLOC(StateInfo*) >::const_iterator
|
for (vector<StateInfo*>::const_iterator state = state_list.begin();
|
||||||
state = state_list.begin();
|
|
||||||
state != state_list.end();
|
state != state_list.end();
|
||||||
++state)
|
++state)
|
||||||
{
|
{
|
||||||
|
|
@ -167,7 +161,7 @@ void NeverClaimAutomaton::write(const char* output_filename)
|
||||||
+ ((*state)->initial() ? "1" : "0") + ' '
|
+ ((*state)->initial() ? "1" : "0") + ' '
|
||||||
+ ((*state)->accepting() ? "0 " : "") + "-1\n";
|
+ ((*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().begin();
|
||||||
transition != (*state)->transitions().end(); ++transition)
|
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.begin();
|
||||||
transition != state_transitions.end();
|
transition != state_transitions.end();
|
||||||
++transition)
|
++transition)
|
||||||
|
|
@ -312,7 +306,7 @@ ParseErrorException::ParseErrorException
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
string space_string(msg.substr(0, error_pos));
|
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')
|
if (space_string[c] != ' ' && space_string[c] != '\t')
|
||||||
space_string[c] = ' ';
|
space_string[c] = ' ';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
|
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
|
@ -93,12 +93,13 @@ public:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private:
|
private:
|
||||||
vector<StateInfo*, ALLOC(StateInfo*) > /* States of the */
|
vector<StateInfo*> state_list; /* States of the automaton.
|
||||||
state_list; /* automaton. */
|
*/
|
||||||
|
|
||||||
map<string, StateInfo*, less<string>, /* Mapping from state */
|
map<string, StateInfo*> label_mapping; /* Mapping from state
|
||||||
ALLOC(StateInfo*) > /* labels to the states */
|
* labels to the states
|
||||||
label_mapping; /* itself. */
|
* itself.
|
||||||
|
*/
|
||||||
|
|
||||||
StateInfo* current_state; /* Pointer to the state
|
StateInfo* current_state; /* Pointer to the state
|
||||||
* introduced most recently
|
* introduced most recently
|
||||||
|
|
@ -142,9 +143,9 @@ public:
|
||||||
/* of the state.
|
/* of the state.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const multimap<Cstr, Cstr*, less<Cstr>, /* Returns the labels of */
|
const multimap<Cstr, Cstr*>& transitions() const; /* Returns the labels of
|
||||||
ALLOC(Cstr*) >& /* the state's successor */
|
* the state's successor
|
||||||
transitions() const; /* states, including the
|
* states, including the
|
||||||
* conditions controlling
|
* conditions controlling
|
||||||
* the enabledness of the
|
* the enabledness of the
|
||||||
* transition.
|
* transition.
|
||||||
|
|
@ -174,8 +175,8 @@ private:
|
||||||
* accepting state?
|
* accepting state?
|
||||||
*/
|
*/
|
||||||
|
|
||||||
multimap<Cstr, Cstr*, less<Cstr>, ALLOC(Cstr*) > /* Labels of the state's */
|
multimap<Cstr, Cstr*> state_transitions; /* Labels of the state's
|
||||||
state_transitions; /* successors, including
|
* successors, including
|
||||||
* the guard formulae
|
* the guard formulae
|
||||||
* controlling the
|
* controlling the
|
||||||
* enabledness of the
|
* enabledness of the
|
||||||
|
|
@ -373,9 +374,7 @@ inline bool& NeverClaimAutomaton::StateInfo::accepting()
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
inline const multimap<NeverClaimAutomaton::Cstr, NeverClaimAutomaton::Cstr*,
|
inline const multimap<NeverClaimAutomaton::Cstr, NeverClaimAutomaton::Cstr*>&
|
||||||
less<NeverClaimAutomaton::Cstr>,
|
|
||||||
ALLOC(NeverClaimAutomaton::Cstr*) >&
|
|
||||||
NeverClaimAutomaton::StateInfo::transitions() const
|
NeverClaimAutomaton::StateInfo::transitions() const
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 1999, 2000, 2001, 2002
|
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* 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.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
#pragma implementation
|
|
||||||
#endif /* __GNUC__ */
|
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <stack>
|
#include <stack>
|
||||||
|
|
@ -53,9 +49,8 @@ void PathEvaluator::reset()
|
||||||
current_loop_state = 0;
|
current_loop_state = 0;
|
||||||
path_states.clear();
|
path_states.clear();
|
||||||
|
|
||||||
for (map<const LtlFormula*, BitArray*, LtlFormula::ptr_less,
|
for (map<const LtlFormula*, BitArray*, LtlFormula::ptr_less>::iterator
|
||||||
ALLOC(BitArray*) >::iterator it
|
it = eval_info.begin();
|
||||||
= eval_info.begin();
|
|
||||||
it != eval_info.end();
|
it != eval_info.end();
|
||||||
++it)
|
++it)
|
||||||
delete it->second;
|
delete it->second;
|
||||||
|
|
@ -65,26 +60,25 @@ void PathEvaluator::reset()
|
||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
bool PathEvaluator::evaluate
|
bool PathEvaluator::evaluate
|
||||||
(const LtlFormula& formula, const StateSpace& statespace,
|
(const LtlFormula& formula, const StateSpace::Path& prefix,
|
||||||
const vector<StateSpace::size_type, ALLOC(StateSpace::size_type) >&
|
const StateSpace::Path& cycle, const StateSpace& statespace)
|
||||||
states_on_path,
|
|
||||||
StateSpace::size_type loop_state)
|
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* Description: Evaluates an LTL formula in a state space in which the states
|
* Description: Evaluates an LTL formula in a path formed from a prefix and
|
||||||
* are connected into a non-branching sequence that ends in a
|
* an infinitely repeating cycle of states in a state space.
|
||||||
* loop.
|
|
||||||
*
|
*
|
||||||
* Arguments: formula -- Formula to be evaluated.
|
* Arguments: formula -- Formula to be evaluated.
|
||||||
* statespace -- State space from which the path is
|
* prefix -- A StateSpace::Path object corresponding to
|
||||||
* extracted.
|
* the prefix of the path. Only the state
|
||||||
* states_on_path -- Mapping between states in the path and
|
* identifiers in the path elements are used;
|
||||||
* the states in `statespace' such that
|
* the function will not require `prefix' to
|
||||||
* `statespace[states_on_path[i]]'
|
* actually represent a path in `statespace'.
|
||||||
* corresponds to the ith state of the path.
|
* cycle -- A StateSpace::Path object corresponding to
|
||||||
* loop_state -- Number of the state in the path to which
|
* the infinitely repeating cycle. Only the
|
||||||
* the ``last'' state of the path is
|
* state identifiers in the path elements are
|
||||||
* connected.
|
* 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.
|
* Returns: `true' if and only if the LTL formula holds in the path.
|
||||||
*
|
*
|
||||||
|
|
@ -92,13 +86,21 @@ bool PathEvaluator::evaluate
|
||||||
{
|
{
|
||||||
reset();
|
reset();
|
||||||
|
|
||||||
if (states_on_path.empty() || loop_state >= states_on_path.size())
|
if (cycle.empty())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
current_formula = &formula;
|
current_formula = &formula;
|
||||||
current_path = &statespace;
|
current_path = &statespace;
|
||||||
current_loop_state = loop_state;
|
current_loop_state = prefix.size();
|
||||||
path_states = states_on_path;
|
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();
|
return eval();
|
||||||
}
|
}
|
||||||
|
|
@ -128,8 +130,7 @@ bool PathEvaluator::evaluate
|
||||||
current_formula = &formula;
|
current_formula = &formula;
|
||||||
current_path = &statespace;
|
current_path = &statespace;
|
||||||
|
|
||||||
map<StateSpace::size_type, StateSpace::size_type,
|
map<StateSpace::size_type, StateSpace::size_type> ordering;
|
||||||
less<StateSpace::size_type>, ALLOC(StateSpace::size_type) > ordering;
|
|
||||||
|
|
||||||
StateSpace::size_type state = statespace.initialState();
|
StateSpace::size_type state = statespace.initialState();
|
||||||
StateSpace::size_type state_count = 0;
|
StateSpace::size_type state_count = 0;
|
||||||
|
|
@ -173,9 +174,7 @@ bool PathEvaluator::eval()
|
||||||
*
|
*
|
||||||
* ------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------- */
|
||||||
{
|
{
|
||||||
stack<const LtlFormula*, deque<const LtlFormula*,
|
stack<const LtlFormula*, deque<const LtlFormula*> > subformula_stack;
|
||||||
ALLOC(const LtlFormula*) > >
|
|
||||||
subformula_stack;
|
|
||||||
|
|
||||||
const LtlFormula* f;
|
const LtlFormula* f;
|
||||||
BitArray* val;
|
BitArray* val;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
|
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
|
@ -54,11 +54,11 @@ public:
|
||||||
|
|
||||||
bool evaluate /* Tests whether an */
|
bool evaluate /* Tests whether an */
|
||||||
(const LtlFormula& formula, /* LtlFormula holds in a */
|
(const LtlFormula& formula, /* LtlFormula holds in a */
|
||||||
const StateSpace& statespace, /* state space. */
|
const StateSpace::Path& prefix, /* path described by a */
|
||||||
const vector<StateSpace::size_type,
|
const StateSpace::Path& cycle, /* prefix and a cycle of */
|
||||||
ALLOC(StateSpace::size_type) >&
|
const StateSpace& statespace); /* states from a state
|
||||||
states_on_path,
|
* space.
|
||||||
StateSpace::size_type loop_state);
|
*/
|
||||||
|
|
||||||
bool evaluate /* Same as above. */
|
bool evaluate /* Same as above. */
|
||||||
(const LtlFormula& formula,
|
(const LtlFormula& formula,
|
||||||
|
|
@ -105,15 +105,15 @@ private:
|
||||||
* the current path.
|
* the current path.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
vector<StateSpace::size_type, /* Correspondence */
|
vector<StateSpace::size_type> path_states; /* Correspondence
|
||||||
ALLOC(StateSpace::size_type) > /* between states of the */
|
* between states of the
|
||||||
path_states; /* path and the states
|
* path and the states
|
||||||
* of the current state
|
* of the current state
|
||||||
* space.
|
* space.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
map<const LtlFormula*, BitArray*, /* Information about the */
|
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
|
eval_info; /* subformulae of the
|
||||||
* formula to be
|
* formula to be
|
||||||
* evaluated.
|
* evaluated.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 1999, 2000, 2001, 2002
|
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* 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.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
#pragma implementation
|
|
||||||
#endif /* __GNUC__ */
|
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include "BitArray.h"
|
#include "BitArray.h"
|
||||||
#include "PathIterator.h"
|
#include "PathIterator.h"
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 1999, 2000, 2001, 2002
|
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
|
@ -20,10 +20,6 @@
|
||||||
#ifndef PATHITERATOR_H
|
#ifndef PATHITERATOR_H
|
||||||
#define PATHITERATOR_H
|
#define PATHITERATOR_H
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
#pragma interface
|
|
||||||
#endif /* __GNUC__ */
|
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include "StateSpace.h"
|
#include "StateSpace.h"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
|
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
|
@ -393,8 +393,8 @@ public:
|
||||||
typedef ProductEdgeCollection EdgeContainerType; /* required for making */
|
typedef ProductEdgeCollection EdgeContainerType; /* required for making */
|
||||||
/* Product<Operations> */
|
/* Product<Operations> */
|
||||||
struct PathElement; /* suitable for */
|
struct PathElement; /* suitable for */
|
||||||
typedef deque<PathElement, ALLOC(PathElement) > /* instantiating the */
|
typedef deque<PathElement> Path; /* instantiating the
|
||||||
Path; /* SccCollection
|
* SccCollection
|
||||||
* template (see
|
* template (see
|
||||||
* SccCollection.h).
|
* SccCollection.h).
|
||||||
*/
|
*/
|
||||||
|
|
@ -419,9 +419,7 @@ private:
|
||||||
Graph<GraphEdgeContainer>::Path >& cycle, /* segment of the cycle */
|
Graph<GraphEdgeContainer>::Path >& cycle, /* segment of the cycle */
|
||||||
size_type source_state_id, Edge transition, /* in a witness for the */
|
size_type source_state_id, Edge transition, /* in a witness for the */
|
||||||
const size_type root_id, /* nonemptiness of the */
|
const size_type root_id, /* nonemptiness of the */
|
||||||
const map<size_type, PathElement, /* product. */
|
const map<size_type, PathElement>& /* product. */
|
||||||
less<size_type>,
|
|
||||||
ALLOC(PathElement) >&
|
|
||||||
predecessor) const;
|
predecessor) const;
|
||||||
|
|
||||||
Operations operations; /* Operations for
|
Operations operations; /* Operations for
|
||||||
|
|
@ -524,8 +522,8 @@ public:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const Graph<GraphEdgeContainer>::Edge* edge_1; /* Components of the */
|
GraphEdgeContainer::const_iterator edge_1; /* Components of the */
|
||||||
const Graph<GraphEdgeContainer>::Edge* edge_2; /* transition. */
|
GraphEdgeContainer::const_iterator edge_2; /* transition. */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -655,9 +653,10 @@ protected:
|
||||||
* acceptance sets.
|
* acceptance sets.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef deque<AcceptanceStackElement, /* Stack formed from */
|
typedef deque<AcceptanceStackElement> /* Stack formed from */
|
||||||
ALLOC(AcceptanceStackElement) > /* the above */
|
AcceptanceStack; /* the above
|
||||||
AcceptanceStack; /* associations. */
|
* associations.
|
||||||
|
*/
|
||||||
|
|
||||||
AcceptanceStack acceptance_stack; /* Stack for storing the
|
AcceptanceStack acceptance_stack; /* Stack for storing the
|
||||||
* dfs numbers of roots
|
* dfs numbers of roots
|
||||||
|
|
@ -877,9 +876,9 @@ private:
|
||||||
* reachable.
|
* reachable.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
set<size_type, less<size_type>, /* Set of states from */
|
set<size_type> reachability_info; /* Set of states from
|
||||||
ALLOC(size_type) > /* which an accepting */
|
* which an accepting
|
||||||
reachability_info; /* component is known to
|
* component is known to
|
||||||
* be reachable in the
|
* be reachable in the
|
||||||
* product.
|
* product.
|
||||||
*/
|
*/
|
||||||
|
|
@ -928,9 +927,9 @@ public:
|
||||||
|
|
||||||
~AcceptingComponentFinder(); /* Destructor. */
|
~AcceptingComponentFinder(); /* Destructor. */
|
||||||
|
|
||||||
typedef set<size_type, less<size_type>, /* Type definition for */
|
typedef set<size_type> SccType; /* Type definition for
|
||||||
ALLOC(size_type) > /* the set of product */
|
* the set of product
|
||||||
SccType; /* state identifiers in
|
* state identifiers in
|
||||||
* an accepting
|
* an accepting
|
||||||
* strongly connected
|
* strongly connected
|
||||||
* component.
|
* component.
|
||||||
|
|
@ -1369,10 +1368,9 @@ void Product<Operations>::findWitness
|
||||||
unsigned long int number_of_collected_acceptance_sets
|
unsigned long int number_of_collected_acceptance_sets
|
||||||
= collected_acceptance_sets.count(number_of_acceptance_sets);
|
= collected_acceptance_sets.count(number_of_acceptance_sets);
|
||||||
|
|
||||||
deque<size_type, ALLOC(size_type) > search_queue;
|
deque<size_type> search_queue;
|
||||||
set<size_type, less<size_type>, ALLOC(size_type) > visited;
|
set<size_type> visited;
|
||||||
map<size_type, PathElement, less<size_type>, ALLOC(PathElement) >
|
map<size_type, PathElement> shortest_path_predecessor;
|
||||||
shortest_path_predecessor;
|
|
||||||
|
|
||||||
size_type bfs_root = search_start_state;
|
size_type bfs_root = search_start_state;
|
||||||
|
|
||||||
|
|
@ -1475,8 +1473,7 @@ void Product<Operations>::addCycleSegment
|
||||||
(pair<Graph<GraphEdgeContainer>::Path, Graph<GraphEdgeContainer>::Path>&
|
(pair<Graph<GraphEdgeContainer>::Path, Graph<GraphEdgeContainer>::Path>&
|
||||||
cycle,
|
cycle,
|
||||||
size_type source_state_id, Edge transition, const size_type root_id,
|
size_type source_state_id, Edge transition, const size_type root_id,
|
||||||
const map<size_type, PathElement, less<size_type>, ALLOC(PathElement) >&
|
const map<size_type, PathElement>& predecessor) const
|
||||||
predecessor) const
|
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* Description: Helper function for constructing a segment of an accepting
|
* Description: Helper function for constructing a segment of an accepting
|
||||||
|
|
@ -1598,7 +1595,7 @@ template <class Operations>
|
||||||
inline Product<Operations>::ProductEdge::ProductEdge
|
inline Product<Operations>::ProductEdge::ProductEdge
|
||||||
(const GraphEdgeContainer::const_iterator& e1,
|
(const GraphEdgeContainer::const_iterator& e1,
|
||||||
const GraphEdgeContainer::const_iterator& e2)
|
const GraphEdgeContainer::const_iterator& e2)
|
||||||
: edge_1(*e1), edge_2(*e2)
|
: edge_1(e1), edge_2(e2)
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* Description: Constructor for class Product<Operations>::ProductEdge.
|
* 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
1063
lbtt/src/ProductAutomaton.cc
Normal file
File diff suppressed because it is too large
Load diff
596
lbtt/src/ProductAutomaton.h
Normal file
596
lbtt/src/ProductAutomaton.h
Normal 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 */
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 1999, 2000, 2001, 2002
|
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
|
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
|
@ -195,10 +195,8 @@ public:
|
||||||
|
|
||||||
/* default assignment operator */
|
/* default assignment operator */
|
||||||
|
|
||||||
typedef set<typename GraphType::size_type, /* Type definition for */
|
typedef set<typename GraphType::size_type> /* Type definition for */
|
||||||
less<typename GraphType::size_type>, /* a set of node id's. */
|
SccType; /* a set of node id's. */
|
||||||
ALLOC(typename GraphType::size_type) >
|
|
||||||
SccType;
|
|
||||||
|
|
||||||
const SccType& operator()() const; /* Returns the set of node
|
const SccType& operator()() const; /* Returns the set of node
|
||||||
* identifiers in a
|
* identifiers in a
|
||||||
|
|
@ -338,10 +336,10 @@ public:
|
||||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||||
|
|
||||||
typedef map<typename GraphType::size_type, /* Type definition for a */
|
typedef map<typename GraphType::size_type, /* Type definition for a */
|
||||||
typename GraphType::size_type, /* mapping between node */
|
typename GraphType::size_type> /* mapping between node */
|
||||||
less<typename GraphType::size_type>, /* identifiers and the */
|
DfsOrdering; /* identifiers and the
|
||||||
ALLOC(typename GraphType::size_type) >/* order in which they */
|
* order in which they
|
||||||
DfsOrdering; /* were encountered in
|
* were encountered in
|
||||||
* the search for
|
* the search for
|
||||||
* strongly connected
|
* strongly connected
|
||||||
* components.
|
* components.
|
||||||
|
|
@ -433,18 +431,19 @@ public:
|
||||||
typename GraphType::size_type lowlink;
|
typename GraphType::size_type lowlink;
|
||||||
};
|
};
|
||||||
|
|
||||||
deque<NodeStackElement, /* Depth-first search */
|
deque<NodeStackElement> node_stack; /* Depth-first search
|
||||||
ALLOC(NodeStackElement) > /* backtracking stack. */
|
* backtracking stack.
|
||||||
node_stack;
|
*/
|
||||||
|
|
||||||
|
|
||||||
NodeStackElement* current_node; /* Pointer to the top
|
NodeStackElement* current_node; /* Pointer to the top
|
||||||
* element of the
|
* element of the
|
||||||
* backtracking stack.
|
* backtracking stack.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
deque<typename GraphType::size_type, /* Stack used for */
|
deque<typename GraphType::size_type> scc_stack; /* Stack used for
|
||||||
ALLOC(typename GraphType::size_type) > /* collecting the nodes */
|
* collecting the nodes
|
||||||
scc_stack; /* in a strongly
|
* in a strongly
|
||||||
* connected component,
|
* connected component,
|
||||||
* excluding the root
|
* excluding the root
|
||||||
* nodes of the
|
* nodes of the
|
||||||
|
|
@ -998,8 +997,7 @@ void SccCollection<GraphType, NodeVisitor>::iterator::getPath
|
||||||
* when exiting from this function).
|
* when exiting from this function).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typename deque<NodeStackElement, ALLOC(NodeStackElement) >::const_iterator
|
typename deque<NodeStackElement>::const_iterator n = node_stack.begin();
|
||||||
n = node_stack.begin();
|
|
||||||
if (n != node_stack.end())
|
if (n != node_stack.end())
|
||||||
{
|
{
|
||||||
for (++n; n != node_stack.end(); ++n)
|
for (++n; n != node_stack.end(); ++n)
|
||||||
|
|
|
||||||
752
lbtt/src/SccIterator.h
Normal file
752
lbtt/src/SccIterator.h
Normal 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 ¤t_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 */
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
|
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
|
@ -42,14 +42,14 @@ extern TestRoundInfo round_info; /* Data structure for
|
||||||
* round.
|
* round.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
extern vector<AlgorithmTestResults, /* Test results for each */
|
extern vector<AlgorithmTestResults> test_results; /* Test results for each
|
||||||
ALLOC(AlgorithmTestResults) > /* implementation. */
|
* implementation.
|
||||||
test_results;
|
*/
|
||||||
|
|
||||||
extern vector<TestStatistics, /* Overall test */
|
|
||||||
ALLOC(TestStatistics) > /* statistics for each */
|
|
||||||
final_statistics; /* implementation. */
|
|
||||||
|
|
||||||
|
extern vector<TestStatistics> final_statistics; /* Overall test
|
||||||
|
* statistics for each
|
||||||
|
* implementation.
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* !SHAREDTESTDATA_H */
|
#endif /* !SHAREDTESTDATA_H */
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 1999, 2000, 2001, 2002
|
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* 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.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
#pragma implementation
|
|
||||||
#endif /* __GNUC__ */
|
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#ifdef HAVE_SSTREAM
|
#ifdef HAVE_SSTREAM
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 1999, 2000, 2001, 2002
|
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
|
@ -20,10 +20,6 @@
|
||||||
#ifndef SPINWRAPPER_H
|
#ifndef SPINWRAPPER_H
|
||||||
#define SPINWRAPPER_H
|
#define SPINWRAPPER_H
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
#pragma interface
|
|
||||||
#endif /* __GNUC__ */
|
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "ExternalTranslator.h"
|
#include "ExternalTranslator.h"
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 1999, 2000, 2001, 2002
|
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* 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.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
#pragma implementation
|
|
||||||
#endif /* __GNUC__ */
|
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "DispUtil.h"
|
#include "DispUtil.h"
|
||||||
#include "Exception.h"
|
#include "Exception.h"
|
||||||
|
#include "IntervalList.h"
|
||||||
#include "SharedTestData.h"
|
#include "SharedTestData.h"
|
||||||
#include "StatDisplay.h"
|
#include "StatDisplay.h"
|
||||||
#include "StringUtil.h"
|
#include "StringUtil.h"
|
||||||
|
|
@ -37,11 +34,51 @@ using namespace ::DispUtil;
|
||||||
using namespace ::SharedTestData;
|
using namespace ::SharedTestData;
|
||||||
using namespace ::StringUtil;
|
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
|
void printBuchiAutomatonStats
|
||||||
(ostream& stream, int indent,
|
(ostream& stream, int indent,
|
||||||
vector<AlgorithmTestResults, ALLOC(AlgorithmTestResults) >::size_type
|
vector<AlgorithmTestResults>::size_type algorithm,
|
||||||
algorithm,
|
|
||||||
int result_id)
|
int result_id)
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
|
|
@ -52,7 +89,7 @@ void printBuchiAutomatonStats
|
||||||
* Arguments: stream -- A reference to the output stream to which the
|
* Arguments: stream -- A reference to the output stream to which the
|
||||||
* information should be written.
|
* information should be written.
|
||||||
* indent -- Number of spaces to leave on the left of the
|
* indent -- Number of spaces to leave on the left of the
|
||||||
* output.
|
* output in verbosity modes >= 3.
|
||||||
* algorithm -- Identifier of the algorithm used for
|
* algorithm -- Identifier of the algorithm used for
|
||||||
* generating the automaton.
|
* generating the automaton.
|
||||||
* result_id -- Selects between the automata constructed from
|
* result_id -- Selects between the automata constructed from
|
||||||
|
|
@ -67,43 +104,75 @@ void printBuchiAutomatonStats
|
||||||
const AutomatonStats& automaton_stats =
|
const AutomatonStats& automaton_stats =
|
||||||
test_results[algorithm].automaton_stats[result_id];
|
test_results[algorithm].automaton_stats[result_id];
|
||||||
|
|
||||||
estream << string(indent, ' ');
|
if (configuration.global_options.verbosity <= 2)
|
||||||
|
{
|
||||||
if (!automaton_stats.buchiAutomatonComputed())
|
if (!automaton_stats.buchiAutomatonComputed())
|
||||||
estream << "not computed";
|
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
|
else
|
||||||
{
|
{
|
||||||
estream << "number of states:" + string(6, ' ')
|
estream << string(indent, ' ');
|
||||||
+ 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)";
|
if (!automaton_stats.buchiAutomatonComputed())
|
||||||
}
|
estream << "not computed";
|
||||||
else
|
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();
|
estream.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
void printProductAutomatonStats
|
void printProductAutomatonStats
|
||||||
(ostream& stream, int indent,
|
(ostream& stream, int indent,
|
||||||
vector<AlgorithmTestResults, ALLOC(AlgorithmTestResults) >::size_type
|
vector<AlgorithmTestResults>::size_type algorithm,
|
||||||
algorithm,
|
|
||||||
int result_id)
|
int result_id)
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
|
|
@ -114,7 +183,7 @@ void printProductAutomatonStats
|
||||||
* Arguments: stream -- A reference to the output stream to which the
|
* Arguments: stream -- A reference to the output stream to which the
|
||||||
* information should be written.
|
* information should be written.
|
||||||
* indent -- Number of spaces to leave on the left of the
|
* indent -- Number of spaces to leave on the left of the
|
||||||
* output.
|
* output in verbosity modes >= 3.
|
||||||
* algorithm -- Identifier of the algorithm used for
|
* algorithm -- Identifier of the algorithm used for
|
||||||
* generating the product automaton.
|
* generating the product automaton.
|
||||||
* result_id -- Selects between the automata constructed from
|
* result_id -- Selects between the automata constructed from
|
||||||
|
|
@ -129,51 +198,71 @@ void printProductAutomatonStats
|
||||||
const AutomatonStats& automaton_stats =
|
const AutomatonStats& automaton_stats =
|
||||||
test_results[algorithm].automaton_stats[result_id];
|
test_results[algorithm].automaton_stats[result_id];
|
||||||
|
|
||||||
estream << string(indent, ' ');
|
if (configuration.global_options.verbosity <= 2)
|
||||||
|
{
|
||||||
if (!automaton_stats.productAutomatonComputed())
|
if (!automaton_stats.productAutomatonComputed())
|
||||||
estream << "not computed";
|
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
|
else
|
||||||
{
|
{
|
||||||
estream << "number of states:" + string(6, ' ');
|
estream << string(indent, ' ');
|
||||||
|
|
||||||
changeStreamFormatting(stream, 9, 0, ios::left);
|
if (!automaton_stats.productAutomatonComputed())
|
||||||
estream << automaton_stats.number_of_product_states;
|
estream << "not computed";
|
||||||
restoreStreamFormatting(stream);
|
else
|
||||||
|
|
||||||
estream << " [";
|
|
||||||
|
|
||||||
if (automaton_stats.number_of_product_states != 0)
|
|
||||||
{
|
{
|
||||||
changeStreamFormatting(stream, 0, 2, ios::fixed);
|
estream << "number of states:" + string(6, ' ');
|
||||||
estream << static_cast<double>
|
|
||||||
(automaton_stats.number_of_product_states)
|
changeStreamFormatting(stream, 9, 0, ios::left);
|
||||||
/ static_cast<double>(automaton_stats.number_of_buchi_states)
|
estream << automaton_stats.number_of_product_states;
|
||||||
/ static_cast<double>(round_info.statespace->size())
|
|
||||||
* 100.0;
|
|
||||||
restoreStreamFormatting(stream);
|
restoreStreamFormatting(stream);
|
||||||
|
|
||||||
estream << "% of worst case ("
|
estream << " [";
|
||||||
<< automaton_stats.number_of_buchi_states
|
|
||||||
* round_info.statespace->size()
|
|
||||||
<< ')';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
estream << "empty automaton";
|
|
||||||
|
|
||||||
estream << "]\n" + string(indent, ' ') + "number of transitions: "
|
if (automaton_stats.number_of_product_states != 0)
|
||||||
+ toString(automaton_stats.number_of_product_transitions);
|
{
|
||||||
|
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();
|
estream.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
void printAcceptanceCycleStats
|
void printAcceptanceCycleStats
|
||||||
(ostream& stream, int indent,
|
(ostream& stream, int indent,
|
||||||
vector<AlgorithmTestResults, ALLOC(AlgorithmTestResults) >::size_type
|
vector<AlgorithmTestResults>::size_type algorithm,
|
||||||
algorithm,
|
|
||||||
int result_id)
|
int result_id)
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
|
|
@ -185,7 +274,7 @@ void printAcceptanceCycleStats
|
||||||
* Arguments: stream -- A reference to the output stream to which the
|
* Arguments: stream -- A reference to the output stream to which the
|
||||||
* information should be written.
|
* information should be written.
|
||||||
* indent -- Number of spaces to leave on the left of the
|
* indent -- Number of spaces to leave on the left of the
|
||||||
* output.
|
* output in verbosity mode >= 3.
|
||||||
* algorithm -- Identifier of the algorithm used for
|
* algorithm -- Identifier of the algorithm used for
|
||||||
* computing the Büchi automaton whose accepting
|
* computing the Büchi automaton whose accepting
|
||||||
* cycles are to be considered.
|
* cycles are to be considered.
|
||||||
|
|
@ -201,49 +290,64 @@ void printAcceptanceCycleStats
|
||||||
const AutomatonStats& automaton_stats =
|
const AutomatonStats& automaton_stats =
|
||||||
test_results[algorithm].automaton_stats[result_id];
|
test_results[algorithm].automaton_stats[result_id];
|
||||||
|
|
||||||
estream << string(indent, ' ');
|
if (configuration.global_options.verbosity <= 2)
|
||||||
|
|
||||||
if (!automaton_stats.emptiness_check_performed)
|
|
||||||
estream << "not computed";
|
|
||||||
else if (configuration.global_options.product_mode == Configuration::LOCAL)
|
|
||||||
{
|
{
|
||||||
estream << string("cycle ");
|
if (!automaton_stats.emptiness_check_performed)
|
||||||
|
estream << " N/A";
|
||||||
if (automaton_stats.emptiness_check_result[0])
|
|
||||||
estream << "reachable ";
|
|
||||||
else
|
else
|
||||||
estream << "not reachable";
|
{
|
||||||
|
changeStreamFormatting(stream, 6, 0, ios::right);
|
||||||
estream << " (from the initial state)";
|
estream << automaton_stats.emptiness_check_result.count();
|
||||||
|
restoreStreamFormatting(stream);
|
||||||
|
}
|
||||||
|
estream << ' ';
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
estream << "cycle reachable from ";
|
estream << string(indent, ' ');
|
||||||
|
|
||||||
changeStreamFormatting(stream, 9, 0, ios::left);
|
if (!automaton_stats.emptiness_check_performed)
|
||||||
estream << automaton_stats.emptiness_check_result.count();
|
estream << "not computed";
|
||||||
restoreStreamFormatting(stream);
|
else if (configuration.global_options.product_mode == Configuration::LOCAL)
|
||||||
|
{
|
||||||
|
estream << string("cycle ");
|
||||||
|
|
||||||
estream << " states\n" + string(indent, ' ')
|
if (automaton_stats.emptiness_check_result[0])
|
||||||
+ "not reachable from ";
|
estream << "reachable ";
|
||||||
|
else
|
||||||
|
estream << "not reachable";
|
||||||
|
|
||||||
changeStreamFormatting(stream, 9, 0, ios::left);
|
estream << " (from the initial state)";
|
||||||
estream << (round_info.real_emptiness_check_size
|
}
|
||||||
- automaton_stats.emptiness_check_result.count());
|
else
|
||||||
restoreStreamFormatting(stream);
|
{
|
||||||
|
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();
|
estream.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
void printConsistencyCheckStats
|
void printConsistencyCheckStats
|
||||||
(ostream& stream, int indent,
|
(ostream& stream, int indent,
|
||||||
vector<AlgorithmTestResults, ALLOC(AlgorithmTestResults) >::size_type
|
vector<AlgorithmTestResults>::size_type algorithm)
|
||||||
algorithm)
|
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* Description: Displays information about the consistency check result for
|
* 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
|
* Arguments: stream -- A reference to an output stream to which the
|
||||||
* information should be written.
|
* information should be written.
|
||||||
* indent -- Number of spaces to leave on the left of the
|
* indent -- Number of spaces to leave on the left of the
|
||||||
* output.
|
* output in verbosity mode >= 3.
|
||||||
* algorithm -- Identifier of the algorithm whose consistency
|
* algorithm -- Identifier of the algorithm whose consistency
|
||||||
* check result should be displayed.
|
* check result should be displayed.
|
||||||
*
|
*
|
||||||
|
|
@ -264,100 +368,113 @@ void printConsistencyCheckStats
|
||||||
Exceptional_ostream estream(&stream, ios::failbit | ios::badbit);
|
Exceptional_ostream estream(&stream, ios::failbit | ios::badbit);
|
||||||
const AlgorithmTestResults& test_result = test_results[algorithm];
|
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)
|
case 0 :
|
||||||
estream << "not performed";
|
estream << " F";
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
estream << " P";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
estream << "result:" + string(18, ' ');
|
estream << string(indent, ' ');
|
||||||
|
|
||||||
if (test_result.consistency_check_result == 0)
|
if (test_result.consistency_check_result == -1)
|
||||||
{
|
estream << "not performed";
|
||||||
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
|
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();
|
estream.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
void printCrossComparisonStats
|
void printCrossComparisonStats
|
||||||
(ostream& stream, int indent,
|
(ostream& stream, int indent, const IntervalList& algorithms)
|
||||||
vector<AlgorithmTestResults, ALLOC(AlgorithmTestResults) >::size_type
|
|
||||||
algorithm)
|
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* Description: Displays information about the model checking result cross-
|
* Description: Displays information about the model checking result cross-
|
||||||
* comparison check, extracting the information from a vector of
|
* comparison check, extracting the information from a vector of
|
||||||
* TestStatistics structures stored in the UserInterface object.
|
* TestStatistics structures stored in the UserInterface object.
|
||||||
*
|
*
|
||||||
* Arguments: stream -- A reference to an output stream to which the
|
* Arguments: stream -- A reference to an output stream to which the
|
||||||
* information should be written.
|
* information should be written.
|
||||||
* indent -- Number of spaces to leave on the left of the
|
* indent -- Number of spaces to leave on the left of the
|
||||||
* output.
|
* output.
|
||||||
* algorithm -- If less than the number of algorithms, show
|
* algorithms -- A reference to a constant IntervalList
|
||||||
* only the results for the algorithm with this
|
* storing the numeric identifiers of the
|
||||||
* identifier.
|
* algorithms for which the statistics should
|
||||||
|
* be shown.
|
||||||
*
|
*
|
||||||
* Returns: Nothing.
|
* Returns: Nothing.
|
||||||
*
|
*
|
||||||
* ------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------- */
|
||||||
{
|
{
|
||||||
Exceptional_ostream estream(&stream, ios::failbit | ios::badbit);
|
Exceptional_ostream estream(&stream, ios::failbit | ios::badbit);
|
||||||
bool no_errors_to_report = true;
|
bool no_errors_to_report = true, nothing_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:";
|
|
||||||
|
|
||||||
const AutomatonStats* alg_1_pos_results;
|
const AutomatonStats* alg_1_pos_results;
|
||||||
const AutomatonStats* alg_1_neg_results;
|
const AutomatonStats* alg_1_neg_results;
|
||||||
|
|
||||||
for (vector<AlgorithmTestResults, ALLOC(AlgorithmTestResults) >::size_type
|
for (IntervalList::const_iterator alg_1 = algorithms.begin();
|
||||||
alg_1 = 0;
|
alg_1 != algorithms.end();
|
||||||
alg_1 < test_results.size();
|
++alg_1)
|
||||||
alg_1++)
|
|
||||||
{
|
{
|
||||||
alg_1_pos_results = &test_results[alg_1].automaton_stats[0];
|
alg_1_pos_results = &test_results[*alg_1].automaton_stats[0];
|
||||||
alg_1_neg_results = &test_results[alg_1].automaton_stats[1];
|
alg_1_neg_results = &test_results[*alg_1].automaton_stats[1];
|
||||||
|
|
||||||
for (vector<AlgorithmTestResults, ALLOC(AlgorithmTestResults) >::size_type
|
for (vector<AlgorithmTestResults>::size_type alg_2 = 0;
|
||||||
alg_2 = alg_1 + 1;
|
alg_2 < round_info.number_of_translators;
|
||||||
alg_2 < test_results.size();
|
|
||||||
alg_2++)
|
alg_2++)
|
||||||
{
|
{
|
||||||
if ((algorithm >= configuration.algorithms.size()
|
if (*alg_1 != alg_2
|
||||||
|| alg_1 == algorithm
|
&& (alg_2 > *alg_1 || !algorithms.covers(alg_2))
|
||||||
|| alg_2 == algorithm)
|
&& configuration.algorithms[*alg_1].enabled
|
||||||
&& configuration.algorithms[alg_1].enabled
|
|
||||||
&& configuration.algorithms[alg_2].enabled)
|
&& configuration.algorithms[alg_2].enabled)
|
||||||
{
|
{
|
||||||
bool pos_test, neg_test;
|
bool pos_test, neg_test;
|
||||||
|
|
||||||
|
if (nothing_to_report)
|
||||||
|
{
|
||||||
|
nothing_to_report = false;
|
||||||
|
estream << string(indent, ' ') + "result:";
|
||||||
|
}
|
||||||
|
|
||||||
for (int counter = 0; counter < 2; counter++)
|
for (int counter = 0; counter < 2; counter++)
|
||||||
{
|
{
|
||||||
if (counter == 0)
|
if (counter == 0)
|
||||||
|
|
@ -385,89 +502,75 @@ void printCrossComparisonStats
|
||||||
else
|
else
|
||||||
estream << "-) ";
|
estream << "-) ";
|
||||||
|
|
||||||
estream << ' ';
|
estream << " " + configuration.algorithmString(*alg_1) + ", "
|
||||||
if (alg_1 == round_info.number_of_translators)
|
+ configuration.algorithmString(alg_2);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 << string(20, ' ') + "no failures detected";
|
||||||
|
|
||||||
estream << "\n\n";
|
estream << "\n\n";
|
||||||
estream.flush();
|
estream.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
void printBuchiIntersectionCheckStats
|
void printBuchiIntersectionCheckStats
|
||||||
(ostream& stream, int indent,
|
(ostream& stream, int indent, const IntervalList& algorithms)
|
||||||
vector<AlgorithmTestResults, ALLOC(AlgorithmTestResults) >::size_type
|
|
||||||
algorithm)
|
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* Description: Displays information about the Büchi automaton intersection
|
* Description: Displays information about the Büchi automaton intersection
|
||||||
* emptiness check results, extracting the information from a
|
* emptiness check results, extracting the information from a
|
||||||
* TestStatistics structure stored in the UserInterface object.
|
* TestStatistics structure stored in the UserInterface object.
|
||||||
*
|
*
|
||||||
* Arguments: stream -- A reference to an output stream to which the
|
* Arguments: stream -- A reference to an output stream to which the
|
||||||
* information should be written.
|
* information should be written.
|
||||||
* indent -- Number of spaces to leave on the left of the
|
* indent -- Number of spaces to leave on the left of the
|
||||||
* output.
|
* output.
|
||||||
* algorithm -- If less than the number of algorithms, show
|
* algorithms -- A reference to a constant IntervalList
|
||||||
* only the results for the algorithm with this
|
* storing the numeric identifiers of the
|
||||||
* identifier.
|
* algorithms for which the statistics should
|
||||||
|
* be shown.
|
||||||
*
|
*
|
||||||
* Returns: Nothing.
|
* Returns: Nothing.
|
||||||
*
|
*
|
||||||
* ------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------- */
|
||||||
{
|
{
|
||||||
Exceptional_ostream estream(&stream, ios::failbit | ios::badbit);
|
Exceptional_ostream estream(&stream, ios::failbit | ios::badbit);
|
||||||
bool no_errors_to_report = true;
|
bool no_errors_to_report = true, nothing_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:";
|
|
||||||
|
|
||||||
const AutomatonStats* alg_1_pos_results;
|
const AutomatonStats* alg_1_pos_results;
|
||||||
const AutomatonStats* alg_1_neg_results;
|
const AutomatonStats* alg_1_neg_results;
|
||||||
|
|
||||||
for (vector<AlgorithmTestResults, ALLOC(AlgorithmTestResults) >::size_type
|
for (IntervalList::const_iterator alg_1 = algorithms.begin();
|
||||||
alg_1 = 0;
|
alg_1 != algorithms.end();
|
||||||
alg_1 < round_info.number_of_translators;
|
++alg_1)
|
||||||
alg_1++)
|
|
||||||
{
|
{
|
||||||
alg_1_pos_results = &test_results[alg_1].automaton_stats[0];
|
alg_1_pos_results = &test_results[*alg_1].automaton_stats[0];
|
||||||
alg_1_neg_results = &test_results[alg_1].automaton_stats[1];
|
alg_1_neg_results = &test_results[*alg_1].automaton_stats[1];
|
||||||
|
|
||||||
for (vector<AlgorithmTestResults, ALLOC(AlgorithmTestResults) >::size_type
|
for (vector<AlgorithmTestResults>::size_type alg_2 = 0;
|
||||||
alg_2 = alg_1;
|
|
||||||
alg_2 < round_info.number_of_translators;
|
alg_2 < round_info.number_of_translators;
|
||||||
alg_2++)
|
alg_2++)
|
||||||
{
|
{
|
||||||
if ((algorithm >= round_info.number_of_translators
|
if (configuration.algorithms[*alg_1].enabled
|
||||||
|| alg_1 == algorithm
|
&& configuration.algorithms[alg_2].enabled
|
||||||
|| alg_2 == algorithm)
|
&& (alg_2 >= *alg_1 || !algorithms.covers(alg_2))
|
||||||
&& configuration.algorithms[alg_1].enabled
|
&& !configuration.isInternalAlgorithm(*alg_1)
|
||||||
&& configuration.algorithms[alg_2].enabled)
|
&& !configuration.isInternalAlgorithm(alg_2))
|
||||||
{
|
{
|
||||||
bool pos_test, neg_test;
|
bool pos_test, neg_test;
|
||||||
|
|
||||||
|
if (nothing_to_report)
|
||||||
|
{
|
||||||
|
nothing_to_report = false;
|
||||||
|
estream << string(indent, ' ') + "result:";
|
||||||
|
}
|
||||||
|
|
||||||
for (int counter = -1; counter < 1; counter++)
|
for (int counter = -1; counter < 1; counter++)
|
||||||
{
|
{
|
||||||
pos_test = (alg_1_pos_results->buchi_intersection_check_stats[alg_2]
|
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") + ' ';
|
estream << string(counter == -1 ? "N/A " : "failed") + ' ';
|
||||||
|
|
||||||
if (alg_1 != alg_2)
|
if (*alg_1 != alg_2)
|
||||||
{
|
{
|
||||||
estream << '(';
|
estream << '(';
|
||||||
if (pos_test)
|
if (pos_test)
|
||||||
|
|
@ -493,9 +596,9 @@ void printBuchiIntersectionCheckStats
|
||||||
else
|
else
|
||||||
estream << " ";
|
estream << " ";
|
||||||
|
|
||||||
estream << ' ' + configuration.algorithmString(alg_1);
|
estream << ' ' + configuration.algorithmString(*alg_1);
|
||||||
|
|
||||||
if (alg_1 != alg_2)
|
if (*alg_1 != alg_2)
|
||||||
{
|
{
|
||||||
estream << ", (";
|
estream << ", (";
|
||||||
if (pos_test)
|
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 << string(20, ' ') + "no failures detected";
|
||||||
|
estream << "\n";
|
||||||
estream << "\n\n";
|
|
||||||
estream.flush();
|
estream.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
void printAllStats
|
void printAllStats
|
||||||
(ostream& stream, int indent,
|
(ostream& stream, int indent,
|
||||||
vector<AlgorithmTestResults, ALLOC(AlgorithmTestResults) >::size_type
|
vector<AlgorithmTestResults>::size_type algorithm)
|
||||||
algorithm)
|
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* Description: Displays all test information (Büchi automaton and product
|
* Description: Displays all test information (Büchi automaton and product
|
||||||
|
|
@ -541,30 +644,46 @@ void printAllStats
|
||||||
{
|
{
|
||||||
Exceptional_ostream estream(&stream, ios::failbit | ios::badbit);
|
Exceptional_ostream estream(&stream, ios::failbit | ios::badbit);
|
||||||
|
|
||||||
estream << string(indent, ' ') + configuration.algorithmString(algorithm)
|
if (configuration.global_options.verbosity >= 3)
|
||||||
+ '\n';
|
estream << string(indent, ' ') + configuration.algorithmString(algorithm)
|
||||||
estream.flush();
|
+ '\n';
|
||||||
|
|
||||||
for (int counter = 0; counter < 2; counter++)
|
for (int counter = 0; counter < 2; counter++)
|
||||||
{
|
{
|
||||||
estream << string(indent + 2, ' ')
|
if (configuration.global_options.verbosity <= 2)
|
||||||
+ (counter == 0 ? "Positive" : "Negated") + " formula:\n"
|
{
|
||||||
+ string(indent + 4, ' ') + "Büchi automaton:\n";
|
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);
|
printBuchiAutomatonStats(stream, indent + 6, algorithm, counter);
|
||||||
|
|
||||||
if (configuration.global_options.do_comp_test
|
if (configuration.global_options.do_comp_test
|
||||||
|| configuration.global_options.do_cons_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);
|
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);
|
printAcceptanceCycleStats(stream, indent + 6, algorithm, counter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (configuration.global_options.do_cons_test)
|
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);
|
printConsistencyCheckStats(stream, indent + 4, algorithm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -575,8 +694,8 @@ void printAllStats
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
void printCollectiveCrossComparisonStats
|
void printCollectiveCrossComparisonStats
|
||||||
(ostream& stream,
|
(ostream& stream,
|
||||||
vector<TestStatistics, ALLOC(TestStatistics) >::size_type algorithm_y,
|
vector<TestStatistics>::size_type algorithm_y,
|
||||||
vector<TestStatistics, ALLOC(TestStatistics) >::size_type algorithm_x,
|
vector<TestStatistics>::size_type algorithm_x,
|
||||||
int data_type)
|
int data_type)
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
|
|
@ -630,10 +749,8 @@ void printCollectiveCrossComparisonStats
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default :
|
default :
|
||||||
if (configuration.global_options.statespace_generation_mode
|
if (configuration.isInternalAlgorithm(algorithm_x)
|
||||||
& Configuration::PATH
|
|| configuration.isInternalAlgorithm(algorithm_y))
|
||||||
&& (algorithm_x == round_info.number_of_translators
|
|
||||||
|| algorithm_y == round_info.number_of_translators))
|
|
||||||
{
|
{
|
||||||
estream << string(21, ' ');
|
estream << string(21, ' ');
|
||||||
return;
|
return;
|
||||||
|
|
@ -768,13 +885,12 @@ void printCollectiveStats(ostream& stream, int indent)
|
||||||
if (round_info.num_processed_formulae > 0
|
if (round_info.num_processed_formulae > 0
|
||||||
&& configuration.global_options.formula_input_filename.empty())
|
&& configuration.global_options.formula_input_filename.empty())
|
||||||
{
|
{
|
||||||
const map<unsigned long int, unsigned long int, less<unsigned long int>,
|
const map<unsigned long int, unsigned long int>&
|
||||||
ALLOC(unsigned long int) >&
|
|
||||||
proposition_statistics
|
proposition_statistics
|
||||||
= configuration.formula_options.formula_generator.
|
= configuration.formula_options.formula_generator.
|
||||||
propositionStatistics();
|
propositionStatistics();
|
||||||
|
|
||||||
const map<int, unsigned long int, less<int>, ALLOC(unsigned long int) >
|
const map<int, unsigned long int>
|
||||||
symbol_statistics
|
symbol_statistics
|
||||||
= configuration.formula_options.formula_generator.symbolStatistics();
|
= configuration.formula_options.formula_generator.symbolStatistics();
|
||||||
|
|
||||||
|
|
@ -820,9 +936,8 @@ void printCollectiveStats(ostream& stream, int indent)
|
||||||
number_of_symbols_printed++;
|
number_of_symbols_printed++;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (map<unsigned long int, unsigned long int,
|
for (map<unsigned long int, unsigned long int>::const_iterator
|
||||||
less<unsigned long int>, ALLOC(unsigned long int) >
|
proposition = proposition_statistics.begin();
|
||||||
::const_iterator proposition = proposition_statistics.begin();
|
|
||||||
proposition != proposition_statistics.end();
|
proposition != proposition_statistics.end();
|
||||||
++proposition)
|
++proposition)
|
||||||
{
|
{
|
||||||
|
|
@ -869,8 +984,8 @@ void printCollectiveStats(ostream& stream, int indent)
|
||||||
= "";
|
= "";
|
||||||
number_of_symbols_printed = 0;
|
number_of_symbols_printed = 0;
|
||||||
|
|
||||||
for (map<int, unsigned long int, less<int>, ALLOC(unsigned long int) >
|
for (map<int, unsigned long int>::const_iterator
|
||||||
::const_iterator op = symbol_statistics.begin();
|
op = symbol_statistics.begin();
|
||||||
op != symbol_statistics.end();
|
op != symbol_statistics.end();
|
||||||
++op)
|
++op)
|
||||||
{
|
{
|
||||||
|
|
@ -912,6 +1027,8 @@ void printCollectiveStats(ostream& stream, int indent)
|
||||||
|
|
||||||
if (number_of_symbols_printed % 5 != 0)
|
if (number_of_symbols_printed % 5 != 0)
|
||||||
{
|
{
|
||||||
|
if (number_of_symbols_printed > 5)
|
||||||
|
estream << '\n';
|
||||||
estream << ind + " operator " + symbol_name_string + '\n'
|
estream << ind + " operator " + symbol_name_string + '\n'
|
||||||
+ ind + " # " + symbol_number_string + '\n'
|
+ ind + " # " + symbol_number_string + '\n'
|
||||||
+ ind + " #/formula " + symbol_distribution_string
|
+ ind + " #/formula " + symbol_distribution_string
|
||||||
|
|
@ -953,8 +1070,11 @@ void printCollectiveStats(ostream& stream, int indent)
|
||||||
algorithm < round_info.number_of_translators;
|
algorithm < round_info.number_of_translators;
|
||||||
++algorithm)
|
++algorithm)
|
||||||
{
|
{
|
||||||
|
if (configuration.isInternalAlgorithm(algorithm))
|
||||||
|
continue;
|
||||||
|
|
||||||
estream << '\n' + string((i > 0 ? 4 : 2) + indent, ' ')
|
estream << '\n' + string((i > 0 ? 4 : 2) + indent, ' ')
|
||||||
+ *(configuration.algorithms[algorithm].name) + '\n';
|
+ configuration.algorithms[algorithm].name + '\n';
|
||||||
|
|
||||||
switch (i)
|
switch (i)
|
||||||
{
|
{
|
||||||
|
|
@ -967,14 +1087,14 @@ void printCollectiveStats(ostream& stream, int indent)
|
||||||
unsigned long int failures_to_compute_automaton;
|
unsigned long int failures_to_compute_automaton;
|
||||||
unsigned long int automaton_count;
|
unsigned long int automaton_count;
|
||||||
unsigned long int number_of_successful_instances;
|
unsigned long int number_of_successful_instances;
|
||||||
unsigned long int total_number_of_states;
|
BIGUINT total_number_of_states;
|
||||||
unsigned long int total_number_of_transitions;
|
BIGUINT total_number_of_transitions;
|
||||||
|
|
||||||
const TestStatistics& stats = final_statistics[algorithm];
|
const TestStatistics& stats = final_statistics[algorithm];
|
||||||
|
|
||||||
estream << string(2 + indent, ' ')
|
estream << string(2 + indent, ' ')
|
||||||
+ string(configuration.algorithms[algorithm].name
|
+ string(configuration.algorithms[algorithm].name.
|
||||||
->length(), '=');
|
length(), '=');
|
||||||
|
|
||||||
for (int k = 0; k < 2; k++)
|
for (int k = 0; k < 2; k++)
|
||||||
{
|
{
|
||||||
|
|
@ -1119,7 +1239,7 @@ void printCollectiveStats(ostream& stream, int indent)
|
||||||
|
|
||||||
if (k == 0)
|
if (k == 0)
|
||||||
{
|
{
|
||||||
unsigned long int total_number_of_acceptance_sets;
|
BIGUINT total_number_of_acceptance_sets;
|
||||||
double buchi_generation_time;
|
double buchi_generation_time;
|
||||||
|
|
||||||
estream << '\n' + string(22 + indent, ' ')
|
estream << '\n' + string(22 + indent, ' ')
|
||||||
|
|
@ -1339,8 +1459,7 @@ void printCollectiveStats(ostream& stream, int indent)
|
||||||
estream << ind + " Result inconsistency statistics\n"
|
estream << ind + " Result inconsistency statistics\n"
|
||||||
+ ind + " " + string(31, '=') + '\n';
|
+ ind + " " + string(31, '=') + '\n';
|
||||||
|
|
||||||
vector<TestStatistics, ALLOC(TestStatistics) >::size_type
|
vector<TestStatistics>::size_type algorithm_x, algorithm_y;
|
||||||
algorithm_x, algorithm_y;
|
|
||||||
|
|
||||||
for (algorithm_x = 0; algorithm_x < number_of_algorithms;
|
for (algorithm_x = 0; algorithm_x < number_of_algorithms;
|
||||||
algorithm_x += 2)
|
algorithm_x += 2)
|
||||||
|
|
@ -1352,7 +1471,7 @@ void printCollectiveStats(ostream& stream, int indent)
|
||||||
if (algorithm_x + i < number_of_algorithms)
|
if (algorithm_x + i < number_of_algorithms)
|
||||||
{
|
{
|
||||||
algorithm_name =
|
algorithm_name =
|
||||||
(*(configuration.algorithms[algorithm_x + i].name)).substr(0, 20);
|
configuration.algorithms[algorithm_x + i].name.substr(0, 20);
|
||||||
estream << "| " + algorithm_name
|
estream << "| " + algorithm_name
|
||||||
+ string(21 - algorithm_name.length(), ' ');
|
+ string(21 - algorithm_name.length(), ' ');
|
||||||
}
|
}
|
||||||
|
|
@ -1362,6 +1481,9 @@ void printCollectiveStats(ostream& stream, int indent)
|
||||||
for (algorithm_y = 0; algorithm_y < number_of_algorithms;
|
for (algorithm_y = 0; algorithm_y < number_of_algorithms;
|
||||||
algorithm_y++)
|
algorithm_y++)
|
||||||
{
|
{
|
||||||
|
if (configuration.isInternalAlgorithm(algorithm_y))
|
||||||
|
continue;
|
||||||
|
|
||||||
estream << "\n " + ind + string(26, '-');
|
estream << "\n " + ind + string(26, '-');
|
||||||
|
|
||||||
for (int i = 0; i < 2; ++i)
|
for (int i = 0; i < 2; ++i)
|
||||||
|
|
@ -1372,7 +1494,7 @@ void printCollectiveStats(ostream& stream, int indent)
|
||||||
estream << '+';
|
estream << '+';
|
||||||
|
|
||||||
algorithm_name
|
algorithm_name
|
||||||
= (*(configuration.algorithms[algorithm_y].name)).substr(0, 20);
|
= configuration.algorithms[algorithm_y].name.substr(0, 20);
|
||||||
|
|
||||||
bool algorithm_name_printed = false;
|
bool algorithm_name_printed = false;
|
||||||
legend = 1;
|
legend = 1;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
|
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
|
@ -42,65 +42,60 @@ extern Configuration configuration;
|
||||||
namespace StatDisplay
|
namespace StatDisplay
|
||||||
{
|
{
|
||||||
|
|
||||||
|
void printStatTableHeader /* Displays a table */
|
||||||
|
(ostream& stream, int indent); /* header for test
|
||||||
|
* statistics.
|
||||||
|
*/
|
||||||
|
|
||||||
void printBuchiAutomatonStats /* Displays information */
|
void printBuchiAutomatonStats /* Displays information */
|
||||||
(ostream& stream, /* about a Büchi */
|
(ostream& stream, /* about a Büchi */
|
||||||
int indent, /* automaton. */
|
int indent, /* automaton. */
|
||||||
vector<AlgorithmTestResults,
|
vector<AlgorithmTestResults>::size_type
|
||||||
ALLOC(AlgorithmTestResults) >::size_type
|
|
||||||
algorithm,
|
algorithm,
|
||||||
int result_id);
|
int result_id);
|
||||||
|
|
||||||
void printProductAutomatonStats /* Displays information */
|
void printProductAutomatonStats /* Displays information */
|
||||||
(ostream& stream, /* about a product */
|
(ostream& stream, /* about a product */
|
||||||
int indent, /* automaton. */
|
int indent, /* automaton. */
|
||||||
vector<AlgorithmTestResults,
|
vector<AlgorithmTestResults>::size_type
|
||||||
ALLOC(AlgorithmTestResults) >::size_type
|
|
||||||
algorithm,
|
algorithm,
|
||||||
int result_id);
|
int result_id);
|
||||||
|
|
||||||
void printAcceptanceCycleStats /* Displays information */
|
void printAcceptanceCycleStats /* Displays information */
|
||||||
(ostream& stream, /* about the acceptance */
|
(ostream& stream, /* about the acceptance */
|
||||||
int indent, /* cycles of a product */
|
int indent, /* cycles of a product */
|
||||||
vector<AlgorithmTestResults, /* automaton. */
|
vector<AlgorithmTestResults>::size_type /* automaton. */
|
||||||
ALLOC(AlgorithmTestResults) >::size_type
|
|
||||||
algorithm,
|
algorithm,
|
||||||
int result_id);
|
int result_id);
|
||||||
|
|
||||||
void printConsistencyCheckStats /* Displays the result */
|
void printConsistencyCheckStats /* Displays the result */
|
||||||
(ostream& stream, /* of the consistency */
|
(ostream& stream, /* of the consistency */
|
||||||
int indent, /* check for a given */
|
int indent, /* check for a given */
|
||||||
vector<AlgorithmTestResults, /* algorithm. */
|
vector<AlgorithmTestResults>::size_type /* algorithm. */
|
||||||
ALLOC(AlgorithmTestResults) >::size_type
|
|
||||||
algorithm);
|
algorithm);
|
||||||
|
|
||||||
void printCrossComparisonStats /* Displays information */
|
void printCrossComparisonStats /* Displays information */
|
||||||
(ostream& stream, /* about the model */
|
(ostream& stream, int indent, /* about the model */
|
||||||
int indent, /* checking result */
|
const IntervalList& algorithms); /* checking result */
|
||||||
vector<AlgorithmTestResults, /* cross-comparison */
|
/* cross-comparison */
|
||||||
ALLOC(AlgorithmTestResults) >::size_type /* check. */
|
/* check. */
|
||||||
algorithm);
|
|
||||||
|
|
||||||
void printBuchiIntersectionCheckStats /* Displays the results */
|
void printBuchiIntersectionCheckStats /* Displays the results */
|
||||||
(ostream& stream, int indent, /* of the Büchi automata */
|
(ostream& stream, int indent, /* of the Büchi automata */
|
||||||
vector<AlgorithmTestResults, /* intersection */
|
const IntervalList& algorithms); /* intersection */
|
||||||
ALLOC(AlgorithmTestResults) >::size_type /* emptiness checks. */
|
/* emptiness checks. */
|
||||||
algorithm);
|
|
||||||
|
|
||||||
void printAllStats /* A shorthand for */
|
void printAllStats /* A shorthand for */
|
||||||
(ostream& stream, /* showing all the */
|
(ostream& stream, /* showing all the */
|
||||||
int indent, /* information displayed */
|
int indent, /* information displayed */
|
||||||
vector<TestStatistics, /* by the previous five */
|
vector<TestStatistics>::size_type algorithm); /* by the previous five
|
||||||
ALLOC(TestStatistics)>::size_type /* functions. */
|
* functions.
|
||||||
algorithm);
|
*/
|
||||||
|
|
||||||
void printCollectiveCrossComparisonStats /* Displays a single */
|
void printCollectiveCrossComparisonStats /* Displays a single */
|
||||||
(ostream& stream, /* `cell' of the final */
|
(ostream& stream, /* `cell' of the final */
|
||||||
vector<TestStatistics, /* result cross- */
|
vector<TestStatistics>::size_type algorithm_y, /* result cross- */
|
||||||
ALLOC(TestStatistics) >::size_type /* comparison table. */
|
vector<TestStatistics>::size_type algorithm_x, /* comparison table. */
|
||||||
algorithm_y,
|
|
||||||
vector<TestStatistics,
|
|
||||||
ALLOC(TestStatistics) >::size_type
|
|
||||||
algorithm_x,
|
|
||||||
int data_type);
|
int data_type);
|
||||||
|
|
||||||
void printCollectiveStats /* Displays average test */
|
void printCollectiveStats /* Displays average test */
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 1999, 2000, 2001, 2002
|
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* 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.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
#pragma implementation
|
|
||||||
#endif /* __GNUC__ */
|
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include "DispUtil.h"
|
#include "DispUtil.h"
|
||||||
|
|
@ -148,8 +144,7 @@ void StateSpace::clear()
|
||||||
initial_state = 0;
|
initial_state = 0;
|
||||||
|
|
||||||
#ifdef HAVE_OBSTACK_H
|
#ifdef HAVE_OBSTACK_H
|
||||||
for (vector<Node*, ALLOC(Node*) >::iterator state = nodes.begin();
|
for (vector<Node*>::iterator state = nodes.begin(); state != nodes.end();
|
||||||
state != nodes.end();
|
|
||||||
++state)
|
++state)
|
||||||
static_cast<State*>(*state)->~State();
|
static_cast<State*>(*state)->~State();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
|
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
|
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
|
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* 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;
|
StateSpace::size_type first_unreachable_state = 1, random_node;
|
||||||
|
|
||||||
multimap<long int, StateSpace::size_type, less<long int>,
|
multimap<long int, StateSpace::size_type> reachable_but_unprocessed;
|
||||||
ALLOC(StateSpace::size_type) >
|
|
||||||
reachable_but_unprocessed;
|
|
||||||
|
|
||||||
reachable_but_unprocessed.insert(make_pair(0, 0));
|
reachable_but_unprocessed.insert(make_pair(0, 0));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 1999, 2000, 2001, 2002
|
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
|
@ -20,10 +20,6 @@
|
||||||
#ifndef STATESPACERANDOMIZER_H
|
#ifndef STATESPACERANDOMIZER_H
|
||||||
#define STATESPACERANDOMIZER_H
|
#define STATESPACERANDOMIZER_H
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
#pragma interface
|
|
||||||
#endif /* __GNUC__ */
|
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include "Random.h"
|
#include "Random.h"
|
||||||
#include "StateSpace.h"
|
#include "StateSpace.h"
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 1999, 2000, 2001, 2002
|
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* 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.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
#pragma implementation
|
|
||||||
#endif /* __GNUC__ */
|
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
#include <cctype>
|
||||||
|
#include <climits>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include "StringUtil.h"
|
#include "StringUtil.h"
|
||||||
|
|
||||||
|
|
@ -63,8 +61,7 @@ string toString(const double d, const int precision, const ios::fmtflags flags)
|
||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
void sliceString
|
void sliceString
|
||||||
(const string& s, const char* slice_chars,
|
(const string& s, const char* slice_chars, vector<string>& slices)
|
||||||
vector<string, ALLOC(string) >& slices)
|
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* Description: Slices a string into a vector of strings, using a given set
|
* 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);
|
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)
|
unsigned long int parseNumber(const string& number_string)
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
|
|
@ -119,9 +321,11 @@ unsigned long int parseNumber(const string& number_string)
|
||||||
* ------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------- */
|
||||||
{
|
{
|
||||||
char* endptr;
|
char* endptr;
|
||||||
|
|
||||||
unsigned long int number = strtoul(number_string.c_str(), &endptr, 10);
|
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 `"
|
throw NotANumberException("expected a nonnegative integer, got `"
|
||||||
+ number_string + "'");
|
+ number_string + "'");
|
||||||
|
|
||||||
|
|
@ -129,98 +333,253 @@ unsigned long int parseNumber(const string& number_string)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
void parseInterval
|
int parseInterval
|
||||||
(const string& token,
|
(const string& token, unsigned long int& min, unsigned long int& max)
|
||||||
set<unsigned long int, less<unsigned long int>, ALLOC(unsigned long int) >&
|
|
||||||
number_set,
|
|
||||||
unsigned long int min, unsigned long int max)
|
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* Description: Parses a string for a list of number intervals, storing all
|
* Description: Reads the lower and upper bound from an "interval string"
|
||||||
* the numbers into a set.
|
* into two unsigned long integer variables.
|
||||||
*
|
*
|
||||||
* Arguments: token -- A reference to a constant string containing
|
* Arguments: token -- A reference to a constant "interval string" of
|
||||||
* the list of intervals. A legal list of
|
* the format
|
||||||
* intervals has the following syntax:
|
* <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>
|
* Returns: A value telling the type of the specified interval, which is
|
||||||
* ::= <number>
|
* a bitwise or of the values LEFT_BOUNDED and RIGHT_BOUNDED
|
||||||
* | '*' // all numbers in the
|
* depending on which bounds were given explicitly for the
|
||||||
* // interval
|
* interval. (The lower and upper bounds of the interval itself
|
||||||
* // [min, max]
|
* are stored in the variables `min' and `max', respectively.)
|
||||||
* | '-'<number> // all numbers in the
|
* The function will throw a NotANumberException if the
|
||||||
* // interval
|
* interval string is of an invalid format.
|
||||||
* // [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.
|
|
||||||
*
|
*
|
||||||
* ------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------- */
|
||||||
{
|
{
|
||||||
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);
|
if (token != "*")
|
||||||
string::size_type dash_pos;
|
|
||||||
|
|
||||||
number_set.clear();
|
|
||||||
|
|
||||||
for (vector<string, ALLOC(string) >::const_iterator
|
|
||||||
interval = intervals.begin();
|
|
||||||
interval != intervals.end();
|
|
||||||
++interval)
|
|
||||||
{
|
{
|
||||||
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++)
|
tmp_min = parseNumber(value);
|
||||||
number_set.insert(i);
|
if (pos == string::npos)
|
||||||
break;
|
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)
|
if (!value.empty())
|
||||||
number_set.insert(parseNumber(*interval));
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
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));
|
extra_tokens->push_back(*i);
|
||||||
for (unsigned long int i = min; i <= number; i++)
|
continue;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
throw;
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
|
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
|
@ -31,6 +31,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "LbttAlloc.h"
|
#include "LbttAlloc.h"
|
||||||
#include "Exception.h"
|
#include "Exception.h"
|
||||||
|
#include "IntervalList.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
|
@ -57,22 +58,71 @@ template<typename T> string toString(const T& t); /* Template function for
|
||||||
|
|
||||||
void sliceString /* Breaks a string into */
|
void sliceString /* Breaks a string into */
|
||||||
(const string& s, const char* slice_chars, /* `slices', using a */
|
(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
|
* characters as
|
||||||
* separators.
|
* 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 */
|
unsigned long int parseNumber /* Converts a string to */
|
||||||
(const string& number_string); /* an unsigned long
|
(const string& number_string); /* an unsigned long
|
||||||
* integer.
|
* integer.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void parseInterval /* Converts a string of */
|
enum IntervalStringType {UNBOUNDED = 0, /* Type for an interval */
|
||||||
(const string& token, /* number intervals to */
|
LEFT_BOUNDED = 1, /* string (see the */
|
||||||
set<unsigned long int, less<unsigned long int>, /* the corresponding set */
|
RIGHT_BOUNDED = 2}; /* documentation of
|
||||||
ALLOC(unsigned long int) >& number_set, /* of unsigned long */
|
* the parseInterval
|
||||||
unsigned long int min, /* integers. */
|
* function in
|
||||||
unsigned long int max);
|
* 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.
|
* Inline function definitions for class NotANumberException.
|
||||||
|
|
@ -189,6 +271,82 @@ inline NotANumberException& NotANumberException::operator=
|
||||||
return *this;
|
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 */
|
#endif /* !STRINGUTIL_H */
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2004
|
* Copyright (C) 2004, 2005
|
||||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2004
|
* Copyright (C) 2004, 2005
|
||||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
|
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
|
@ -29,6 +29,7 @@
|
||||||
#include "Configuration.h"
|
#include "Configuration.h"
|
||||||
#include "Exception.h"
|
#include "Exception.h"
|
||||||
#include "StateSpace.h"
|
#include "StateSpace.h"
|
||||||
|
#include "TestStatistics.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
|
@ -53,7 +54,11 @@ void openFile /* Opens a file for */
|
||||||
(const char* filename, ofstream& stream, /* writing. */
|
(const char* filename, ofstream& stream, /* writing. */
|
||||||
ios::openmode mode, int indent = 0);
|
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);
|
(const char* filename, int indent = 0);
|
||||||
|
|
||||||
void printFileContents /* Displays the contents */
|
void printFileContents /* Displays the contents */
|
||||||
|
|
@ -90,32 +95,25 @@ void writeFormulaeToFiles(); /* Writes LTL formulas */
|
||||||
|
|
||||||
void generateBuchiAutomaton /* Generates a Büchi */
|
void generateBuchiAutomaton /* Generates a Büchi */
|
||||||
(int f, /* automaton from a LTL */
|
(int f, /* automaton from a LTL */
|
||||||
vector<Configuration::AlgorithmInformation, /* formula stored in a */
|
vector<Configuration::AlgorithmInformation> /* formula stored in a */
|
||||||
ALLOC(Configuration::AlgorithmInformation) > /* given file, using a */
|
::size_type /* given file, using a */
|
||||||
::size_type /* given LTL-to-Büchi */
|
algorithm_id); /* given LTL-to-Büchi
|
||||||
algorithm_id); /* translation algorithm
|
* translation algorithm
|
||||||
* for the conversion.
|
* 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 */
|
void performEmptinessCheck /* Performs an emptiness */
|
||||||
(int f, /* check on a product */
|
(int f, /* check on a product */
|
||||||
vector<Configuration::AlgorithmInformation, /* automaton. */
|
vector<Configuration::AlgorithmInformation> /* automaton. */
|
||||||
ALLOC(Configuration::AlgorithmInformation) >
|
|
||||||
::size_type
|
::size_type
|
||||||
algorithm_id);
|
algorithm_id);
|
||||||
|
|
||||||
void performConsistencyCheck /* Performs a */
|
void performConsistencyCheck /* Performs a */
|
||||||
(vector<Configuration::AlgorithmInformation, /* consistency check on */
|
(vector<Configuration::AlgorithmInformation> /* consistency check on */
|
||||||
ALLOC(Configuration::AlgorithmInformation) > /* the test results */
|
::size_type /* the test results */
|
||||||
::size_type /* for a formula and its */
|
algorithm_id); /* for a formula and its
|
||||||
algorithm_id); /* negation. */
|
* negation.
|
||||||
|
*/
|
||||||
|
|
||||||
void compareResults(); /* Compares the model
|
void compareResults(); /* Compares the model
|
||||||
* checking results
|
* checking results
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
|
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
|
@ -28,9 +28,9 @@
|
||||||
#include "LbttAlloc.h"
|
#include "LbttAlloc.h"
|
||||||
#include "Exception.h"
|
#include "Exception.h"
|
||||||
#include "LtlFormula.h"
|
#include "LtlFormula.h"
|
||||||
#include "ProductAutomaton.h"
|
|
||||||
#include "PathIterator.h"
|
#include "PathIterator.h"
|
||||||
#include "StateSpace.h"
|
#include "StateSpace.h"
|
||||||
|
#include "TempFsysName.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
|
@ -55,7 +55,11 @@ public:
|
||||||
* stream for messages.
|
* 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.
|
* formulae.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -90,6 +94,10 @@ public:
|
||||||
* current round.
|
* current round.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
bool all_tests_successful; /* True if no errors have
|
||||||
|
* occurred during testing.
|
||||||
|
*/
|
||||||
|
|
||||||
bool skip; /* True if the current
|
bool skip; /* True if the current
|
||||||
* round is to be skipped.
|
* round is to be skipped.
|
||||||
*/
|
*/
|
||||||
|
|
@ -122,11 +130,6 @@ public:
|
||||||
* paths as state spaces.
|
* 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
|
unsigned long int real_emptiness_check_size; /* Number of states in the
|
||||||
* state space where the
|
* state space where the
|
||||||
* emptiness check should
|
* emptiness check should
|
||||||
|
|
@ -150,9 +153,9 @@ public:
|
||||||
* current round.
|
* current round.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
vector<class ::Ltl::LtlFormula*, /* Formulae used in the */
|
vector<class ::Ltl::LtlFormula*> formulae; /* Formulae used in the
|
||||||
ALLOC(class ::Ltl::LtlFormula*) > /* current round: */
|
* current round:
|
||||||
formulae; /* formulae[0]:
|
* formulae[0]:
|
||||||
* positive formula in
|
* positive formula in
|
||||||
* negation normal
|
* negation normal
|
||||||
* form
|
* form
|
||||||
|
|
@ -168,7 +171,7 @@ public:
|
||||||
* generated
|
* 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
|
* vector will be set to
|
||||||
* true when the
|
* true when the
|
||||||
* corresponding
|
* corresponding
|
||||||
|
|
@ -181,10 +184,10 @@ public:
|
||||||
* formula.
|
* formula.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
char formula_file_name[2][L_tmpnam + 1]; /* Storage space for the */
|
TempFsysName* formula_file_name[2]; /* Names for temporary */
|
||||||
char automaton_file_name[L_tmpnam + 1]; /* names of several */
|
TempFsysName* automaton_file_name; /* files. */
|
||||||
char cout_capture_file[L_tmpnam + 1]; /* temporary files. */
|
TempFsysName* cout_capture_file;
|
||||||
char cerr_capture_file[L_tmpnam + 1];
|
TempFsysName* cerr_capture_file;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TestRoundInfo(const TestRoundInfo& info); /* Prevent copying and */
|
TestRoundInfo(const TestRoundInfo& info); /* Prevent copying and */
|
||||||
|
|
@ -206,14 +209,15 @@ private:
|
||||||
inline TestRoundInfo::TestRoundInfo() :
|
inline TestRoundInfo::TestRoundInfo() :
|
||||||
cout(&std::cout, ios::failbit | ios::badbit), number_of_translators(0),
|
cout(&std::cout, ios::failbit | ios::badbit), number_of_translators(0),
|
||||||
current_round(1), next_round_to_run(1), next_round_to_stop(1),
|
current_round(1), next_round_to_run(1), next_round_to_stop(1),
|
||||||
error_report_round(0), error(false), skip(false), abort(false),
|
error_report_round(0), error(false), all_tests_successful(true),
|
||||||
num_generated_statespaces(0), total_statespace_states(0),
|
skip(false), abort(false), num_generated_statespaces(0),
|
||||||
total_statespace_transitions(0), num_processed_formulae(0),
|
total_statespace_states(0), total_statespace_transitions(0),
|
||||||
fresh_statespace(false), statespace(0), path_iterator(0),
|
num_processed_formulae(0), fresh_statespace(false), statespace(0),
|
||||||
product_automaton(0), real_emptiness_check_size(0),
|
path_iterator(0), real_emptiness_check_size(0),
|
||||||
next_round_to_change_statespace(1), next_round_to_change_formula(1),
|
next_round_to_change_statespace(1), next_round_to_change_formula(1),
|
||||||
fresh_formula(false), formulae(4, static_cast<class ::Ltl::LtlFormula*>(0)),
|
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
|
* Description: Constructor for class TestRoundInfo. Creates a new
|
||||||
|
|
@ -225,6 +229,7 @@ inline TestRoundInfo::TestRoundInfo() :
|
||||||
*
|
*
|
||||||
* ------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------- */
|
||||||
{
|
{
|
||||||
|
formula_file_name[0] = formula_file_name[1] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 1999, 2000, 2001, 2002
|
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* 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.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
#pragma implementation
|
|
||||||
#endif /* __GNUC__ */
|
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include "TestStatistics.h"
|
#include "TestStatistics.h"
|
||||||
|
|
||||||
|
|
@ -54,8 +50,7 @@ void AlgorithmTestResults::emptinessReset()
|
||||||
automaton_stats[i].emptiness_check_result.clear();
|
automaton_stats[i].emptiness_check_result.clear();
|
||||||
automaton_stats[i].emptiness_check_performed = false;
|
automaton_stats[i].emptiness_check_performed = false;
|
||||||
|
|
||||||
for (vector<AutomatonStats::CrossComparisonStats,
|
for (vector<AutomatonStats::CrossComparisonStats>::iterator it
|
||||||
ALLOC(AutomatonStats::CrossComparisonStats) >::iterator it
|
|
||||||
= automaton_stats[i].cross_comparison_stats.begin();
|
= automaton_stats[i].cross_comparison_stats.begin();
|
||||||
it != automaton_stats[i].cross_comparison_stats.end();
|
it != automaton_stats[i].cross_comparison_stats.end();
|
||||||
++it)
|
++it)
|
||||||
|
|
@ -91,7 +86,7 @@ void AlgorithmTestResults::fullReset()
|
||||||
automaton_stats[i].number_of_msccs = 0;
|
automaton_stats[i].number_of_msccs = 0;
|
||||||
automaton_stats[i].buchi_generation_time = 0.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();
|
= automaton_stats[i].buchi_intersection_check_stats.begin();
|
||||||
it != automaton_stats[i].buchi_intersection_check_stats.end();
|
it != automaton_stats[i].buchi_intersection_check_stats.end();
|
||||||
++it)
|
++it)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
|
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
|
@ -23,16 +23,16 @@
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include "EdgeContainer.h"
|
||||||
|
#include "Graph.h"
|
||||||
#include "LbttAlloc.h"
|
#include "LbttAlloc.h"
|
||||||
#include "BuchiAutomaton.h"
|
#include "BuchiAutomaton.h"
|
||||||
#include "Configuration.h"
|
#include "Configuration.h"
|
||||||
#include "ProductAutomaton.h"
|
|
||||||
#include "StateSpace.h"
|
#include "StateSpace.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using Graph::BuchiAutomaton;
|
using Graph::BuchiAutomaton;
|
||||||
using Graph::StateSpace;
|
using Graph::StateSpace;
|
||||||
using Graph::ProductAutomaton;
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
*
|
*
|
||||||
|
|
@ -43,9 +43,8 @@ using Graph::ProductAutomaton;
|
||||||
struct AutomatonStats
|
struct AutomatonStats
|
||||||
{
|
{
|
||||||
explicit AutomatonStats /* Constructor. */
|
explicit AutomatonStats /* Constructor. */
|
||||||
(vector<Configuration::AlgorithmInformation,
|
(vector<Configuration::AlgorithmInformation>
|
||||||
ALLOC(Configuration::AlgorithmInformation) >
|
::size_type number_of_algorithms,
|
||||||
::size_type number_of_algorithms,
|
|
||||||
StateSpace::size_type max_statespace_size);
|
StateSpace::size_type max_statespace_size);
|
||||||
|
|
||||||
/* default copy constructor */
|
/* default copy constructor */
|
||||||
|
|
@ -107,7 +106,7 @@ struct AutomatonStats
|
||||||
* Büchi automaton.
|
* 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. */
|
number_of_product_states; /* product automaton. */
|
||||||
|
|
||||||
unsigned long int number_of_product_transitions; /* Number of transitions in
|
unsigned long int number_of_product_transitions; /* Number of transitions in
|
||||||
|
|
@ -127,9 +126,9 @@ struct AutomatonStats
|
||||||
typedef pair<bool, unsigned long int>
|
typedef pair<bool, unsigned long int>
|
||||||
CrossComparisonStats;
|
CrossComparisonStats;
|
||||||
|
|
||||||
vector<CrossComparisonStats, /* Emptiness check */
|
vector<CrossComparisonStats> /* Emptiness check */
|
||||||
ALLOC(CrossComparisonStats) > /* cross-comparison */
|
cross_comparison_stats; /* cross-comparison
|
||||||
cross_comparison_stats; /* results. The `first'
|
* results. The `first'
|
||||||
* element of the pair
|
* element of the pair
|
||||||
* tells whether a cross-
|
* tells whether a cross-
|
||||||
* comparison with a given
|
* comparison with a given
|
||||||
|
|
@ -142,8 +141,8 @@ struct AutomatonStats
|
||||||
* differ.
|
* differ.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
vector<int, ALLOC(int) > /* Büchi automaton */
|
vector<int> buchi_intersection_check_stats; /* Büchi automaton
|
||||||
buchi_intersection_check_stats; /* intersection
|
* intersection
|
||||||
* emptiness check
|
* emptiness check
|
||||||
* results. The elements
|
* results. The elements
|
||||||
* of the vector tell
|
* of the vector tell
|
||||||
|
|
@ -173,8 +172,7 @@ struct AutomatonStats
|
||||||
struct AlgorithmTestResults
|
struct AlgorithmTestResults
|
||||||
{
|
{
|
||||||
explicit AlgorithmTestResults /* Constructor. */
|
explicit AlgorithmTestResults /* Constructor. */
|
||||||
(vector<Configuration::AlgorithmInformation,
|
(vector<Configuration::AlgorithmInformation>
|
||||||
ALLOC(Configuration::AlgorithmInformation) >
|
|
||||||
::size_type
|
::size_type
|
||||||
number_of_algorithms,
|
number_of_algorithms,
|
||||||
StateSpace::size_type max_statespace_size);
|
StateSpace::size_type max_statespace_size);
|
||||||
|
|
@ -214,8 +212,8 @@ struct AlgorithmTestResults
|
||||||
* check.
|
* check.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
vector<AutomatonStats, ALLOC(AutomatonStats) > /* A two-element vector */
|
vector<AutomatonStats> automaton_stats; /* A two-element vector
|
||||||
automaton_stats; /* storing test results
|
* storing test results
|
||||||
* for an algorithm.
|
* for an algorithm.
|
||||||
*/
|
*/
|
||||||
};
|
};
|
||||||
|
|
@ -232,8 +230,7 @@ struct AlgorithmTestResults
|
||||||
struct TestStatistics
|
struct TestStatistics
|
||||||
{
|
{
|
||||||
explicit TestStatistics /* Constructor. */
|
explicit TestStatistics /* Constructor. */
|
||||||
(vector<TestStatistics,
|
(vector<TestStatistics>::size_type
|
||||||
ALLOC(TestStatistics) >::size_type
|
|
||||||
number_of_algorithms);
|
number_of_algorithms);
|
||||||
|
|
||||||
/* default copy constructor */
|
/* default copy constructor */
|
||||||
|
|
@ -270,29 +267,21 @@ struct TestStatistics
|
||||||
* checks performed.
|
* checks performed.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
unsigned long int /* Total number of */
|
BIGUINT total_number_of_buchi_states[2]; /* Total number of states
|
||||||
total_number_of_buchi_states[2]; /* states in all the
|
* in all the generated
|
||||||
* generated Büchi
|
* Büchi automata.
|
||||||
* automata.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
unsigned long int /* Total number of */
|
BIGUINT total_number_of_buchi_transitions[2]; /* Total number of
|
||||||
total_number_of_buchi_transitions[2]; /* transitions in all
|
* transitions in all
|
||||||
* the generated Büchi
|
* the generated Büchi
|
||||||
* automata.
|
* automata.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
unsigned long int /* Total number of sets */
|
BIGUINT total_number_of_acceptance_sets[2]; /* Total number of sets of
|
||||||
total_number_of_acceptance_sets[2]; /* of accepting states
|
* accepting states in all
|
||||||
* in all the generated
|
* the generated Büchi
|
||||||
* Büchi automata.
|
* automata.
|
||||||
*/
|
|
||||||
|
|
||||||
unsigned long int /* Total number of */
|
|
||||||
total_number_of_msccs[2]; /* maximal strongly
|
|
||||||
* connected components
|
|
||||||
* in the generated
|
|
||||||
* Büchi automata.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
double total_buchi_generation_time[2]; /* Total time used when
|
double total_buchi_generation_time[2]; /* Total time used when
|
||||||
|
|
@ -300,36 +289,37 @@ struct TestStatistics
|
||||||
* automata.
|
* automata.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
unsigned long int /* Total number of */
|
BIGUINT total_number_of_product_states[2]; /* Total number of states
|
||||||
total_number_of_product_states[2]; /* states in all the
|
* in all the generated
|
||||||
|
* product automata.
|
||||||
|
*/
|
||||||
|
|
||||||
|
BIGUINT total_number_of_product_transitions[2]; /* Total number of
|
||||||
|
* transitions in all the
|
||||||
* generated product
|
* generated product
|
||||||
* automata.
|
* automata.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
unsigned long int /* Total number of */
|
vector<unsigned long int> /* Number of failed */
|
||||||
total_number_of_product_transitions[2]; /* transitions in all the
|
cross_comparison_mismatches; /* result cross-
|
||||||
* generated product
|
* comparisons.
|
||||||
* automata.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
vector<unsigned long int, /* Number of failed */
|
vector<unsigned long int> /* Number of failed */
|
||||||
ALLOC(unsigned long int) > /* result cross- */
|
initial_cross_comparison_mismatches; /* result cross-
|
||||||
cross_comparison_mismatches; /* comparisons. */
|
* comparisons in the
|
||||||
|
|
||||||
vector<unsigned long int, /* Number of failed */
|
|
||||||
ALLOC(unsigned long int) > /* result cross- */
|
|
||||||
initial_cross_comparison_mismatches; /* comparisons in the
|
|
||||||
* initial state of the
|
* initial state of the
|
||||||
* state space.
|
* state space.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
vector<unsigned long int, /* Number of result */
|
vector<unsigned long int> /* Number of result */
|
||||||
ALLOC(unsigned long int) > /* cross-comparisons */
|
cross_comparisons_performed; /* cross-comparisons
|
||||||
cross_comparisons_performed; /* performed. */
|
* performed.
|
||||||
|
*/
|
||||||
|
|
||||||
vector<unsigned long int, /* Number of failed */
|
vector<unsigned long int> /* Number of failed */
|
||||||
ALLOC(unsigned long int) > /* Büchi automaton */
|
buchi_intersection_check_failures; /* Büchi automaton
|
||||||
buchi_intersection_check_failures; /* emptiness checks
|
* emptiness checks
|
||||||
* against the automata
|
* against the automata
|
||||||
* constructed from the
|
* constructed from the
|
||||||
* negated formula
|
* negated formula
|
||||||
|
|
@ -337,9 +327,9 @@ struct TestStatistics
|
||||||
* algorithms.
|
* algorithms.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
vector<unsigned long int, /* Number of Büchi */
|
vector<unsigned long int> /* Number of Büchi */
|
||||||
ALLOC(unsigned long int) > /* automaton emptiness */
|
buchi_intersection_checks_performed; /* automaton emptiness
|
||||||
buchi_intersection_checks_performed; /* checks performed
|
* checks performed
|
||||||
* against the automata
|
* against the automata
|
||||||
* constructed from the
|
* constructed from the
|
||||||
* negated formula using
|
* negated formula using
|
||||||
|
|
@ -357,9 +347,7 @@ struct TestStatistics
|
||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
inline AutomatonStats::AutomatonStats
|
inline AutomatonStats::AutomatonStats
|
||||||
(vector<Configuration::AlgorithmInformation,
|
(vector<Configuration::AlgorithmInformation>::size_type number_of_algorithms,
|
||||||
ALLOC(Configuration::AlgorithmInformation) >::size_type
|
|
||||||
number_of_algorithms,
|
|
||||||
StateSpace::size_type max_statespace_size) :
|
StateSpace::size_type max_statespace_size) :
|
||||||
buchi_automaton(0), number_of_buchi_states(0),
|
buchi_automaton(0), number_of_buchi_states(0),
|
||||||
number_of_buchi_transitions(0), number_of_acceptance_sets(0),
|
number_of_buchi_transitions(0), number_of_acceptance_sets(0),
|
||||||
|
|
@ -481,9 +469,7 @@ AutomatonStats::buchiIntersectionCheckPerformed(unsigned long int algorithm)
|
||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
inline AlgorithmTestResults::AlgorithmTestResults
|
inline AlgorithmTestResults::AlgorithmTestResults
|
||||||
(vector<Configuration::AlgorithmInformation,
|
(vector<Configuration::AlgorithmInformation>::size_type number_of_algorithms,
|
||||||
ALLOC(Configuration::AlgorithmInformation) >::size_type
|
|
||||||
number_of_algorithms,
|
|
||||||
StateSpace::size_type max_statespace_size) :
|
StateSpace::size_type max_statespace_size) :
|
||||||
consistency_check_result(-1), consistency_check_comparisons(0),
|
consistency_check_result(-1), consistency_check_comparisons(0),
|
||||||
failed_consistency_check_comparisons(0),
|
failed_consistency_check_comparisons(0),
|
||||||
|
|
@ -528,8 +514,7 @@ inline AlgorithmTestResults::~AlgorithmTestResults()
|
||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
inline TestStatistics::TestStatistics
|
inline TestStatistics::TestStatistics
|
||||||
(vector<TestStatistics, ALLOC(TestStatistics) >::size_type
|
(vector<TestStatistics>::size_type number_of_algorithms) :
|
||||||
number_of_algorithms) :
|
|
||||||
consistency_check_failures(0), consistency_checks_performed(0),
|
consistency_check_failures(0), consistency_checks_performed(0),
|
||||||
cross_comparison_mismatches(number_of_algorithms, 0),
|
cross_comparison_mismatches(number_of_algorithms, 0),
|
||||||
initial_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_states[i] = 0;
|
||||||
total_number_of_buchi_transitions[i] = 0;
|
total_number_of_buchi_transitions[i] = 0;
|
||||||
total_number_of_acceptance_sets[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_states[i] = 0;
|
||||||
total_number_of_product_transitions[i] = 0;
|
total_number_of_product_transitions[i] = 0;
|
||||||
total_buchi_generation_time[i] = 0.0;
|
total_buchi_generation_time[i] = 0.0;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 1999, 2000, 2001, 2002
|
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 1999, 2000, 2001, 2002
|
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* 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.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
#pragma implementation
|
|
||||||
#endif /* __GNUC__ */
|
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include <csignal>
|
#include <csignal>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
@ -32,7 +28,6 @@
|
||||||
#include <strstream>
|
#include <strstream>
|
||||||
#endif /* HAVE_SSTREAM */
|
#endif /* HAVE_SSTREAM */
|
||||||
#include "DispUtil.h"
|
#include "DispUtil.h"
|
||||||
#include "ProductAutomaton.h"
|
|
||||||
#include "SharedTestData.h"
|
#include "SharedTestData.h"
|
||||||
#include "StatDisplay.h"
|
#include "StatDisplay.h"
|
||||||
#include "StringUtil.h"
|
#include "StringUtil.h"
|
||||||
|
|
@ -50,6 +45,13 @@
|
||||||
#include <readline/history.h>
|
#include <readline/history.h>
|
||||||
#endif /* HAVE_READLINE */
|
#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;
|
string input_line;
|
||||||
vector<string, ALLOC(string) > input_tokens;
|
vector<string> input_tokens;
|
||||||
TokenType token;
|
TokenType token;
|
||||||
|
|
||||||
bool formula_type = true;
|
bool formula_type = true;
|
||||||
|
|
@ -115,9 +117,6 @@ void executeUserCommands()
|
||||||
{
|
{
|
||||||
#endif /* HAVE_READLINE */
|
#endif /* HAVE_READLINE */
|
||||||
|
|
||||||
ProductAutomaton* product_automaton = 0;
|
|
||||||
pair<unsigned long int, bool> last_computed_product_automaton;
|
|
||||||
|
|
||||||
signal(SIGPIPE, SIG_IGN);
|
signal(SIGPIPE, SIG_IGN);
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
|
|
@ -131,47 +130,86 @@ void executeUserCommands()
|
||||||
input_line = line;
|
input_line = line;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
round_info.cout << '\n';
|
|
||||||
round_info.cout.flush();
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
round_info.cout << prompt;
|
round_info.cout << prompt;
|
||||||
round_info.cout.flush();
|
round_info.cout.flush();
|
||||||
getline(cin, input_line, '\n');
|
getline(cin, input_line, '\n');
|
||||||
if (cin.eof())
|
if (cin.eof())
|
||||||
{
|
{
|
||||||
round_info.cout << '\n';
|
|
||||||
round_info.cout.flush();
|
|
||||||
cin.clear();
|
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 */
|
#endif /* HAVE_READLINE */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the input line contains an unescaped pipe symbol ('|') outside
|
||||||
|
* quotes, extract an external command from the line.
|
||||||
|
*/
|
||||||
|
|
||||||
external_command = "";
|
external_command = "";
|
||||||
string::size_type pipe_pos = input_line.find_first_of('|');
|
string::size_type pos
|
||||||
if (pipe_pos != string::npos)
|
= findInQuotedString(input_line, "|", OUTSIDE_QUOTES);
|
||||||
|
|
||||||
|
if (pos != string::npos)
|
||||||
{
|
{
|
||||||
string::size_type nonspace_pos
|
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)
|
if (nonspace_pos != string::npos)
|
||||||
{
|
{
|
||||||
external_command = input_line.substr(nonspace_pos);
|
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;
|
user_break = false;
|
||||||
|
|
||||||
|
if (!input_tokens.empty() || !external_command.empty())
|
||||||
|
{
|
||||||
|
round_info.cout << '\n';
|
||||||
|
round_info.cout.flush();
|
||||||
|
}
|
||||||
|
|
||||||
if (!input_tokens.empty())
|
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]);
|
token = parseCommand(input_tokens[0]);
|
||||||
|
|
||||||
if (token == CONTINUE || token == SKIP)
|
if (token == CONTINUE || token == SKIP)
|
||||||
|
|
@ -192,9 +230,7 @@ void executeUserCommands()
|
||||||
{
|
{
|
||||||
bool all_algorithms_disabled = true;
|
bool all_algorithms_disabled = true;
|
||||||
|
|
||||||
for (vector<Configuration::AlgorithmInformation,
|
for (vector<Configuration::AlgorithmInformation>::const_iterator
|
||||||
ALLOC(Configuration::AlgorithmInformation) >
|
|
||||||
::const_iterator
|
|
||||||
algorithm = configuration.algorithms.begin();
|
algorithm = configuration.algorithms.begin();
|
||||||
algorithm != configuration.algorithms.end();
|
algorithm != configuration.algorithms.end();
|
||||||
++algorithm)
|
++algorithm)
|
||||||
|
|
@ -379,8 +415,7 @@ void executeUserCommands()
|
||||||
case BUCHIANALYZE :
|
case BUCHIANALYZE :
|
||||||
verifyArgumentCount(input_tokens, 2, 2);
|
verifyArgumentCount(input_tokens, 2, 2);
|
||||||
printAutomatonAnalysisResults(*output_stream, indent,
|
printAutomatonAnalysisResults(*output_stream, indent,
|
||||||
parseNumber(input_tokens[1]),
|
input_tokens);
|
||||||
parseNumber(input_tokens[2]));
|
|
||||||
if (output_file != 0)
|
if (output_file != 0)
|
||||||
round_info.cout << " Büchi automaton intersection emptiness "
|
round_info.cout << " Büchi automaton intersection emptiness "
|
||||||
"check analysis";
|
"check analysis";
|
||||||
|
|
@ -403,8 +438,8 @@ void executeUserCommands()
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FORMULA :
|
case FORMULA :
|
||||||
verifyArgumentCount(input_tokens, 0, 0);
|
verifyArgumentCount(input_tokens, 0, 1);
|
||||||
printFormula(*output_stream, indent, formula_type);
|
printFormula(*output_stream, indent, formula_type, input_tokens);
|
||||||
if (output_file != 0)
|
if (output_file != 0)
|
||||||
round_info.cout << string(" ") + (formula_type
|
round_info.cout << string(" ") + (formula_type
|
||||||
? "Formula"
|
? "Formula"
|
||||||
|
|
@ -431,8 +466,7 @@ void executeUserCommands()
|
||||||
case RESULTANALYZE :
|
case RESULTANALYZE :
|
||||||
verifyArgumentCount(input_tokens, 2, 3);
|
verifyArgumentCount(input_tokens, 2, 3);
|
||||||
printCrossComparisonAnalysisResults
|
printCrossComparisonAnalysisResults
|
||||||
(*output_stream, indent, formula_type, input_tokens,
|
(*output_stream, indent, formula_type, input_tokens);
|
||||||
product_automaton, last_computed_product_automaton);
|
|
||||||
if (output_file != 0)
|
if (output_file != 0)
|
||||||
round_info.cout << " Model checking result cross-comparison "
|
round_info.cout << " Model checking result cross-comparison "
|
||||||
"analysis";
|
"analysis";
|
||||||
|
|
@ -474,8 +508,8 @@ void executeUserCommands()
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default :
|
default :
|
||||||
throw CommandErrorException("Unknown command (`"
|
throw CommandErrorException("Unknown command (`" + input_tokens[0]
|
||||||
+ input_tokens[0] + "').");
|
+ "').");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (output_string != 0)
|
if (output_string != 0)
|
||||||
|
|
@ -486,21 +520,17 @@ void executeUserCommands()
|
||||||
FILE* output_pipe = popen(external_command.c_str(), "w");
|
FILE* output_pipe = popen(external_command.c_str(), "w");
|
||||||
if (output_pipe == NULL)
|
if (output_pipe == NULL)
|
||||||
throw ExecFailedException(external_command);
|
throw ExecFailedException(external_command);
|
||||||
int status = fputs(outstring.c_str(), output_pipe);
|
fputs(outstring.c_str(), output_pipe);
|
||||||
if (status != EOF)
|
|
||||||
fflush(output_pipe);
|
|
||||||
pclose(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
|
if (output_file != 0)
|
||||||
? " appended"
|
round_info.cout << string(redirection_info.second
|
||||||
: " written")
|
? " appended"
|
||||||
+ " to `" + redirection_info.first + "'.\n\n";
|
: " written")
|
||||||
|
+ " to `" + redirection_info.first + "'.\n";
|
||||||
|
round_info.cout << '\n';
|
||||||
round_info.cout.flush();
|
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
|
#ifdef HAVE_READLINE
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
|
|
@ -555,7 +575,7 @@ void executeUserCommands()
|
||||||
#endif /* HAVE_READLINE */
|
#endif /* HAVE_READLINE */
|
||||||
|
|
||||||
signal(SIGPIPE, SIG_DFL);
|
signal(SIGPIPE, SIG_DFL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
TokenType parseCommand(const string& token)
|
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;
|
TokenType token_type = UNKNOWN;
|
||||||
string::size_type len = token.length();
|
string::size_type len = token.length();
|
||||||
bool ambiguous = false;
|
bool ambiguous = false;
|
||||||
|
|
@ -679,8 +686,19 @@ TokenType parseCommand(const string& token)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'i' :
|
case 'i' :
|
||||||
if (token.compare(1, len - 1, "nconsistencies", len - 1) == 0)
|
if (len < 2)
|
||||||
token_type = INCONSISTENCIES;
|
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;
|
break;
|
||||||
|
|
||||||
case 'q' :
|
case 'q' :
|
||||||
|
|
@ -760,6 +778,11 @@ TokenType parseCommand(const string& token)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 't' :
|
||||||
|
if (token.compare(1, len - 1, "ranslators", len - 1) == 0)
|
||||||
|
token_type = ALGORITHMS;
|
||||||
|
break;
|
||||||
|
|
||||||
case 'v' :
|
case 'v' :
|
||||||
if (token.compare(1, len - 1, "erbosity", len - 1) == 0)
|
if (token.compare(1, len - 1, "erbosity", len - 1) == 0)
|
||||||
token_type = VERBOSITY;
|
token_type = VERBOSITY;
|
||||||
|
|
@ -770,19 +793,12 @@ TokenType parseCommand(const string& token)
|
||||||
throw CommandErrorException("Ambiguous command.");
|
throw CommandErrorException("Ambiguous command.");
|
||||||
|
|
||||||
return token_type;
|
return token_type;
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
#if __GNUC__ < 3
|
|
||||||
#undef compare
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
void verifyArgumentCount
|
void verifyArgumentCount
|
||||||
(const vector<string, ALLOC(string) >& command,
|
(const vector<string>& command, vector<string>::size_type min_arg_count,
|
||||||
vector<string, ALLOC(string) >::size_type min_arg_count,
|
vector<string>::size_type max_arg_count)
|
||||||
vector<string, ALLOC(string) >::size_type max_arg_count)
|
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* Description: Verifies that the number of arguments given for a user
|
* Description: Verifies that the number of arguments given for a user
|
||||||
|
|
@ -805,8 +821,7 @@ void verifyArgumentCount
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
pair<string, bool> parseRedirection
|
pair<string, bool> parseRedirection(vector<string>& input_tokens)
|
||||||
(vector<string, ALLOC(string) >& input_tokens)
|
|
||||||
/* ----------------------------------------------------------------------------
|
/* ----------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* Description: Tests whether the last argument to a user command specifies
|
* Description: Tests whether the last argument to a user command specifies
|
||||||
|
|
@ -840,13 +855,13 @@ pair<string, bool> parseRedirection
|
||||||
if (token.length() > 2)
|
if (token.length() > 2)
|
||||||
{
|
{
|
||||||
append = true;
|
append = true;
|
||||||
filename = token.substr(2);
|
filename = unquoteString(token.substr(2));
|
||||||
input_tokens.pop_back();
|
input_tokens.pop_back();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
filename = token.substr(1);
|
filename = unquoteString(token.substr(1));
|
||||||
input_tokens.pop_back();
|
input_tokens.pop_back();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -855,10 +870,9 @@ pair<string, bool> parseRedirection
|
||||||
{
|
{
|
||||||
string& token = *(input_tokens.rbegin() + 1);
|
string& token = *(input_tokens.rbegin() + 1);
|
||||||
|
|
||||||
if (token[0] == '>' && (token.length() == 1
|
if (token == ">" || token == ">>")
|
||||||
|| (token.length() == 2 && token[1] == '>')))
|
|
||||||
{
|
{
|
||||||
filename = input_tokens.back();
|
filename = unquoteString(input_tokens.back());
|
||||||
append = (token.length() == 2);
|
append = (token.length() == 2);
|
||||||
input_tokens.pop_back();
|
input_tokens.pop_back();
|
||||||
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
|
* 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] != "-");
|
formula_type = (input_tokens[1] != "-");
|
||||||
|
|
||||||
if (input_tokens[1].length() == 1
|
if (input_tokens[1] == "+" || input_tokens[1] == "-")
|
||||||
&& (input_tokens[1][0] == '+' || input_tokens[1][0] == '-'))
|
|
||||||
input_tokens.erase(input_tokens.begin());
|
input_tokens.erase(input_tokens.begin());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
|
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* 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 */
|
void verifyArgumentCount /* Checks that the */
|
||||||
(const vector<string, ALLOC(string) >& /* number of arguments */
|
(const vector<string>& arguments, /* number of arguments */
|
||||||
arguments, /* for a command is */
|
vector<string>::size_type min_arg_count, /* for a command is */
|
||||||
vector<string, ALLOC(string) >::size_type /* within given limits. */
|
vector<string>::size_type max_arg_count); /* within given limits. */
|
||||||
min_arg_count,
|
|
||||||
vector<string, ALLOC(string) >::size_type
|
|
||||||
max_arg_count);
|
|
||||||
|
|
||||||
pair<string, bool> parseRedirection /* Checks whether an */
|
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
|
* will require
|
||||||
* redirecting its
|
* redirecting its
|
||||||
* output to a file.
|
* output to a file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool parseFormulaType /* Checks whether an */
|
bool parseFormulaType /* Checks whether an */
|
||||||
(vector<string, ALLOC(string) >& input_tokens); /* user command
|
(vector<string>& input_tokens); /* user command
|
||||||
* specified a positive
|
* specified a positive
|
||||||
* or a negative
|
* or a negative
|
||||||
* formula.
|
* formula.
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
|
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
|
@ -23,13 +23,17 @@
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include "LbttAlloc.h"
|
#include "LbttAlloc.h"
|
||||||
#include "BuchiAutomaton.h"
|
#include "BuchiAutomaton.h"
|
||||||
#include "Configuration.h"
|
#include "Configuration.h"
|
||||||
#include "ProductAutomaton.h"
|
#include "EdgeContainer.h"
|
||||||
|
#include "Graph.h"
|
||||||
|
#include "IntervalList.h"
|
||||||
|
#include "Product.h"
|
||||||
#include "StateSpace.h"
|
#include "StateSpace.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
@ -45,119 +49,102 @@ extern Configuration configuration;
|
||||||
namespace UserCommands
|
namespace UserCommands
|
||||||
{
|
{
|
||||||
|
|
||||||
void computeProductAutomaton /* Computes a product */
|
unsigned long int parseAlgorithmId /* Parses an */
|
||||||
(ProductAutomaton*& product_automaton, /* automaton. */
|
(const string& id); /* implementation
|
||||||
const BuchiAutomaton& buchi_automaton,
|
* identifier.
|
||||||
pair<unsigned long int, bool>& last_automaton,
|
*/
|
||||||
const pair<unsigned long int, bool>&
|
|
||||||
new_automaton);
|
void parseAlgorithmId /* Parses a list of */
|
||||||
|
(const string& ids, IntervalList& algorithms); /* implementation
|
||||||
|
* identifiers.
|
||||||
|
*/
|
||||||
|
|
||||||
void printAlgorithmList /* Displays a list of */
|
void printAlgorithmList /* Displays a list of */
|
||||||
(ostream& stream, int indent); /* algorithms used in
|
(ostream& stream, int indent); /* algorithms used in
|
||||||
* the tests.
|
* 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 */
|
void printCrossComparisonAnalysisResults /* Analyzes a */
|
||||||
(ostream& stream, int indent, /* contradiction between */
|
(ostream& stream, int indent, /* contradiction between */
|
||||||
bool formula_type, /* test results of two */
|
bool formula_type, /* test results of two */
|
||||||
const vector<string, ALLOC(string) >& /* implementations. */
|
const vector<string>& input_tokens); /* implementations. */
|
||||||
input_tokens,
|
|
||||||
ProductAutomaton*& product_automaton,
|
|
||||||
pair<unsigned long int, bool>&
|
|
||||||
last_product_automaton);
|
|
||||||
|
|
||||||
void printConsistencyAnalysisResults /* Analyzes a */
|
void printConsistencyAnalysisResults /* Analyzes a */
|
||||||
(ostream& stream, int indent, /* contradicition in the */
|
(ostream& stream, int indent, /* contradicition in the */
|
||||||
const vector<string, ALLOC(string) >& /* model checking result */
|
const vector<string>& input_tokens); /* model checking result
|
||||||
input_tokens); /* consistency check for
|
* consistency check for
|
||||||
* an implementation.
|
* an implementation.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void printAutomatonAnalysisResults /* Analyzes a */
|
void printAutomatonAnalysisResults /* Analyzes a */
|
||||||
(ostream& stream, int indent, /* contradiction in the */
|
(ostream& stream, int indent, /* contradiction in the */
|
||||||
unsigned long int algorithm1, /* Büchi automata */
|
const vector<string>& input_tokens); /* Büchi automata
|
||||||
unsigned long int algorithm2); /* intersection
|
* intersection
|
||||||
* emptiness check.
|
* emptiness check.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void printPath /* Displays information */
|
void printPath /* Displays information */
|
||||||
(ostream& stream, int indent, /* about a single */
|
(ostream& stream, int indent, /* about a single */
|
||||||
const deque<StateSpace::size_type, /* system execution. */
|
const StateSpace::Path& prefix, /* system execution. */
|
||||||
ALLOC(StateSpace::size_type) >&
|
const StateSpace::Path& cycle,
|
||||||
prefix,
|
|
||||||
const deque<StateSpace::size_type,
|
|
||||||
ALLOC(StateSpace::size_type) >&
|
|
||||||
cycle,
|
|
||||||
const StateSpace& path);
|
const StateSpace& path);
|
||||||
|
|
||||||
void printAcceptingCycle /* Displays information */
|
void printAcceptingCycle /* Displays information */
|
||||||
(ostream& stream, int indent, /* a single automaton */
|
(ostream& stream, int indent, /* a single automaton */
|
||||||
vector<Configuration::AlgorithmInformation, /* execution. */
|
vector<Configuration::AlgorithmInformation> /* execution. */
|
||||||
ALLOC(Configuration::AlgorithmInformation) >
|
|
||||||
::size_type
|
::size_type
|
||||||
algorithm_id,
|
algorithm_id,
|
||||||
const deque<StateSpace::size_type,
|
const BuchiAutomaton::Path& aut_prefix,
|
||||||
ALLOC(StateSpace::size_type) >&
|
const BuchiAutomaton::Path& aut_cycle,
|
||||||
prefix,
|
const BuchiAutomaton& automaton,
|
||||||
const deque<StateSpace::size_type,
|
const StateSpace::Path& path_prefix,
|
||||||
ALLOC(StateSpace::size_type) >&
|
const StateSpace::Path& path_cycle,
|
||||||
cycle,
|
const StateSpace& statespace);
|
||||||
const BuchiAutomaton& automaton);
|
|
||||||
|
|
||||||
void printBuchiAutomaton /* Displays information */
|
void printBuchiAutomaton /* Displays information */
|
||||||
(ostream& stream, int indent, /* about a Büchi */
|
(ostream& stream, int indent, /* about a Büchi */
|
||||||
bool formula_type, /* automaton. */
|
bool formula_type, /* automaton. */
|
||||||
vector<string, ALLOC(string) >& input_tokens,
|
vector<string>& input_tokens,
|
||||||
Graph::GraphOutputFormat fmt);
|
Graph::GraphOutputFormat fmt);
|
||||||
|
|
||||||
void evaluateFormula /* Displays information */
|
void evaluateFormula /* Displays information */
|
||||||
(ostream& stream, int indent, /* about existence of */
|
(ostream& stream, int indent, /* about existence of */
|
||||||
bool formula_type, /* accepting system */
|
bool formula_type, /* accepting system */
|
||||||
vector<string, ALLOC(string) >& input_tokens); /* executions. */
|
vector<string>& input_tokens); /* executions. */
|
||||||
|
|
||||||
void printFormula /* Displays a formula */
|
void printFormula /* Displays a formula */
|
||||||
(ostream& stream, int indent, /* used for testing. */
|
(ostream& stream, int indent, /* used for testing. */
|
||||||
bool formula_type);
|
bool formula_type,
|
||||||
|
const vector<string>& input_tokens);
|
||||||
|
|
||||||
void printCommandHelp /* Displays help about */
|
void printCommandHelp /* Displays help about */
|
||||||
(ostream& stream, int indent, /* user commands. */
|
(ostream& stream, int indent, /* user commands. */
|
||||||
const vector<string, ALLOC(string) >&
|
const vector<string>& input_tokens);
|
||||||
input_tokens);
|
|
||||||
|
|
||||||
void printInconsistencies /* Lists the system */
|
void printInconsistencies /* Lists the system */
|
||||||
(ostream& stream, int indent, /* states failing the */
|
(ostream& stream, int indent, /* states failing the */
|
||||||
vector<string, ALLOC(string) >& input_tokens); /* consistency check
|
vector<string>& input_tokens); /* consistency check
|
||||||
* for an algorihm.
|
* for an algorihm.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void printTestResults /* Displays the test */
|
void printTestResults /* Displays the test */
|
||||||
(ostream& stream, int indent, /* results of the last */
|
(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 */
|
void printStateSpace /* Displays information */
|
||||||
(ostream& stream, int indent, /* about a state space. */
|
(ostream& stream, int indent, /* about a state space. */
|
||||||
vector<string, ALLOC(string) >& input_tokens,
|
vector<string>& input_tokens,
|
||||||
Graph::GraphOutputFormat fmt);
|
Graph::GraphOutputFormat fmt);
|
||||||
|
|
||||||
void changeVerbosity /* Displays or changes */
|
void changeVerbosity /* Displays or changes */
|
||||||
(const vector<string, ALLOC(string) >& /* the verbosity of */
|
(const vector<string>& input_tokens); /* the verbosity of
|
||||||
input_tokens); /* output. */
|
* output.
|
||||||
|
*/
|
||||||
|
|
||||||
void changeAlgorithmState /* Enables or disables a */
|
void changeAlgorithmState /* Enables or disables a */
|
||||||
(vector<string, ALLOC(string) >& input_tokens, /* set of algorithms */
|
(vector<string>& input_tokens, bool enable); /* set of algorithms
|
||||||
bool enable); /* used in the tests. */
|
* used in the tests.
|
||||||
|
*/
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
434
lbtt/src/main.cc
434
lbtt/src/main.cc
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
|
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
|
@ -21,6 +21,9 @@
|
||||||
#include <csignal>
|
#include <csignal>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
|
#include <sys/types.h>
|
||||||
|
#endif /* HAVE_SYS_TYPES_H */
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#ifdef HAVE_READLINE
|
#ifdef HAVE_READLINE
|
||||||
|
|
@ -28,6 +31,11 @@
|
||||||
#include <readline/readline.h>
|
#include <readline/readline.h>
|
||||||
#include <readline/history.h>
|
#include <readline/history.h>
|
||||||
#endif /* HAVE_READLINE */
|
#endif /* HAVE_READLINE */
|
||||||
|
#ifdef HAVE_ISATTY
|
||||||
|
#ifdef HAVE_UNISTD_H
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif /* HAVE_UNISTD_H */
|
||||||
|
#endif /* HAVE_ISATTY */
|
||||||
#include "LbttAlloc.h"
|
#include "LbttAlloc.h"
|
||||||
#include "Configuration.h"
|
#include "Configuration.h"
|
||||||
#include "DispUtil.h"
|
#include "DispUtil.h"
|
||||||
|
|
@ -36,6 +44,7 @@
|
||||||
#include "Random.h"
|
#include "Random.h"
|
||||||
#include "SharedTestData.h"
|
#include "SharedTestData.h"
|
||||||
#include "StatDisplay.h"
|
#include "StatDisplay.h"
|
||||||
|
#include "TempFsysName.h"
|
||||||
#include "TestOperations.h"
|
#include "TestOperations.h"
|
||||||
#include "TestRoundInfo.h"
|
#include "TestRoundInfo.h"
|
||||||
#include "TestStatistics.h"
|
#include "TestStatistics.h"
|
||||||
|
|
@ -43,17 +52,6 @@
|
||||||
|
|
||||||
using namespace std;
|
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.
|
* round.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
vector<AlgorithmTestResults, /* Test results for each */
|
vector<AlgorithmTestResults> test_results; /* Test results for each
|
||||||
ALLOC(AlgorithmTestResults) > /* individual algorithm. */
|
* individual algorithm.
|
||||||
test_results;
|
*/
|
||||||
|
|
||||||
vector<TestStatistics, ALLOC(TestStatistics) > /* Overall test */
|
vector<TestStatistics> final_statistics; /* Overall test
|
||||||
final_statistics; /* statistics for each
|
* statistics for each
|
||||||
* algorithm.
|
* 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.
|
* Test loop.
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
int testLoop()
|
bool testLoop()
|
||||||
{
|
{
|
||||||
using namespace DispUtil;
|
using namespace DispUtil;
|
||||||
using namespace SharedTestData;
|
using namespace SharedTestData;
|
||||||
|
|
@ -119,9 +228,6 @@ int testLoop()
|
||||||
using namespace StringUtil;
|
using namespace StringUtil;
|
||||||
using namespace TestOperations;
|
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
|
const Configuration::GlobalConfiguration& global_options
|
||||||
= configuration.global_options;
|
= configuration.global_options;
|
||||||
|
|
||||||
|
|
@ -139,13 +245,6 @@ int testLoop()
|
||||||
? round_info.next_round_to_run
|
? round_info.next_round_to_run
|
||||||
: global_options.number_of_rounds + 1);
|
: 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
|
* If a name for the error log file was given in the configuration, create
|
||||||
* the file.
|
* the file.
|
||||||
|
|
@ -173,9 +272,9 @@ int testLoop()
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
round_info.transcript_file << "lbtt " PACKAGE_VERSION
|
round_info.transcript_file << "lbtt " PACKAGE_VERSION
|
||||||
" error log file, created on "
|
" error log file, created on "
|
||||||
+ string(ctime(¤t_time))
|
+ string(ctime(¤t_time))
|
||||||
+ '\n';
|
+ '\n';
|
||||||
|
|
||||||
configuration.print(round_info.transcript_file);
|
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
|
* 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
|
try
|
||||||
{
|
{
|
||||||
if (!global_options.formula_input_filename.empty())
|
if (!global_options.formula_input_filename.empty())
|
||||||
openFile(global_options.formula_input_filename.c_str(),
|
{
|
||||||
round_info.formula_input_file,
|
if (global_options.formula_input_filename == "-")
|
||||||
ios::in,
|
round_info.formula_input_stream = &cin;
|
||||||
0);
|
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)
|
catch (const FileOpenException& e)
|
||||||
{
|
{
|
||||||
|
|
@ -224,19 +331,6 @@ int testLoop()
|
||||||
formula_random_state[i] = static_cast<short int>(LRAND(0, LONG_MAX));
|
formula_random_state[i] = static_cast<short int>(LRAND(0, LONG_MAX));
|
||||||
#endif /* HAVE_RAND48 */
|
#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
|
* Intialize the vector for storing the test results for each
|
||||||
* implementation and the vector for collecting overall test statistics for
|
* implementation and the vector for collecting overall test statistics for
|
||||||
|
|
@ -265,30 +359,18 @@ int testLoop()
|
||||||
|
|
||||||
for (round_info.current_round = 1;
|
for (round_info.current_round = 1;
|
||||||
!round_info.abort
|
!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)
|
++round_info.current_round)
|
||||||
{
|
{
|
||||||
user_break = false;
|
user_break = false;
|
||||||
round_info.error = false;
|
round_info.error = false;
|
||||||
round_info.skip
|
round_info.skip
|
||||||
= (round_info.current_round < round_info.next_round_to_run);
|
= (round_info.current_round < round_info.next_round_to_run);
|
||||||
|
|
||||||
if (!round_info.skip)
|
if (!round_info.skip)
|
||||||
{
|
printText(string("Round ") + toString(round_info.current_round)
|
||||||
if (!printText(string("Round ") + toString(round_info.current_round)
|
+ " of " + toString(global_options.number_of_rounds) + "\n\n",
|
||||||
+ " of " + toString(global_options.number_of_rounds)
|
2);
|
||||||
+ "\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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
@ -299,7 +381,7 @@ int testLoop()
|
||||||
round_info.fresh_statespace
|
round_info.fresh_statespace
|
||||||
= ((global_options.do_comp_test || global_options.do_cons_test)
|
= ((global_options.do_comp_test || global_options.do_cons_test)
|
||||||
&& round_info.next_round_to_change_statespace
|
&& round_info.next_round_to_change_statespace
|
||||||
== round_info.current_round);
|
== round_info.current_round);
|
||||||
|
|
||||||
if (round_info.fresh_statespace)
|
if (round_info.fresh_statespace)
|
||||||
{
|
{
|
||||||
|
|
@ -307,13 +389,13 @@ int testLoop()
|
||||||
seed48(statespace_random_state);
|
seed48(statespace_random_state);
|
||||||
for (int i = 0; i < 3; i++)
|
for (int i = 0; i < 3; i++)
|
||||||
statespace_random_state[i] = static_cast<short int>
|
statespace_random_state[i] = static_cast<short int>
|
||||||
(LRAND(0, LONG_MAX));
|
(LRAND(0, LONG_MAX));
|
||||||
#else
|
#else
|
||||||
SRAND(global_options.statespace_random_seed);
|
SRAND(global_options.statespace_random_seed);
|
||||||
configuration.global_options.statespace_random_seed
|
configuration.global_options.statespace_random_seed
|
||||||
= LRAND(0, RAND_MAX);
|
= LRAND(0, RAND_MAX);
|
||||||
#endif /* HAVE_RAND48 */
|
#endif /* HAVE_RAND48 */
|
||||||
|
|
||||||
if (global_options.statespace_change_interval == 0)
|
if (global_options.statespace_change_interval == 0)
|
||||||
round_info.next_round_to_change_statespace
|
round_info.next_round_to_change_statespace
|
||||||
= global_options.number_of_rounds + 1;
|
= global_options.number_of_rounds + 1;
|
||||||
|
|
@ -321,8 +403,7 @@ int testLoop()
|
||||||
round_info.next_round_to_change_statespace
|
round_info.next_round_to_change_statespace
|
||||||
+= global_options.statespace_change_interval;
|
+= global_options.statespace_change_interval;
|
||||||
|
|
||||||
for (vector<AlgorithmTestResults, ALLOC(AlgorithmTestResults) >
|
for (vector<AlgorithmTestResults>::iterator it = test_results.begin();
|
||||||
::iterator it = test_results.begin();
|
|
||||||
it != test_results.end();
|
it != test_results.end();
|
||||||
++it)
|
++it)
|
||||||
it->emptinessReset();
|
it->emptinessReset();
|
||||||
|
|
@ -352,7 +433,7 @@ int testLoop()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
round_info.fresh_formula
|
round_info.fresh_formula
|
||||||
= (round_info.next_round_to_change_formula
|
= (round_info.next_round_to_change_formula
|
||||||
== round_info.current_round);
|
== round_info.current_round);
|
||||||
|
|
||||||
if (round_info.fresh_formula)
|
if (round_info.fresh_formula)
|
||||||
|
|
@ -375,8 +456,7 @@ int testLoop()
|
||||||
|
|
||||||
round_info.formula_in_file[0] = round_info.formula_in_file[1] = false;
|
round_info.formula_in_file[0] = round_info.formula_in_file[1] = false;
|
||||||
|
|
||||||
for (vector<AlgorithmTestResults, ALLOC(AlgorithmTestResults) >
|
for (vector<AlgorithmTestResults>::iterator it = test_results.begin();
|
||||||
::iterator it = test_results.begin();
|
|
||||||
it != test_results.end();
|
it != test_results.end();
|
||||||
++it)
|
++it)
|
||||||
it->fullReset();
|
it->fullReset();
|
||||||
|
|
@ -387,8 +467,8 @@ int testLoop()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
generateFormulae(round_info.formula_input_file.is_open()
|
generateFormulae(!global_options.formula_input_filename.empty()
|
||||||
? &round_info.formula_input_file
|
? round_info.formula_input_stream
|
||||||
: 0);
|
: 0);
|
||||||
}
|
}
|
||||||
catch (const FormulaGenerationException&)
|
catch (const FormulaGenerationException&)
|
||||||
|
|
@ -402,7 +482,7 @@ int testLoop()
|
||||||
|
|
||||||
if (user_break)
|
if (user_break)
|
||||||
{
|
{
|
||||||
printText("[User break]\n\n", 2, 4);
|
printText("[User break]\n\n", 1, 4);
|
||||||
throw UserBreakException();
|
throw UserBreakException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -417,12 +497,17 @@ int testLoop()
|
||||||
|
|
||||||
if (global_options.statespace_generation_mode & Configuration::PATH
|
if (global_options.statespace_generation_mode & Configuration::PATH
|
||||||
&& (global_options.do_cons_test || global_options.do_comp_test)
|
&& (global_options.do_cons_test || global_options.do_comp_test)
|
||||||
&& (!test_results[round_info.number_of_translators].
|
&& (!test_results[round_info.number_of_translators - 1].
|
||||||
automaton_stats[0].emptiness_check_performed))
|
automaton_stats[0].emptiness_check_performed)
|
||||||
|
&& configuration.algorithms[round_info.number_of_translators - 1].
|
||||||
|
enabled)
|
||||||
verifyFormulaOnPath();
|
verifyFormulaOnPath();
|
||||||
|
|
||||||
if (!round_info.error)
|
if (!round_info.error)
|
||||||
{
|
{
|
||||||
|
if (global_options.verbosity == 2)
|
||||||
|
::StatDisplay::printStatTableHeader(round_info.cout, 4);
|
||||||
|
|
||||||
unsigned long int num_enabled_implementations = 0;
|
unsigned long int num_enabled_implementations = 0;
|
||||||
|
|
||||||
for (unsigned long int algorithm_id = 0;
|
for (unsigned long int algorithm_id = 0;
|
||||||
|
|
@ -434,81 +519,61 @@ int testLoop()
|
||||||
|
|
||||||
num_enabled_implementations++;
|
num_enabled_implementations++;
|
||||||
|
|
||||||
|
if (configuration.isInternalAlgorithm(algorithm_id))
|
||||||
|
continue;
|
||||||
|
|
||||||
printText(configuration.algorithmString(algorithm_id) + '\n',
|
printText(configuration.algorithmString(algorithm_id) + '\n',
|
||||||
2, 4);
|
3, 4);
|
||||||
|
|
||||||
for (int counter = 0; counter < 2; counter++)
|
for (int counter = 0; counter < 2; counter++)
|
||||||
{
|
{
|
||||||
if (user_break)
|
if (user_break)
|
||||||
{
|
{
|
||||||
printText("[User break]\n\n", 2, 4);
|
printText("[User break]\n\n", 1, 4);
|
||||||
throw UserBreakException();
|
throw UserBreakException();
|
||||||
}
|
}
|
||||||
|
|
||||||
printText(string(counter == 1 ? "Negated" : "Positive")
|
if (global_options.verbosity == 1
|
||||||
+ " formula:\n",
|
|| global_options.verbosity == 2)
|
||||||
2,
|
{
|
||||||
6);
|
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
|
||||||
{
|
{
|
||||||
try
|
/*
|
||||||
{
|
* Generate a Büchi automaton using the current algorithm.
|
||||||
round_info.product_automaton = 0;
|
* `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.
|
* Find the system states from which an accepting
|
||||||
* `counter' determines the formula which is to be
|
* execution cycle can be reached by checking the product
|
||||||
* translated into an automaton; 0 denotes the positive and
|
* automaton for emptiness.
|
||||||
* 1 the negated formula.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
generateBuchiAutomaton(counter, algorithm_id);
|
performEmptinessCheck(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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (const BuchiAutomatonGenerationException&)
|
catch (const BuchiAutomatonGenerationException&)
|
||||||
|
|
@ -544,7 +609,13 @@ int testLoop()
|
||||||
emptiness_check_performed)
|
emptiness_check_performed)
|
||||||
performConsistencyCheck(algorithm_id);
|
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)
|
if (num_enabled_implementations > 0)
|
||||||
|
|
@ -556,10 +627,7 @@ int testLoop()
|
||||||
* results obtained using the different algorithms.
|
* results obtained using the different algorithms.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (num_enabled_implementations >= 2
|
if (num_enabled_implementations >= 2)
|
||||||
|| (num_enabled_implementations == 1
|
|
||||||
&& global_options.statespace_generation_mode
|
|
||||||
& Configuration::PATH))
|
|
||||||
compareResults();
|
compareResults();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -590,33 +658,22 @@ int testLoop()
|
||||||
round_info.next_round_to_stop = round_info.current_round;
|
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
|
* Determine from the program configuration and the error status whether
|
||||||
* the testing should be paused to wait for user commands.
|
* the testing should be paused to wait for user commands.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
if (round_info.error)
|
||||||
|
round_info.all_tests_successful = false;
|
||||||
|
|
||||||
if (round_info.error
|
if (round_info.error
|
||||||
&& global_options.interactive == Configuration::ONERROR)
|
&& global_options.interactive == Configuration::ONERROR)
|
||||||
round_info.next_round_to_stop = round_info.current_round;
|
round_info.next_round_to_stop = round_info.current_round;
|
||||||
|
|
||||||
if (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();
|
::UserCommandInterface::executeUserCommands();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 2; i++)
|
|
||||||
removeFile(round_info.formula_file_name[i], 2);
|
|
||||||
|
|
||||||
if (round_info.path_iterator != 0)
|
if (round_info.path_iterator != 0)
|
||||||
delete round_info.path_iterator;
|
delete round_info.path_iterator;
|
||||||
else if (round_info.statespace != 0)
|
else if (round_info.statespace != 0)
|
||||||
|
|
@ -628,8 +685,7 @@ int testLoop()
|
||||||
::Ltl::LtlFormula::destruct(round_info.formulae[f]);
|
::Ltl::LtlFormula::destruct(round_info.formulae[f]);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (vector<AlgorithmTestResults, ALLOC(AlgorithmTestResults) >
|
for (vector<AlgorithmTestResults>::iterator it = test_results.begin();
|
||||||
::iterator it = test_results.begin();
|
|
||||||
it != test_results.end();
|
it != test_results.end();
|
||||||
++it)
|
++it)
|
||||||
it->fullReset();
|
it->fullReset();
|
||||||
|
|
@ -661,19 +717,19 @@ int testLoop()
|
||||||
time(¤t_time);
|
time(¤t_time);
|
||||||
|
|
||||||
round_info.transcript_file << "lbtt error log closed on "
|
round_info.transcript_file << "lbtt error log closed on "
|
||||||
+ string(ctime(¤t_time))
|
+ string(ctime(¤t_time))
|
||||||
<< endl;
|
<< endl;
|
||||||
|
|
||||||
round_info.transcript_file.close();
|
round_info.transcript_file.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (global_options.verbosity >= 1)
|
if (global_options.verbosity >= 2)
|
||||||
printCollectiveStats(cout, 0);
|
printCollectiveStats(cout, 0);
|
||||||
|
|
||||||
if (round_info.formula_input_file.is_open())
|
if (round_info.formula_input_file.is_open())
|
||||||
round_info.formula_input_file.close();
|
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[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
configuration.read(argc, argv);
|
configuration.read(argc, argv);
|
||||||
}
|
}
|
||||||
|
|
@ -697,15 +753,35 @@ int main(int argc, char* argv[])
|
||||||
cerr << ":" << configuration.global_options.cfg_filename << ":"
|
cerr << ":" << configuration.global_options.cfg_filename << ":"
|
||||||
<< e.line_info;
|
<< e.line_info;
|
||||||
cerr << ": " << e.what() << endl;
|
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)
|
if (configuration.global_options.verbosity >= 3)
|
||||||
configuration.print(cout);
|
configuration.print(cout);
|
||||||
|
|
||||||
user_break = false;
|
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
|
#ifdef HAVE_OBSTACK_H
|
||||||
obstack_alloc_failed_handler = &ObstackAllocator::failure;
|
obstack_alloc_failed_handler = &ObstackAllocator::failure;
|
||||||
|
|
@ -715,18 +791,28 @@ int main(int argc, char* argv[])
|
||||||
using_history();
|
using_history();
|
||||||
#endif /* HAVE_READLINE */
|
#endif /* HAVE_READLINE */
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return testLoop();
|
allocateTempFilenames();
|
||||||
|
if (!testLoop())
|
||||||
|
{
|
||||||
|
deallocateTempFilenames();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (const Exception& e)
|
catch (const Exception& e)
|
||||||
{
|
{
|
||||||
cerr << argv[0] << ": " << e.what() << endl;
|
deallocateTempFilenames();
|
||||||
exit(-1);
|
cerr << endl << argv[0] << ": " << e.what() << endl;
|
||||||
|
exit(3);
|
||||||
}
|
}
|
||||||
catch (const bad_alloc&)
|
catch (const bad_alloc&)
|
||||||
{
|
{
|
||||||
cerr << argv[0] << ": out of memory" << endl;
|
deallocateTempFilenames();
|
||||||
exit(-1);
|
cerr << endl << argv[0] << ": out of memory" << endl;
|
||||||
|
exit(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
deallocateTempFilenames();
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -180,11 +180,11 @@ int main(int argc, char** argv)
|
||||||
|
|
||||||
case OPT_VERSION :
|
case OPT_VERSION :
|
||||||
cout << "lbtt-translate " PACKAGE_VERSION "\n"
|
cout << "lbtt-translate " PACKAGE_VERSION "\n"
|
||||||
"lbtt-translate is free software; you may change and "
|
"lbtt-translate is free software; you may change and "
|
||||||
"redistribute it under the\n"
|
"redistribute it under the\n"
|
||||||
"terms of the GNU General Public License. lbtt-translate "
|
"terms of the GNU General Public License. lbtt-translate "
|
||||||
"comes with NO WARRANTY.\n"
|
"comes with NO WARRANTY.\n"
|
||||||
"See the file COPYING for details.\n";
|
"See the file COPYING for details.\n";
|
||||||
exit(0);
|
exit(0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 1999, 2000, 2001, 2002
|
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
|
@ -20,10 +20,6 @@
|
||||||
#ifndef TRANSLATE_H
|
#ifndef TRANSLATE_H
|
||||||
#define TRANSLATE_H
|
#define TRANSLATE_H
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
#pragma interface
|
|
||||||
#endif /* __GNUC__ */
|
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue