Remove LBTT.

* configure.ac: Detect lbtt using AC_CHECK_PROG.
* m4/lbtt.m4: Delete.
* lbtt/: Remove directory.
* Makefile.am, README: Adjust.
This commit is contained in:
Alexandre Duret-Lutz 2012-10-27 20:11:55 +02:00
parent a577850eb3
commit e2f17f65b8
105 changed files with 29 additions and 52054 deletions

View file

@ -23,9 +23,6 @@
if WITH_INCLUDED_BUDDY
MAYBE_BUDDY = buddy
endif WITH_INCLUDED_BUDDY
if WITH_INCLUDED_LBTT
MAYBE_LBTT = lbtt
endif WITH_INCLUDED_LBTT
if NEVER
# For Automake a conditional directory
# is conditionally built, but unconditionally distributed.
@ -34,8 +31,7 @@ if NEVER
NEVER_BENCH = bench
endif
SUBDIRS = $(MAYBE_BUDDY) $(MAYBE_LBTT) \
$(NEVER_BENCH) doc lib src wrap ltdl iface
SUBDIRS = $(MAYBE_BUDDY) $(NEVER_BENCH) doc lib src wrap ltdl iface
UTF8 = utf8/doc/ReleaseNotes utf8/doc/utf8cpp.html utf8/utf8.h \
utf8/utf8/checked.h utf8/utf8/core.h utf8/utf8/unchecked.h

46
README
View file

@ -33,10 +33,24 @@ later). Especially, Python's headers files should be installed. If
you don't have Python installed, you should run configure with
the --disable-python option (see below).
Spot also uses modified versions of BuDDy (a binary decision diagram),
and LBTT (an LTL to Büchi test bench). You do not need to install
these yourself: they are included in this package (directories buddy/
and lbtt/) and will be built and installed alongside of Spot.
The Boost libraries should also be installed.
Third-party dependencies
------------------------
Spot also uses a modified version of BuDDy (a binary decision diagram
library), that is already included in the buddy/ directory. So you
do not need to install it yourself.
Spot used to distribute a modified version of LBTT (an LTL to Büchi
test bench), mostly fixing errors reported by recent compilers.
However Spot now distributes its own reimplementation of LBTT, called
ltlcross, so the use of LBTT is completely optional. The last
modified version of LBTT we used to distribute can now be found at
http://spot.lip6.fr/dl/lbtt-1.2.1a.tar.gz
If some lbtt binary is found on your system, it will be used in the
test suite in addition to ltlcross.
Building and installing
@ -60,20 +74,13 @@ flags specific to Spot:
CVS repository hosted by the Università di Torino.
--with-included-buddy
--with-included-lbtt
After you have installed Spot the first time, LBTT and a modified
version of BuDDy will be installed. The next time you reconfigure
Spot, configure will detect that these versions are already
installed, and will attempt to use these installed versions
directly (this is in case you had to modify one of these yourself
for another purpose). These two options will *force* the use,
build, and installation of the included versions of these package,
even when compatible versions are already installed.
--without-included-lbtt
Explicitly Turn off the configuration and compilation of LBTT.
This is required on systems (such as MinGW) where LBTT does not
compile.
After you have installed Spot the first time, a modified version
of BuDDy will be installed. The next time you reconfigure Spot,
configure will detect that this version is already installed, and
will attempt to use it directly (this is in case you had to modify
one of these yourself for another purpose). This option will
*force* the use, build, and installation of the included version
of BuDDy, even when a compatible version is already installed.
--disable-python
Turn off the compilation of Python bindings. These bindings are
@ -101,7 +108,7 @@ flags specific to Spot:
--enable-optimizations
Here are the meaning of the fine-tuning options, in case
enable/disable-devel is not enough.
--enable/disable-devel is not enough.
--disable-assert
--enable-assert
@ -198,7 +205,6 @@ Third party software
--------------------
buddy/ A patched version of BuDDy 2.3 (a BDD library).
lbtt/ lbtt 1.2.1a (an LTL to Büchi automata test bench).
ltdl/ Libtool's portable dlopen() wrapper library.
lib/ Gnulib's portability modules.

View file

@ -65,7 +65,6 @@ AC_HEADER_TR1_UNORDERED_MAP
AC_HEADER_EXT_HASH_MAP
AX_CHECK_BUDDY
AX_CHECK_LBTT
AX_CHECK_GSPNLIB
AX_CHECK_BOOST([1.34], [103400])
@ -96,6 +95,8 @@ AC_CHECK_PROG([MODELLA], [modella], [modella])
AC_CHECK_PROG([LTL2NBA], [script4lbtt.py], [script4lbtt.py])
AC_CHECK_PROG([PERL], [perl], [perl])
AC_CHECK_PROG([SPIN], [spin], [spin])
AC_CHECK_PROG([LBTT], [lbtt], [lbtt])
AC_CHECK_PROG([LBTT_TRANSLATE], [lbtt-translate], [lbtt-translate])
AX_CHECK_VALGRIND
AC_CHECK_PROG([WRING2LBTT], [wring2lbtt], [wring2lbtt])
# Debian has a binary for SWIG 2.0 named swig2.0 and they kept swig as

View file

@ -1,22 +0,0 @@
Makefile
Makefile.in
configure
config.log
config.status
aclocal.m4
autom4te.cache
libtool
*.tar.gz
*.patch
depcomp
install-sh
missing
mkinstalldirs
py-compile
config.guess
config.sub
ltmain.sh
ylwrap
config.h.in
config.h
stamp-h1

22
lbtt/.gitignore vendored
View file

@ -1,22 +0,0 @@
Makefile
Makefile.in
configure
config.log
config.status
aclocal.m4
autom4te.cache
libtool
*.tar.gz
*.patch
depcomp
install-sh
missing
mkinstalldirs
py-compile
config.guess
config.sub
ltmain.sh
ylwrap
config.h.in
config.h
stamp-h1

View file

@ -1 +0,0 @@
Heikki Tauriainen <heikki.tauriainen@tkk.fi>

View file

@ -1,340 +0,0 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
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
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

File diff suppressed because it is too large Load diff

View file

@ -1,2 +0,0 @@
SUBDIRS = doc src
ACLOCAL_AMFLAGS = -I m4

392
lbtt/NEWS
View file

@ -1,392 +0,0 @@
lbtt NEWS -- history of user-visible changes.
Copyright (C) 2008 Heikki Tauriainen
Permission is granted to anyone to make or distribute verbatim copies
of this document as received, in any medium, provided that the
copyright notice and this permission notice are preserved.
Permission is granted to distribute modified versions
of this document, or of portions of it, under the above conditions,
provided also that they carry prominent notices stating who last
changed them.
+-----------------------------------------------------------------------+
| This version of LBTT, distributed with Spot, contains several changes |
| that are not in the original version 1.2.1 released in 2008. |
| Unfortunately Heikki Tiaurainen left the TCS lab of TKK and nobody is |
| maintaining LBTT at TKK currently. Please report any issue with this |
| modified version, named 1.2.1a, to <spot@lrde.epita.fr>. The list of |
| changes follows (see ChangeLog for details). |
+-----------------------------------------------------------------------+
Version 1.2.1a
* Fix compilation with newer versions of Bison.
* Fix compilation on Intel's icpc, and recent version of G++ and Clang++.
* Fix compilation with newer versions of Automake.
* Fix construction of manual ("make dvi" and "make pdf") for recent
version of texinfo.
* Fix generation of random formulae on 64bit machines. (They were
all identical.)
* Do not complain about missing path to algorithm that are disabled in
the config file.
* Don't rewrite W and M operators for Spot.
* Count the number of nondeterministic states, and the number of
deterministic automata (thanks to Tomáš Babiak)
Version 1.2.1 (9 Apr 2008)
* Fix compilation and warnings on GCC 4.3 (thanks to Alexandre Duret-Lutz
for the patch).
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
* This release does not add new functionality to the program apart from
some bug fixes and changes to sources to make them more compatible
with versions 3.1.x and 3.2 of gcc.
Version 1.0.0
* lbtt is now packaged using GNU Autotools.
* The distribution includes sources for documentation that can be
built in `info', `dvi' and `html' formats using GNU texinfo. The
documentation is also available at the program's home page at
<http://www.tcs.hut.fi/%7Ehtauriai/lbtt/>.
* lbtt now has direct support for the following binary LTL formula
operators:
---------------------------------------------------------------
operator symbol used in input symbol used in
files for LTL-to-Büchi messages
translators
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
logical "exclusive or"
^ xor
temporal "weak until"
W W
temporal "strong release" (dual of "weak until")
M M
temporal "before"
B B
The ^ operator is also accepted in the transition guard formulas of the
Büchi automata that are given to lbtt as input.
Please see the included documentation for a reference on the exact
semantics of these operators.
* Changes in program behavior:
- The default priority for LTL formula operators is now 0 (instead of
10 as in previous versions).
- The default interval for changing state spaces is now one test round
(instead of 10 as in previous versions).
- The sequences of random formulas and state spaces generated by lbtt
should now be independent of each other, i.e., changing the formula
generation parameters does not affect the sequence of generated state
spaces and vice versa. Unfortunately, the changes required to
implement this functionality make the test sequences obtained using
previous versions of the tool irreproducible with version 1.0.0. In
addition, the random seed must now be set separately for the formula
and state space generation algorithms.
* Changes in program configuration:
- lbtt supports the following new configuration file and command line
options (`O' -- command line option, `C' -- equivalent configuration
file option (SectionName.OptionName), `D' -- description):
O: --[no]comparisontest
C: GlobalOptions.ComparisonTest = Yes | No
D: Enable or disable the model checking result cross-comparison
test
O: --[no]consistencytest
C: GlobalOptions.ConsistencyTest = Yes | No
D: Enable or disable the model checking result consistency test
O: --[no]intersectiontest
C: GlobalOptions.IntersectionTest = Yes | No
D: Enable or disable the Büchi automata intersection emptiness
test
O: --profile
D: Disable all of the above automata correctness tests
O: --skip=N
D: Skip the first N test rounds
O: --nogeneratennf
C: FormulaOptions.GenerateMode = Normal
D: Do not force random formulas to be generated in negation
normal form
O: --nooutputnnf
C: FormulaOptions.OutputMode = Normal
D: Do not rewrite LTL formulas into negation normal form before
passing them to LTL-to Büchi translators
O: --quiet, --silent
D: Run all tests silently without interruption
O: --showconfig
D: Display program configuration and exit
O: --showoperatordistribution
D: Compute the expected distribution of random formula operators
and display the distribution with other configuration
information
O: --xorpriority=PRIORITY
C: FormulaOptions.XorPriority = PRIORITY
D: Set priority for the logical "exclusive or" operator
O: --weakuntilpriority=PRIORITY
C: FormulaOptions.WeakUntilPriority = PRIORITY
D: Set priority for the temporal "weak until" operator
O: --strongreleasepriority=PRIORITY
C: FormulaOptions.StrongReleasePriority = PRIORITY
D: Set priority for the temporal "strong release" operator
O: --beforepriority=PRIORITY
C: FormulaOptions.BeforePriority = PRIORITY
D: Set priority for the temporal "before" operator
- The following configuration file and command line options have been
renamed in lbtt version 1.0.0:
Command line options:
--synchronousproduct => --modelcheck
--localproduct => --localmodelcheck
--globalproduct => --globalmodelcheck
--randomseed => --formularandomseed,
--statespacerandomseed
--formulalength => --formulasize
--vpriority => --releasepriority
Configuration file options:
GlobalOptions.FormulaChangeInterval
=> FormulaOptions.ChangeInterval
GlobalOptions.StateSpaceChangeInterval
=> StateSpaceOptions.ChangeInterval
GlobalOptions.SynchronousProduct
=> GlobalOptions.ModelCheck
GlobalOptions.RandomSeed => FormulaOptions.RandomSeed
StateSpaceOptions.RandomSeed
FormulaOptions.Length => FormulaOptions.Size
FormulaOptions.VPriority => FormulaOptions.ReleasePriority
Please see the included documentation for more information on these
options.
* Changes in the user command interface:
- lbtt's internal command interface now supports redirecting the
output of some internal commands to a pipe to be processed by an
external program. This can be achieved by ending the command line
with `| <command>'.
- If using random or enumerated paths as state spaces for the tests,
the user commands `resultanalysis' and `eval' now support referring
to results computed using lbtt's internal model checking algorithm.
- The tool includes a new user command `consistencyanalysis' that can
be used for analyzing failures in the model checking result
consistency check.
- The user command `resultanalysis' now accepts an optional state
space identifier which can be used to force the analysis to be
performed in a certain state of the state space.
- The user command `pathinconsistencies' has been removed. (The `eval'
command provides equivalent functionality.)
- lbtt now supports the GNU readline library that provides command
line editing enhancements when using the user commands. The support
can be optionally disabled by running the `configure' script with
the parameter `--without-readline'.
* The additional programs `aasa_lbt' and `spin_lbt' have been replaced with
a common `lbtt-translate' utility. This program does not implement an
LTL-to-Büchi translation algorithm, however; a free LTL-to-Büchi
translator that provides similar functionality to the `aasa_lbt' tool
included in previous lbtt releases can be obtained via
<http://www.tcs.hut.fi/Software/maria/tools/lbt/>.

View file

@ -1,94 +0,0 @@
+-----------------------------------------------------------------------+
| This version of LBTT, distributed with Spot, contains several changes |
| that are not in the original version 1.2.1 released in 2008. |
| Unfortunately Heikki Tiaurainen left the TCS lab of TKK and nobody is |
| maintaining LBTT at TKK currently. Please report any issue with this |
| modified version, named 1.2.1a, to <spot@lrde.epita.fr>. See NEWS |
| and ChangeLog for the list of changes. |
+-----------------------------------------------------------------------+
lbtt version 1.2.1
------------------
lbtt is a tool for testing programs that translate formulas
expressed in propositional linear temporal logic (LTL) into
Büchi automata. The goal of the tool is to assist implementing
LTL-to-Büchi translation algorithms correctly by providing an
automated testing environment for LTL-to-Büchi translators.
Additionally, the testing environment can be used for very basic
profiling of different LTL-to-Büchi translators to evaluate their
performance.
The latest version of the program is available at
<http://www.tcs.hut.fi/Software/lbtt/>.
lbtt is free software, you may change and redistribute it under
the terms of the GNU General Public License. lbtt comes with
NO WARRANTY. See the file COPYING for details.
Brief installation instructions:
--------------------------------
The basic procedure to build lbtt, the associated tools
and GNU info documentation is to enter the following
commands in the top-level package directory (the directory
that contains this file):
./configure
make
These commands should create two executable files
(`lbtt' and `lbtt-translate') in the `src' subdirectory
and GNU info documentation under the `doc' subdirectory.
The program and documentation can be used directly in
their build directories. Optionally, the program binaries
and documentation can be installed in their default
location (under `/usr/local/') by entering the command
make install
after the build process is complete. (To change the
default installation directory, the `configure' script
should be invoked with an appropriate `--prefix=PATH'
option before running `make'. Please see the file INSTALL
for generic information about running `configure'.)
Documentation:
--------------
The default build procedure builds the program documentation
in the `doc' subdirectory only in `info' format. Assuming
you have the GNU Info documentation browser installed, the
documentation can be viewed by running the command
`info -f doc/lbtt.info' after the program build is
complete.
The documentation can be optionally generated in DVI
or HTML formats using the TeX typesetting program and the
GNU texinfo tools. To create DVI documentation, run the
command
make dvi
in the top-level package directory. If you have TeX and
the GNU texinfo tools properly installed, this command
should generate a file `lbtt.dvi' in the `doc' subdirectory.
The documentation can be also generated in HTML format by
running `makeinfo --html' on the file `lbtt.texi' in the
`doc' subdirectory.
Note: The generated DVI or HTML files refer to two
auxiliary picture files (`testprocedure.EXT' and
`intersectioncheck.EXT', where EXT stands for `eps' for
DVI documentation, `png' for HTML documentation)
residing in the `doc' subdirectory. To see the figures
included in the documentation correctly, make sure that
the program used for viewing the documentation can find
these files when needed.
The documentation is also available in various formats
at the program's home page at
<http://www.tcs.hut.fi/Software/lbtt/>.

View file

@ -1,221 +0,0 @@
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.59])
AC_INIT([lbtt], [1.2.1a], [heikki.tauriainen@tkk.fi])
AC_REVISION([Revision: 1.9])
AC_CONFIG_SRCDIR([src/main.cc])
AC_CONFIG_HEADERS([config.h])
AM_INIT_AUTOMAKE
# Checks for programs.
AC_PROG_CC
AC_PROG_CPP
AC_PROG_CXX
AC_PROG_CXXCPP
AM_PROG_LEX
AC_PROG_YACC
lbtt_INTEL
# Check whether the user has explicitly disabled support for the GNU readline
# library.
readline=yes
readline_includedir=
readline_libdir=
AC_ARG_WITH(
[readline],
[AS_HELP_STRING(
[--without-readline],
[disable support for the GNU readline library (default enable)])],
[if test x"${withval}" = xno; then readline=no; fi])
AC_ARG_WITH(
[readline-prefix],
[AS_HELP_STRING(
[--with-readline-prefix=DIR],
[location where GNU readline is installed (optional)])],
[readline_includedir="${withval}/include"
readline_libdir="${withval}/lib"])
AC_ARG_WITH(
[readline-includes],
[AS_HELP_STRING(
[--with-readline-includes=DIR],
[location where GNU readline headers are installed (optional)])],
[readline_includedir="${withval}"])
AC_ARG_WITH(
[readline-libs],
[AS_HELP_STRING(
[--with-readline-libs=DIR],
[location where GNU readline libraries are installed (optional)])],
[readline_libdir="${withval}"])
old_CPPFLAGS=${CPPFLAGS}
old_LDFLAGS=${LDFLAGS}
if test -n "${readline_includedir}"; then
CPPFLAGS="${CPPFLAGS} -I${readline_includedir}"
fi
if test -n "${readline_libdir}"; then
LDFLAGS="${LDFLAGS} -L${readline_libdir}"
fi
# Check for the availability of headers.
AC_GNU_SOURCE
AC_HEADER_STDC
AC_CHECK_HEADERS([libintl.h fcntl.h sys/times.h])
AC_HEADER_SYS_WAIT
# Check for the availability of the GNU readline headers.
if test "${readline}" = yes; then
rl_history_h="readline/history.h"
rl_readline_h="readline/readline.h"
AC_CHECK_HEADERS([${rl_history_h} ${rl_readline_h}], [], [readline=no])
fi
AC_LANG([C++])
# Check for the availability of the obstack.h header. GNU libc 2.3.2 includes a
# version of this header that cannot be compiled using g++; enable a workaround
# if necessary.
AC_CHECK_HEADERS(
[obstack.h],
[AC_MSG_CHECKING([whether obstack.h compilation workaround is needed])
old_cxxflags=${CXXFLAGS}
CXXFLAGS="${CXXFLAGS} -Werror"
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[[#include <obstack.h>]],
[[
#ifdef __GLIBC__ == 2 && __GLIBC_MINOR__ = 3
obstack_alloc(0, 0);
#endif
]])],
[AC_MSG_RESULT([no])],
[AC_MSG_RESULT([yes])
AC_DEFINE(
[GLIBC_OBSTACK_WORKAROUND],
[1],
[Define to 1 to enable an obstack.h C++ compilation workaround for GNU libc 2.3.])])
CXXFLAGS=${old_cxxflags}])
# Check for the availablility of the sstream or strstream header.
AC_CHECK_HEADERS(
[sstream],
[],
[AC_CHECK_HEADERS(
[strstream],
[],
[AC_MSG_ERROR([missing one or more standard C++ headers])])])
# Checks for typedefs, structures, and compiler characteristics.
AC_LANG(C)
AC_CHECK_TYPES(
[unsigned long long int],
[AC_DEFINE(
[BIGUINT],
[unsigned long long int],
[Define to an unsigned integer type supported by your compiler.])],
[AC_DEFINE(
[BIGUINT],
[unsigned long int],
[Define to an unsigned integer type supported by your compiler.])])
AC_C_CONST
AC_C_INLINE
# Checks for library functions.
AC_CHECK_FUNCS(
[strchr strtod strtol strtoul strerror mkdir open read write close popen pclose pipe fork execvp getpgrp setpgid tcgetpgrp tcsetpgrp getpid waitpid alarm sigaction sigprocmask sigemptyset sigaddset times sysconf],
[],
[AC_MSG_ERROR([missing one of the library functions required for compilation])])
AC_CHECK_FUNCS([strsignal isatty getopt_long])
if test x"${ac_cv_func_getopt_long}" = xno; then
AC_LIBOBJ([getopt])
AC_LIBOBJ([getopt1])
AC_CHECK_FUNCS([memset])
fi
# Determine which libraries to link with for readline support.
if test "${readline}" = yes; then
AC_MSG_CHECKING([for readline libraries])
oldlibs=${LIBS}
for READLINELIBS in "-lreadline" "-lreadline -lcurses" "-lreadline -ltermcap" error; do
if test "${READLINELIBS}" != error; then
LIBS="${oldlibs} ${READLINELIBS}"
AC_LINK_IFELSE(
[AC_LANG_PROGRAM(
[[
#include <stdio.h>
#include <${rl_history_h}>
#include <${rl_readline_h}>
]],
[[using_history(); readline(""); add_history("");]])],
[break])
fi
done
LIBS=${oldlibs}
if test "${READLINELIBS}" != error; then
AC_DEFINE(
[HAVE_READLINE],
[1],
[Define if you have the GNU readline library.])
AC_SUBST([READLINELIBS])
AC_MSG_RESULT([${READLINELIBS}])
else
AC_MSG_RESULT([no suitable libraries found, readline support disabled])
READLINELIBS=""
readline=no
fi
fi
if test "${readline}" = no; then
CPPFLAGS=${old_CPPFLAGS}
LDFLAGS=${old_LDFLAGS}
fi
# Check for the availability of the `rand48' family of random number
# generation functions.
have_rand48=yes
AC_CHECK_FUNCS(
[srand48 lrand48 seed48],
[],
[have_rand48=no
AC_CHECK_FUNCS(
[rand srand],
[],
[AC_MSG_ERROR([missing library functions for random number generation])])])
if test "${have_rand48}" = yes; then
AC_DEFINE(
[HAVE_RAND48],
[1],
[Define if you have the `rand48' family of random number generation functions.])
fi
AC_CONFIG_FILES([Makefile doc/Makefile src/Makefile src/Graph.h])
AC_OUTPUT

View file

@ -1,4 +0,0 @@
Makefile.in
Makefile
*.info*
texinfo.tex

14
lbtt/doc/.gitignore vendored
View file

@ -1,14 +0,0 @@
Makefile.in
Makefile
*.info*
texinfo.tex
*.cp
*.cps
*.fn
*.fns
*.ky
*.kys
*.pg
*.vr
*.vrs
*.tp

View file

@ -1,3 +0,0 @@
info_TEXINFOS = lbtt.texi
lbtt_TEXINFOS = gpl.texi
EXTRA_DIST = intersectioncheck.txt intersectioncheck.eps intersectioncheck.png testprocedure.txt testprocedure.eps testprocedure.png

View file

@ -1,394 +0,0 @@
@unnumbered GNU GENERAL PUBLIC LICENSE
@center Version 2, June 1991
@c This file is intended to be included in another file.
@display
Copyright @copyright{} 1989, 1991 Free Software Foundation, Inc.
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
@end display
@unnumberedsec Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software---to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
@iftex
@unnumberedsec TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
@end iftex
@ifinfo
@center TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
@end ifinfo
@enumerate 0
@item
This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The ``Program'', below,
refers to any such program or work, and a ``work based on the Program''
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term ``modification''.) Each licensee is addressed as ``you''.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
@item
You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
@item
You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
@enumerate a
@item
You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
@item
You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
@item
If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
@end enumerate
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
@item
You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
@enumerate a
@item
Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
@item
Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
@item
Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
@end enumerate
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
@item
You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
@item
You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
@item
Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
@item
If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
@item
If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
@item
The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and ``any
later version'', you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
@item
If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
@end enumerate
@iftex
@heading NO WARRANTY
@end iftex
@ifinfo
@center NO WARRANTY
@end ifinfo
@enumerate 11
@item
BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM ``AS IS'' WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
@item
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
@end enumerate
@iftex
@heading END OF TERMS AND CONDITIONS
@end iftex
@ifinfo
@center END OF TERMS AND CONDITIONS
@end ifinfo
@page
@unnumberedsec Appendix: How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the ``copyright'' line and a pointer to where the full notice is found.
@smallexample
@var{one line to give the program's name and a brief idea of what it does.}
Copyright (C) @var{yyyy} @var{name of author}
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.
@end smallexample
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
@smallexample
Gnomovision version 69, Copyright (C) 19@var{yy} @var{name of author}
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
@end smallexample
The hypothetical commands @samp{show w} and @samp{show c} should show
the appropriate parts of the General Public License. Of course, the
commands you use may be called something other than @samp{show w} and
@samp{show c}; they could even be mouse-clicks or menu items---whatever
suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a ``copyright disclaimer'' for the program, if
necessary. Here is a sample; alter the names:
@smallexample
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
@var{signature of Ty Coon}, 1 April 1989
Ty Coon, President of Vice
@end smallexample
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

View file

@ -1,747 +0,0 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Title: intersectioncheck.eps
%%Creator: fig2dev Version 3.2 Patchlevel 3a
%%CreationDate: Mon Aug 6 18:07:57 2001
%%For: htauriai@lattice (Heikki Tauriainen,TB349,451 3263,)
%%BoundingBox: 0 0 333 459
%%Magnification: 1.0000
%%EndComments
/$F2psDict 200 dict def
$F2psDict begin
$F2psDict /mtrx matrix put
/col-1 {0 setgray} bind def
/col0 {0.000 0.000 0.000 srgb} bind def
/col1 {0.000 0.000 1.000 srgb} bind def
/col2 {0.000 1.000 0.000 srgb} bind def
/col3 {0.000 1.000 1.000 srgb} bind def
/col4 {1.000 0.000 0.000 srgb} bind def
/col5 {1.000 0.000 1.000 srgb} bind def
/col6 {1.000 1.000 0.000 srgb} bind def
/col7 {1.000 1.000 1.000 srgb} bind def
/col8 {0.000 0.000 0.560 srgb} bind def
/col9 {0.000 0.000 0.690 srgb} bind def
/col10 {0.000 0.000 0.820 srgb} bind def
/col11 {0.530 0.810 1.000 srgb} bind def
/col12 {0.000 0.560 0.000 srgb} bind def
/col13 {0.000 0.690 0.000 srgb} bind def
/col14 {0.000 0.820 0.000 srgb} bind def
/col15 {0.000 0.560 0.560 srgb} bind def
/col16 {0.000 0.690 0.690 srgb} bind def
/col17 {0.000 0.820 0.820 srgb} bind def
/col18 {0.560 0.000 0.000 srgb} bind def
/col19 {0.690 0.000 0.000 srgb} bind def
/col20 {0.820 0.000 0.000 srgb} bind def
/col21 {0.560 0.000 0.560 srgb} bind def
/col22 {0.690 0.000 0.690 srgb} bind def
/col23 {0.820 0.000 0.820 srgb} bind def
/col24 {0.500 0.190 0.000 srgb} bind def
/col25 {0.630 0.250 0.000 srgb} bind def
/col26 {0.750 0.380 0.000 srgb} bind def
/col27 {1.000 0.500 0.500 srgb} bind def
/col28 {1.000 0.630 0.630 srgb} bind def
/col29 {1.000 0.750 0.750 srgb} bind def
/col30 {1.000 0.880 0.880 srgb} bind def
/col31 {1.000 0.840 0.000 srgb} bind def
end
save
newpath 0 459 moveto 0 0 lineto 333 0 lineto 333 459 lineto closepath clip newpath
-32.0 585.0 translate
1 -1 scale
/cp {closepath} bind def
/ef {eofill} bind def
/gr {grestore} bind def
/gs {gsave} bind def
/sa {save} bind def
/rs {restore} bind def
/l {lineto} bind def
/m {moveto} bind def
/rm {rmoveto} bind def
/n {newpath} bind def
/s {stroke} bind def
/sh {show} bind def
/slc {setlinecap} bind def
/slj {setlinejoin} bind def
/slw {setlinewidth} bind def
/srgb {setrgbcolor} bind def
/rot {rotate} bind def
/sc {scale} bind def
/sd {setdash} bind def
/ff {findfont} bind def
/sf {setfont} bind def
/scf {scalefont} bind def
/sw {stringwidth} bind def
/tr {translate} bind def
/tnt {dup dup currentrgbcolor
4 -2 roll dup 1 exch sub 3 -1 roll mul add
4 -2 roll dup 1 exch sub 3 -1 roll mul add
4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
bind def
/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
4 -2 roll mul srgb} bind def
/reencdict 12 dict def /ReEncode { reencdict begin
/newcodesandnames exch def /newfontname exch def /basefontname exch def
/basefontdict basefontname findfont def /newfont basefontdict maxlength dict def
basefontdict { exch dup /FID ne { dup /Encoding eq
{ exch dup length array copy newfont 3 1 roll put }
{ exch newfont 3 1 roll put } ifelse } { pop pop } ifelse } forall
newfont /FontName newfontname put newcodesandnames aload pop
128 1 255 { newfont /Encoding get exch /.notdef put } for
newcodesandnames length 2 idiv { newfont /Encoding get 3 1 roll put } repeat
newfontname newfont definefont pop end } def
/isovec [
8#055 /minus 8#200 /grave 8#201 /acute 8#202 /circumflex 8#203 /tilde
8#204 /macron 8#205 /breve 8#206 /dotaccent 8#207 /dieresis
8#210 /ring 8#211 /cedilla 8#212 /hungarumlaut 8#213 /ogonek 8#214 /caron
8#220 /dotlessi 8#230 /oe 8#231 /OE
8#240 /space 8#241 /exclamdown 8#242 /cent 8#243 /sterling
8#244 /currency 8#245 /yen 8#246 /brokenbar 8#247 /section 8#250 /dieresis
8#251 /copyright 8#252 /ordfeminine 8#253 /guillemotleft 8#254 /logicalnot
8#255 /hyphen 8#256 /registered 8#257 /macron 8#260 /degree 8#261 /plusminus
8#262 /twosuperior 8#263 /threesuperior 8#264 /acute 8#265 /mu 8#266 /paragraph
8#267 /periodcentered 8#270 /cedilla 8#271 /onesuperior 8#272 /ordmasculine
8#273 /guillemotright 8#274 /onequarter 8#275 /onehalf
8#276 /threequarters 8#277 /questiondown 8#300 /Agrave 8#301 /Aacute
8#302 /Acircumflex 8#303 /Atilde 8#304 /Adieresis 8#305 /Aring
8#306 /AE 8#307 /Ccedilla 8#310 /Egrave 8#311 /Eacute
8#312 /Ecircumflex 8#313 /Edieresis 8#314 /Igrave 8#315 /Iacute
8#316 /Icircumflex 8#317 /Idieresis 8#320 /Eth 8#321 /Ntilde 8#322 /Ograve
8#323 /Oacute 8#324 /Ocircumflex 8#325 /Otilde 8#326 /Odieresis 8#327 /multiply
8#330 /Oslash 8#331 /Ugrave 8#332 /Uacute 8#333 /Ucircumflex
8#334 /Udieresis 8#335 /Yacute 8#336 /Thorn 8#337 /germandbls 8#340 /agrave
8#341 /aacute 8#342 /acircumflex 8#343 /atilde 8#344 /adieresis 8#345 /aring
8#346 /ae 8#347 /ccedilla 8#350 /egrave 8#351 /eacute
8#352 /ecircumflex 8#353 /edieresis 8#354 /igrave 8#355 /iacute
8#356 /icircumflex 8#357 /idieresis 8#360 /eth 8#361 /ntilde 8#362 /ograve
8#363 /oacute 8#364 /ocircumflex 8#365 /otilde 8#366 /odieresis 8#367 /divide
8#370 /oslash 8#371 /ugrave 8#372 /uacute 8#373 /ucircumflex
8#374 /udieresis 8#375 /yacute 8#376 /thorn 8#377 /ydieresis] def
/Times-Roman /Times-Roman-iso isovec ReEncode
/Times-Italic /Times-Italic-iso isovec ReEncode
/DrawEllipse {
/endangle exch def
/startangle exch def
/yrad exch def
/xrad exch def
/y exch def
/x exch def
/savematrix mtrx currentmatrix def
x y tr xrad yrad sc 0 0 1 startangle endangle arc
closepath
savematrix setmatrix
} def
/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
/$F2psEnd {$F2psEnteredState restore end} def
$F2psBegin
%%Page: 1 1
10 setmiterlimit
0.06299 0.06299 sc
/Times-Roman-iso ff 180.00 scf sf
2925 3150 m
gs 1 -1 sc (LTL-to-B\374chi) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Roman-iso ff 180.00 scf sf
2925 3375 m
gs 1 -1 sc (translator 2) dup sw pop 2 div neg 0 rm col0 sh gr
% Polyline
15.000 slw
n 2295 2970 m 3555 2970 l 3555 3465 l 2295 3465 l
cp gs col0 s gr
7.500 slw
% Ellipse
n 3847 3195 23 23 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr
% Ellipse
n 4027 3195 23 23 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr
% Ellipse
n 4207 3195 23 23 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr
/Times-Italic-iso ff 180.00 scf sf
2340 2227 m
gs 1 -1 sc (f) col0 sh gr
/Times-Roman-iso ff 180.00 scf sf
1305 2227 m
gs 1 -1 sc (LTL formula) col0 sh gr
% Polyline
n 4830 2154 m 4867 2154 l
4867 2184 l gs col0 s gr
/Times-Italic-iso ff 180.00 scf sf
4905 2227 m
gs 1 -1 sc (f) col0 sh gr
/Times-Roman-iso ff 180.00 scf sf
3150 2227 m
gs 1 -1 sc (Negated LTL formula) col0 sh gr
/Times-Italic-iso ff 180.00 scf sf
2700 5265 m
gs 1 -1 sc (f) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Roman-iso ff 180.00 scf sf
2385 5265 m
gs 1 -1 sc (2 for) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Roman-iso ff 180.00 scf sf
2475 5040 m
gs 1 -1 sc (Automaton) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Roman-iso ff 180.00 scf sf
900 4500 m
gs 1 -1 sc (1 for) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Italic-iso ff 180.00 scf sf
1215 4500 m
gs 1 -1 sc (f) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Roman-iso ff 180.00 scf sf
990 4275 m
gs 1 -1 sc (Automaton) dup sw pop 2 div neg 0 rm col0 sh gr
% Polyline
n 2287 4423 m 2324 4423 l
2324 4453 l gs col0 s gr
/Times-Italic-iso ff 180.00 scf sf
2362 4496 m
gs 1 -1 sc (f) col0 sh gr
/Times-Roman-iso ff 180.00 scf sf
2025 4499 m
gs 1 -1 sc (1 for) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Roman-iso ff 180.00 scf sf
2160 4274 m
gs 1 -1 sc (Automaton) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Italic-iso ff 180.00 scf sf
4334 4497 m
gs 1 -1 sc (f) col0 sh gr
/Times-Roman-iso ff 180.00 scf sf
4117 4499 m
gs 1 -1 sc (for) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Italic-iso ff 180.00 scf sf
3892 4499 m
gs 1 -1 sc (n) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Roman-iso ff 180.00 scf sf
4140 4274 m
gs 1 -1 sc (Automaton) dup sw pop 2 div neg 0 rm col0 sh gr
% Polyline
n 5452 4424 m 5489 4424 l
5489 4454 l gs col0 s gr
/Times-Italic-iso ff 180.00 scf sf
5527 4497 m
gs 1 -1 sc (f) col0 sh gr
/Times-Roman-iso ff 180.00 scf sf
5265 4499 m
gs 1 -1 sc (for) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Italic-iso ff 180.00 scf sf
5040 4499 m
gs 1 -1 sc (n) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Roman-iso ff 180.00 scf sf
5310 4274 m
gs 1 -1 sc (Automaton) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Italic-iso ff 180.00 scf sf
5512 3375 m
gs 1 -1 sc (n) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Roman-iso ff 180.00 scf sf
4702 3375 m
gs 1 -1 sc (translator) col0 sh gr
/Times-Roman-iso ff 180.00 scf sf
5130 3150 m
gs 1 -1 sc (LTL-to-B\374chi) dup sw pop 2 div neg 0 rm col0 sh gr
% Polyline
15.000 slw
n 4500 2970 m 5760 2970 l 5760 3465 l 4500 3465 l
cp gs col0 s gr
% Polyline
7.500 slw
n 3950 5189 m 3987 5189 l
3987 5219 l gs col0 s gr
/Times-Italic-iso ff 180.00 scf sf
4025 5262 m
gs 1 -1 sc (f) col0 sh gr
/Times-Roman-iso ff 180.00 scf sf
3690 5264 m
gs 1 -1 sc (2 for) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Roman-iso ff 180.00 scf sf
3825 5039 m
gs 1 -1 sc (Automaton) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Roman-iso ff 180.00 scf sf
1170 3375 m
gs 1 -1 sc (translator 1) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Roman-iso ff 180.00 scf sf
1170 3150 m
gs 1 -1 sc (LTL-to-B\374chi) dup sw pop 2 div neg 0 rm col0 sh gr
% Polyline
15.000 slw
n 540 2970 m 1800 2970 l 1800 3465 l 540 3465 l
cp gs col0 s gr
/Times-Roman-iso ff 180.00 scf sf
1575 5940 m
gs 1 -1 sc (Intersection) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Roman-iso ff 180.00 scf sf
1575 6165 m
gs 1 -1 sc (emptiness) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Roman-iso ff 180.00 scf sf
1575 6390 m
gs 1 -1 sc (check) dup sw pop 2 div neg 0 rm col0 sh gr
% Polyline
n 1080 5760 m 2070 5760 l 2070 6480 l 1080 6480 l
cp gs col0 s gr
% Polyline
n 1035 5715 m 2115 5715 l 2115 6525 l 1035 6525 l
cp gs col0 s gr
/Times-Roman-iso ff 180.00 scf sf
4725 5940 m
gs 1 -1 sc (Intersection) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Roman-iso ff 180.00 scf sf
4725 6165 m
gs 1 -1 sc (emptiness) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Roman-iso ff 180.00 scf sf
4725 6390 m
gs 1 -1 sc (check) dup sw pop 2 div neg 0 rm col0 sh gr
% Polyline
n 4230 5760 m 5220 5760 l 5220 6480 l 4230 6480 l
cp gs col0 s gr
% Polyline
n 4185 5715 m 5265 5715 l 5265 6525 l 4185 6525 l
cp gs col0 s gr
/Times-Roman-iso ff 180.00 scf sf
1575 7200 m
gs 1 -1 sc (Intersection) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Roman-iso ff 180.00 scf sf
1575 7425 m
gs 1 -1 sc (emptiness) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Roman-iso ff 180.00 scf sf
1575 7650 m
gs 1 -1 sc (check) dup sw pop 2 div neg 0 rm col0 sh gr
% Polyline
n 1080 7020 m 2070 7020 l 2070 7740 l 1080 7740 l
cp gs col0 s gr
% Polyline
n 1035 6975 m 2115 6975 l 2115 7785 l 1035 7785 l
cp gs col0 s gr
/Times-Roman-iso ff 180.00 scf sf
4725 7200 m
gs 1 -1 sc (Intersection) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Roman-iso ff 180.00 scf sf
4725 7425 m
gs 1 -1 sc (emptiness) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Roman-iso ff 180.00 scf sf
4725 7650 m
gs 1 -1 sc (check) dup sw pop 2 div neg 0 rm col0 sh gr
% Polyline
n 4230 7020 m 5220 7020 l 5220 7740 l 4230 7740 l
cp gs col0 s gr
% Polyline
n 4185 6975 m 5265 6975 l 5265 7785 l 4185 7785 l
cp gs col0 s gr
/Times-Roman-iso ff 180.00 scf sf
1575 8370 m
gs 1 -1 sc (Intersection) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Roman-iso ff 180.00 scf sf
1575 8595 m
gs 1 -1 sc (emptiness) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Roman-iso ff 180.00 scf sf
1575 8820 m
gs 1 -1 sc (check) dup sw pop 2 div neg 0 rm col0 sh gr
% Polyline
n 1080 8190 m 2070 8190 l 2070 8910 l 1080 8910 l
cp gs col0 s gr
% Polyline
n 1035 8145 m 2115 8145 l 2115 8955 l 1035 8955 l
cp gs col0 s gr
/Times-Roman-iso ff 180.00 scf sf
4725 8370 m
gs 1 -1 sc (Intersection) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Roman-iso ff 180.00 scf sf
4725 8595 m
gs 1 -1 sc (emptiness) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Roman-iso ff 180.00 scf sf
4725 8820 m
gs 1 -1 sc (check) dup sw pop 2 div neg 0 rm col0 sh gr
% Polyline
n 4230 8190 m 5220 8190 l 5220 8910 l 4230 8910 l
cp gs col0 s gr
% Polyline
n 4185 8145 m 5265 8145 l 5265 8955 l 4185 8955 l
cp gs col0 s gr
/Times-Roman-iso ff 180.00 scf sf
3150 7200 m
gs 1 -1 sc (Intersection) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Roman-iso ff 180.00 scf sf
3150 7425 m
gs 1 -1 sc (emptiness) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Roman-iso ff 180.00 scf sf
3150 7650 m
gs 1 -1 sc (check) dup sw pop 2 div neg 0 rm col0 sh gr
% Polyline
n 2655 7020 m 3645 7020 l 3645 7740 l 2655 7740 l
cp gs col0 s gr
% Polyline
n 2610 6975 m 3690 6975 l 3690 7785 l 2610 7785 l
cp gs col0 s gr
/Times-Roman-iso ff 180.00 scf sf
3150 5940 m
gs 1 -1 sc (Intersection) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Roman-iso ff 180.00 scf sf
3150 6165 m
gs 1 -1 sc (emptiness) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Roman-iso ff 180.00 scf sf
3150 6390 m
gs 1 -1 sc (check) dup sw pop 2 div neg 0 rm col0 sh gr
% Polyline
n 2655 5760 m 3645 5760 l 3645 6480 l 2655 6480 l
cp gs col0 s gr
% Polyline
n 2610 5715 m 3690 5715 l 3690 6525 l 2610 6525 l
cp gs col0 s gr
/Times-Roman-iso ff 180.00 scf sf
3150 8460 m
gs 1 -1 sc (Intersection) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Roman-iso ff 180.00 scf sf
3150 8685 m
gs 1 -1 sc (emptiness) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Roman-iso ff 180.00 scf sf
3150 8910 m
gs 1 -1 sc (check) dup sw pop 2 div neg 0 rm col0 sh gr
% Polyline
n 2655 8280 m 3645 8280 l 3645 9000 l 2655 9000 l
cp gs col0 s gr
% Polyline
n 2610 8235 m 3690 8235 l 3690 9045 l 2610 9045 l
cp gs col0 s gr
% Polyline
7.500 slw
gs clippath
1001 2966 m 1052 2998 l 1134 2871 l 1044 2956 l 1083 2838 l cp
eoclip
n 1440 2340 m
1035 2970 l gs col0 s gr gr
% arrowhead
n 1083 2838 m 1044 2956 l 1134 2871 l 1083 2838 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
4505 3003 m 4523 2945 l 4379 2900 l 4485 2965 l 4361 2957 l cp
eoclip
n 2475 2340 m
4500 2970 l gs col0 s gr gr
% arrowhead
n 4361 2957 m 4485 2965 l 4379 2900 l 4361 2957 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
2689 3001 m 2731 2959 l 2625 2852 l 2689 2959 l 2582 2895 l cp
eoclip
n 2070 2340 m
2700 2970 l gs col0 s gr gr
% arrowhead
n 2582 2895 m 2689 2959 l 2625 2852 l 2582 2895 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
1773 2949 m 1799 3003 l 1936 2937 l 1815 2963 l 1910 2883 l cp
eoclip
n 3105 2340 m
1800 2970 l gs col0 s gr gr
% arrowhead
n 1910 2883 m 1815 2963 l 1936 2937 l 1910 2883 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
3117 2963 m 3164 3000 l 3257 2881 l 3160 2957 l 3210 2844 l cp
eoclip
n 3645 2340 m
3150 2970 l gs col0 s gr gr
% arrowhead
n 3210 2844 m 3160 2957 l 3257 2881 l 3210 2844 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
4841 2997 m 4893 2968 l 4818 2836 l 4852 2956 l 4766 2866 l cp
eoclip
n 4500 2340 m
4860 2970 l gs col0 s gr gr
% arrowhead
n 4766 2866 m 4852 2956 l 4818 2836 l 4766 2866 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
960 4110 m 1020 4110 l 1020 3959 l 990 4079 l 960 3959 l cp
eoclip
n 990 3465 m
990 4095 l gs col0 s gr gr
% arrowhead
n 960 3959 m 990 4079 l 1020 3959 l 960 3959 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
2146 4125 m 2192 4086 l 2093 3972 l 2149 4083 l 2048 4011 l cp
eoclip
n 1620 3465 m
2160 4095 l gs col0 s gr gr
% arrowhead
n 2048 4011 m 2149 4083 l 2093 3972 l 2048 4011 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
5280 4110 m 5340 4110 l 5340 3959 l 5310 4079 l 5280 3959 l cp
eoclip
n 5310 3465 m
5310 4095 l gs col0 s gr gr
% arrowhead
n 5280 3959 m 5310 4079 l 5340 3959 l 5280 3959 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
4107 4086 m 4153 4125 l 4251 4011 l 4151 4083 l 4206 3972 l cp
eoclip
n 4680 3465 m
4140 4095 l gs col0 s gr gr
% arrowhead
n 4206 3972 m 4151 4083 l 4251 4011 l 4206 3972 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
2760 4875 m 2820 4875 l 2820 4724 l 2790 4844 l 2760 4724 l cp
eoclip
n 2790 3465 m
2790 4860 l gs col0 s gr gr
% arrowhead
n 2760 4724 m 2790 4844 l 2820 4724 l 2760 4724 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
3482 4879 m 3542 4870 l 3517 4720 l 3507 4844 l 3458 4730 l cp
eoclip
n 3285 3465 m
3510 4860 l gs col0 s gr gr
% arrowhead
n 3458 4730 m 3507 4844 l 3517 4720 l 3458 4730 l cp gs 0.00 setgray ef gr col0 s
% Polyline
15.000 slw
[15 45] 45 sd
n 1260 2025 m 2475 2025 l 2475 2340 l 1260 2340 l
cp gs col0 s gr [] 0 sd
% Polyline
[15 45] 45 sd
n 3105 2025 m 5040 2025 l 5040 2340 l 3105 2340 l
cp gs col0 s gr [] 0 sd
% Polyline
[15 45] 45 sd
n 540 4095 m 1440 4095 l 1440 4590 l 540 4590 l
cp gs col0 s gr [] 0 sd
% Polyline
[15 45] 45 sd
n 1710 4095 m 2610 4095 l 2610 4590 l 1710 4590 l
cp gs col0 s gr [] 0 sd
% Polyline
[15 45] 45 sd
n 3690 4095 m 4590 4095 l 4590 4590 l 3690 4590 l
cp gs col0 s gr [] 0 sd
% Polyline
[15 45] 45 sd
n 4860 4095 m 5760 4095 l 5760 4590 l 4860 4590 l
cp gs col0 s gr [] 0 sd
% Polyline
[15 45] 45 sd
n 2025 4860 m 2925 4860 l 2925 5355 l 2025 5355 l
cp gs col0 s gr [] 0 sd
% Polyline
7.500 slw
[15 45] 45 sd
n 3375 4860 m 4275 4860 l 4275 5355 l 3375 5355 l
cp gs col0 s gr [] 0 sd
% Polyline
n 675 4590 m
675 9270 l gs col0 s gr
% Polyline
gs clippath
1050 7410 m 1050 7350 l 899 7350 l 1019 7380 l 899 7410 l cp
eoclip
n 675 7380 m
1035 7380 l gs col0 s gr gr
% arrowhead
n 899 7410 m 1019 7380 l 899 7350 l 899 7410 l cp gs 0.00 setgray ef gr col0 s
% Polyline
n 1710 4590 m 1035 5355 l 855 5400 l
855 6750 l gs col0 s gr
% Polyline
n 1035 5355 m
1215 5400 l gs col0 s gr
% Polyline
gs clippath
1185 5730 m 1245 5730 l 1245 5579 l 1215 5699 l 1185 5579 l cp
eoclip
n 1215 5400 m
1215 5715 l gs col0 s gr gr
% arrowhead
n 1185 5579 m 1215 5699 l 1245 5579 l 1185 5579 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
1901 5711 m 1952 5743 l 2033 5615 l 1944 5701 l 1982 5583 l cp
eoclip
n 2160 5355 m
1935 5715 l gs col0 s gr gr
% arrowhead
n 1982 5583 m 1944 5701 l 2033 5615 l 1982 5583 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
4347 5743 m 4398 5711 l 4317 5583 l 4356 5701 l 4266 5615 l cp
eoclip
n 4140 5355 m
4365 5715 l gs col0 s gr gr
% arrowhead
n 4266 5615 m 4356 5701 l 4317 5583 l 4266 5615 l cp gs 0.00 setgray ef gr col0 s
% Polyline
n 4590 4590 m 5265 5355 l 5445 5400 l
5445 6750 l gs col0 s gr
% Polyline
gs clippath
5055 5730 m 5115 5730 l 5115 5579 l 5085 5699 l 5055 5579 l cp
eoclip
n 5085 5400 m
5085 5715 l gs col0 s gr gr
% arrowhead
n 5055 5579 m 5085 5699 l 5115 5579 l 5055 5579 l cp gs 0.00 setgray ef gr col0 s
% Polyline
n 5265 5355 m
5085 5400 l gs col0 s gr
% Polyline
gs clippath
2809 5736 m 2867 5722 l 2831 5575 l 2831 5699 l 2772 5589 l cp
eoclip
n 2745 5355 m
2835 5715 l gs col0 s gr gr
% arrowhead
n 2772 5589 m 2831 5699 l 2831 5575 l 2772 5589 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
3432 5722 m 3490 5736 l 3527 5589 l 3469 5699 l 3469 5575 l cp
eoclip
n 3555 5355 m
3465 5715 l gs col0 s gr gr
% arrowhead
n 3469 5575 m 3469 5699 l 3527 5589 l 3469 5575 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
2096 8117 m 2103 8176 l 2253 8157 l 2131 8143 l 2246 8098 l cp
eoclip
n 3915 5355 m 3915 7920 l
2115 8145 l gs col0 s gr gr
% arrowhead
n 2246 8098 m 2131 8143 l 2253 8157 l 2246 8098 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
2641 9055 m 2599 9013 l 2492 9119 l 2599 9056 l 2535 9162 l cp
eoclip
n 675 9270 m 2385 9270 l
2610 9045 l gs col0 s gr gr
% arrowhead
n 2535 9162 m 2599 9056 l 2492 9119 l 2535 9162 l cp gs 0.00 setgray ef gr col0 s
% Polyline
n 5625 4590 m
5625 9270 l gs col0 s gr
% Polyline
gs clippath
5250 7350 m 5250 7410 l 5401 7410 l 5281 7380 l 5401 7350 l cp
eoclip
n 5625 7380 m
5265 7380 l gs col0 s gr gr
% arrowhead
n 5401 7350 m 5281 7380 l 5401 7410 l 5401 7350 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
3700 9013 m 3658 9055 l 3764 9162 l 3701 9056 l 3807 9119 l cp
eoclip
n 5625 9270 m 3915 9270 l
3690 9045 l gs col0 s gr gr
% arrowhead
n 3807 9119 m 3701 9056 l 3764 9162 l 3807 9119 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
1020 7005 m 1067 6967 l 973 6849 l 1025 6962 l 926 6887 l cp
eoclip
n 855 6750 m
1035 6975 l gs col0 s gr gr
% arrowhead
n 926 6887 m 1025 6962 l 973 6849 l 926 6887 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
5232 6967 m 5279 7005 l 5373 6887 l 5275 6962 l 5326 6849 l cp
eoclip
n 5445 6750 m
5265 6975 l gs col0 s gr gr
% arrowhead
n 5326 6849 m 5275 6962 l 5373 6887 l 5326 6849 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
1050 8580 m 1050 8520 l 899 8520 l 1019 8550 l 899 8580 l cp
eoclip
n 675 8550 m
1035 8550 l gs col0 s gr gr
% arrowhead
n 899 8580 m 1019 8550 l 899 8520 l 899 8580 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
5250 8520 m 5250 8580 l 5401 8580 l 5281 8550 l 5401 8520 l cp
eoclip
n 5625 8550 m
5265 8550 l gs col0 s gr gr
% arrowhead
n 5401 8520 m 5281 8550 l 5401 8580 l 5401 8520 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
4196 8176 m 4203 8117 l 4053 8098 l 4169 8143 l 4046 8157 l cp
eoclip
n 2385 5355 m 2385 7920 l
4185 8145 l gs col0 s gr gr
% arrowhead
n 4046 8157 m 4169 8143 l 4053 8098 l 4046 8157 l cp gs 0.00 setgray ef gr col0 s
% Polyline
n 1665 6599 m 4748 6599 l 4748 6591 l 1665 6591 l
cp gs col7 1.00 shd ef gr gs col7 s gr
% Polyline
n 1665 6644 m 4726 6644 l 4726 6629 l 1665 6629 l
cp gs col7 1.00 shd ef gr gs col7 s gr
% Polyline
n 1665 6765 m 4731 6765 l 4731 6810 l 1665 6810 l
cp gs col7 1.00 shd ef gr gs col7 s gr
% Polyline
n 1665 6877 m 4748 6877 l 4748 6885 l 1665 6885 l
cp gs col7 1.00 shd ef gr gs col7 s gr
% Polyline
n 1665 6832 m 4726 6832 l 4726 6847 l 1665 6847 l
cp gs col7 1.00 shd ef gr gs col7 s gr
% Polyline
n 1670 6763 m 4731 6763 l 4731 6666 l 1670 6666 l
cp gs col7 1.00 shd ef gr gs col7 s gr
% Polyline
gs clippath
3523 6964 m 3565 7006 l 3672 6900 l 3566 6964 l 3629 6857 l cp
eoclip
n 5445 6750 m 3780 6750 l
3555 6975 l gs col0 s gr gr
% arrowhead
n 3629 6857 m 3566 6964 l 3672 6900 l 3629 6857 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
2734 7006 m 2776 6964 l 2670 6857 l 2734 6964 l 2627 6900 l cp
eoclip
n 855 6750 m 2520 6750 l
2745 6975 l gs col0 s gr gr
% arrowhead
n 2627 6900 m 2734 6964 l 2670 6857 l 2627 6900 l cp gs 0.00 setgray ef gr col0 s
$F2psEnd
rs

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

View file

@ -1,56 +0,0 @@
,,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,,,,,,,,,,,,
: LTL formula `f' :_____ : Negated LTL formula `!f' :
'''''''T''''''T'''' \ ___'''''''T'''''''''''T''''''''
| \ ___X / |
| \ ___/ \______ / |
| ___X X_______ |
| / \ / \ |
V V V V V V
:::::::::::::::: :::::::::::::::: ::::::::::::::::
: LTL-to-Buchi : : LTL-to-Buchi : . . . : LTL-to-Buchi :
: translator 1 : : translator 2 : : translator n :
:::::::::::::::: :::::::::::::::: ::::::::::::::::
| | | | / |
| | | | / |
V V | | V V
,,,,,,,,,,,,, ,,,,,,,,,,,,,, | | ,,,,,,,,,,,,, ,,,,,,,,,,,,,,
: Automaton : : Automaton : | | : Automaton : : Automaton :
: 1 for `f' : : 1 for `!f' : | | : n for `f' : : n for `!f' :
''''''''''''' ''T''''''''''' | | ''''''''''T'' ''''''''''''''
/ ________/ | | \_________ \
/ / V V \ \
/ / ,,,,,,,,,,,,, ,,,,,,,,,,,,,, \ \
| | : Automaton : : Automaton : | |
| / \ : 2 for `f' : : 2 for `!f' : / \ |
| | | ''T''''T''T'' ''T''T''''T''' | | |
| | | | | | | | | | | |
| | V V | | | | V V | |
| | ################# | \ / | ################# | |
| | # Intersection # | \ / | # Intersection # | |
| | # emptiness # | X | # emptiness # | |
| | # check # ! / \ ! # check # | |
|\ | ################# : / \ : ################# | /|
| \ \___________ _____/ \_____ ___________/ / |
| \ \ / . . \ / / |
| \ / \ | : : | / \ / |
| V V \ | | | | / V V |
| ################# \ / V V \ / ################# |
| # Intersection # X ################# X # Intersection # |
| # emptiness # / \ # Intersection # / \ # emptiness # |
| # check # | | # emptiness # | | # check # |
| ################# | | # check # | | ################# |
|\ | | ################# | | /|
| \ / \ / \ / |
| V V V V V V |
| ################# ################# ################# |
| # Intersection # # Intersection # # Intersection # |
| # emptiness # # emptiness # # emptiness # |
| # check # # check # # check # |
| ################# ################# ################# |
\ /
\ ################# /
\ # Intersection # /
+---------------------># emptiness #<---------------------+
# check #
#################

File diff suppressed because it is too large Load diff

View file

@ -1,769 +0,0 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Title: testprocedure.eps
%%Creator: fig2dev Version 3.2 Patchlevel 3a
%%CreationDate: Mon Aug 6 16:10:19 2001
%%For: htauriai@lattice (Heikki Tauriainen,TB349,451 3263,)
%%BoundingBox: 0 0 354 441
%%Magnification: 1.0000
%%EndComments
/$F2psDict 200 dict def
$F2psDict begin
$F2psDict /mtrx matrix put
/col-1 {0 setgray} bind def
/col0 {0.000 0.000 0.000 srgb} bind def
/col1 {0.000 0.000 1.000 srgb} bind def
/col2 {0.000 1.000 0.000 srgb} bind def
/col3 {0.000 1.000 1.000 srgb} bind def
/col4 {1.000 0.000 0.000 srgb} bind def
/col5 {1.000 0.000 1.000 srgb} bind def
/col6 {1.000 1.000 0.000 srgb} bind def
/col7 {1.000 1.000 1.000 srgb} bind def
/col8 {0.000 0.000 0.560 srgb} bind def
/col9 {0.000 0.000 0.690 srgb} bind def
/col10 {0.000 0.000 0.820 srgb} bind def
/col11 {0.530 0.810 1.000 srgb} bind def
/col12 {0.000 0.560 0.000 srgb} bind def
/col13 {0.000 0.690 0.000 srgb} bind def
/col14 {0.000 0.820 0.000 srgb} bind def
/col15 {0.000 0.560 0.560 srgb} bind def
/col16 {0.000 0.690 0.690 srgb} bind def
/col17 {0.000 0.820 0.820 srgb} bind def
/col18 {0.560 0.000 0.000 srgb} bind def
/col19 {0.690 0.000 0.000 srgb} bind def
/col20 {0.820 0.000 0.000 srgb} bind def
/col21 {0.560 0.000 0.560 srgb} bind def
/col22 {0.690 0.000 0.690 srgb} bind def
/col23 {0.820 0.000 0.820 srgb} bind def
/col24 {0.500 0.190 0.000 srgb} bind def
/col25 {0.630 0.250 0.000 srgb} bind def
/col26 {0.750 0.380 0.000 srgb} bind def
/col27 {1.000 0.500 0.500 srgb} bind def
/col28 {1.000 0.630 0.630 srgb} bind def
/col29 {1.000 0.750 0.750 srgb} bind def
/col30 {1.000 0.880 0.880 srgb} bind def
/col31 {1.000 0.840 0.000 srgb} bind def
end
save
newpath 0 441 moveto 0 0 lineto 354 0 lineto 354 441 lineto closepath clip newpath
-11.0 521.0 translate
1 -1 scale
/cp {closepath} bind def
/ef {eofill} bind def
/gr {grestore} bind def
/gs {gsave} bind def
/sa {save} bind def
/rs {restore} bind def
/l {lineto} bind def
/m {moveto} bind def
/rm {rmoveto} bind def
/n {newpath} bind def
/s {stroke} bind def
/sh {show} bind def
/slc {setlinecap} bind def
/slj {setlinejoin} bind def
/slw {setlinewidth} bind def
/srgb {setrgbcolor} bind def
/rot {rotate} bind def
/sc {scale} bind def
/sd {setdash} bind def
/ff {findfont} bind def
/sf {setfont} bind def
/scf {scalefont} bind def
/sw {stringwidth} bind def
/tr {translate} bind def
/tnt {dup dup currentrgbcolor
4 -2 roll dup 1 exch sub 3 -1 roll mul add
4 -2 roll dup 1 exch sub 3 -1 roll mul add
4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
bind def
/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
4 -2 roll mul srgb} bind def
/reencdict 12 dict def /ReEncode { reencdict begin
/newcodesandnames exch def /newfontname exch def /basefontname exch def
/basefontdict basefontname findfont def /newfont basefontdict maxlength dict def
basefontdict { exch dup /FID ne { dup /Encoding eq
{ exch dup length array copy newfont 3 1 roll put }
{ exch newfont 3 1 roll put } ifelse } { pop pop } ifelse } forall
newfont /FontName newfontname put newcodesandnames aload pop
128 1 255 { newfont /Encoding get exch /.notdef put } for
newcodesandnames length 2 idiv { newfont /Encoding get 3 1 roll put } repeat
newfontname newfont definefont pop end } def
/isovec [
8#055 /minus 8#200 /grave 8#201 /acute 8#202 /circumflex 8#203 /tilde
8#204 /macron 8#205 /breve 8#206 /dotaccent 8#207 /dieresis
8#210 /ring 8#211 /cedilla 8#212 /hungarumlaut 8#213 /ogonek 8#214 /caron
8#220 /dotlessi 8#230 /oe 8#231 /OE
8#240 /space 8#241 /exclamdown 8#242 /cent 8#243 /sterling
8#244 /currency 8#245 /yen 8#246 /brokenbar 8#247 /section 8#250 /dieresis
8#251 /copyright 8#252 /ordfeminine 8#253 /guillemotleft 8#254 /logicalnot
8#255 /hyphen 8#256 /registered 8#257 /macron 8#260 /degree 8#261 /plusminus
8#262 /twosuperior 8#263 /threesuperior 8#264 /acute 8#265 /mu 8#266 /paragraph
8#267 /periodcentered 8#270 /cedilla 8#271 /onesuperior 8#272 /ordmasculine
8#273 /guillemotright 8#274 /onequarter 8#275 /onehalf
8#276 /threequarters 8#277 /questiondown 8#300 /Agrave 8#301 /Aacute
8#302 /Acircumflex 8#303 /Atilde 8#304 /Adieresis 8#305 /Aring
8#306 /AE 8#307 /Ccedilla 8#310 /Egrave 8#311 /Eacute
8#312 /Ecircumflex 8#313 /Edieresis 8#314 /Igrave 8#315 /Iacute
8#316 /Icircumflex 8#317 /Idieresis 8#320 /Eth 8#321 /Ntilde 8#322 /Ograve
8#323 /Oacute 8#324 /Ocircumflex 8#325 /Otilde 8#326 /Odieresis 8#327 /multiply
8#330 /Oslash 8#331 /Ugrave 8#332 /Uacute 8#333 /Ucircumflex
8#334 /Udieresis 8#335 /Yacute 8#336 /Thorn 8#337 /germandbls 8#340 /agrave
8#341 /aacute 8#342 /acircumflex 8#343 /atilde 8#344 /adieresis 8#345 /aring
8#346 /ae 8#347 /ccedilla 8#350 /egrave 8#351 /eacute
8#352 /ecircumflex 8#353 /edieresis 8#354 /igrave 8#355 /iacute
8#356 /icircumflex 8#357 /idieresis 8#360 /eth 8#361 /ntilde 8#362 /ograve
8#363 /oacute 8#364 /ocircumflex 8#365 /otilde 8#366 /odieresis 8#367 /divide
8#370 /oslash 8#371 /ugrave 8#372 /uacute 8#373 /ucircumflex
8#374 /udieresis 8#375 /yacute 8#376 /thorn 8#377 /ydieresis] def
/Times-Roman /Times-Roman-iso isovec ReEncode
/Times-Italic /Times-Italic-iso isovec ReEncode
/DrawEllipse {
/endangle exch def
/startangle exch def
/yrad exch def
/xrad exch def
/y exch def
/x exch def
/savematrix mtrx currentmatrix def
x y tr xrad yrad sc 0 0 1 startangle endangle arc
closepath
savematrix setmatrix
} def
/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
/$F2psEnd {$F2psEnteredState restore end} def
$F2psBegin
%%Page: 1 1
10 setmiterlimit
0.06299 0.06299 sc
/Times-Roman-iso ff 180.00 scf sf
2925 3150 m
gs 1 -1 sc (LTL-to-B\374chi) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Roman-iso ff 180.00 scf sf
2925 3375 m
gs 1 -1 sc (translator 2) dup sw pop 2 div neg 0 rm col0 sh gr
% Polyline
15.000 slw
n 2295 2970 m 3555 2970 l 3555 3465 l 2295 3465 l
cp gs col0 s gr
7.500 slw
% Ellipse
n 3847 3195 23 23 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr
% Ellipse
n 4027 3195 23 23 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr
% Ellipse
n 4207 3195 23 23 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr
/Times-Italic-iso ff 180.00 scf sf
2340 2227 m
gs 1 -1 sc (f) col0 sh gr
/Times-Roman-iso ff 180.00 scf sf
1305 2227 m
gs 1 -1 sc (LTL formula) col0 sh gr
% Polyline
n 4830 2154 m 4867 2154 l
4867 2184 l gs col0 s gr
/Times-Italic-iso ff 180.00 scf sf
4905 2227 m
gs 1 -1 sc (f) col0 sh gr
/Times-Roman-iso ff 180.00 scf sf
3150 2227 m
gs 1 -1 sc (Negated LTL formula) col0 sh gr
/Times-Italic-iso ff 180.00 scf sf
2700 5265 m
gs 1 -1 sc (f) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Roman-iso ff 180.00 scf sf
2385 5265 m
gs 1 -1 sc (2 for) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Roman-iso ff 180.00 scf sf
2475 5040 m
gs 1 -1 sc (Automaton) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Roman-iso ff 180.00 scf sf
900 4500 m
gs 1 -1 sc (1 for) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Italic-iso ff 180.00 scf sf
1215 4500 m
gs 1 -1 sc (f) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Roman-iso ff 180.00 scf sf
990 4275 m
gs 1 -1 sc (Automaton) dup sw pop 2 div neg 0 rm col0 sh gr
% Polyline
n 2287 4423 m 2324 4423 l
2324 4453 l gs col0 s gr
/Times-Italic-iso ff 180.00 scf sf
2362 4496 m
gs 1 -1 sc (f) col0 sh gr
/Times-Roman-iso ff 180.00 scf sf
2025 4499 m
gs 1 -1 sc (1 for) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Roman-iso ff 180.00 scf sf
2160 4274 m
gs 1 -1 sc (Automaton) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Italic-iso ff 180.00 scf sf
4334 4497 m
gs 1 -1 sc (f) col0 sh gr
/Times-Roman-iso ff 180.00 scf sf
4117 4499 m
gs 1 -1 sc (for) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Italic-iso ff 180.00 scf sf
3892 4499 m
gs 1 -1 sc (n) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Roman-iso ff 180.00 scf sf
4140 4274 m
gs 1 -1 sc (Automaton) dup sw pop 2 div neg 0 rm col0 sh gr
% Polyline
n 5452 4424 m 5489 4424 l
5489 4454 l gs col0 s gr
/Times-Italic-iso ff 180.00 scf sf
5527 4497 m
gs 1 -1 sc (f) col0 sh gr
/Times-Roman-iso ff 180.00 scf sf
5265 4499 m
gs 1 -1 sc (for) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Italic-iso ff 180.00 scf sf
5040 4499 m
gs 1 -1 sc (n) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Roman-iso ff 180.00 scf sf
5310 4274 m
gs 1 -1 sc (Automaton) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Italic-iso ff 180.00 scf sf
5512 3375 m
gs 1 -1 sc (n) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Roman-iso ff 180.00 scf sf
4702 3375 m
gs 1 -1 sc (translator) col0 sh gr
/Times-Roman-iso ff 180.00 scf sf
5130 3150 m
gs 1 -1 sc (LTL-to-B\374chi) dup sw pop 2 div neg 0 rm col0 sh gr
% Polyline
15.000 slw
n 4500 2970 m 5760 2970 l 5760 3465 l 4500 3465 l
cp gs col0 s gr
% Polyline
7.500 slw
n 3950 5189 m 3987 5189 l
3987 5219 l gs col0 s gr
/Times-Italic-iso ff 180.00 scf sf
4025 5262 m
gs 1 -1 sc (f) col0 sh gr
/Times-Roman-iso ff 180.00 scf sf
3690 5264 m
gs 1 -1 sc (2 for) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Roman-iso ff 180.00 scf sf
3825 5039 m
gs 1 -1 sc (Automaton) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Roman-iso ff 180.00 scf sf
1665 6142 m
gs 1 -1 sc (Model) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Roman-iso ff 180.00 scf sf
1665 6367 m
gs 1 -1 sc (check) dup sw pop 2 div neg 0 rm col0 sh gr
% Polyline
15.000 slw
n 1395 5940 m 1935 5940 l 1935 6435 l 1395 6435 l
cp gs col0 s gr
/Times-Roman-iso ff 180.00 scf sf
810 6142 m
gs 1 -1 sc (Model) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Roman-iso ff 180.00 scf sf
810 6367 m
gs 1 -1 sc (check) dup sw pop 2 div neg 0 rm col0 sh gr
% Polyline
n 540 5940 m 1080 5940 l 1080 6435 l 540 6435 l
cp gs col0 s gr
/Times-Roman-iso ff 180.00 scf sf
5490 6142 m
gs 1 -1 sc (Model) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Roman-iso ff 180.00 scf sf
5490 6367 m
gs 1 -1 sc (check) dup sw pop 2 div neg 0 rm col0 sh gr
% Polyline
n 5220 5940 m 5760 5940 l 5760 6435 l 5220 6435 l
cp gs col0 s gr
/Times-Roman-iso ff 180.00 scf sf
4635 6142 m
gs 1 -1 sc (Model) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Roman-iso ff 180.00 scf sf
4635 6367 m
gs 1 -1 sc (check) dup sw pop 2 div neg 0 rm col0 sh gr
% Polyline
n 4365 5940 m 4905 5940 l 4905 6435 l 4365 6435 l
cp gs col0 s gr
/Times-Roman-iso ff 180.00 scf sf
2745 6142 m
gs 1 -1 sc (Model) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Roman-iso ff 180.00 scf sf
2745 6367 m
gs 1 -1 sc (check) dup sw pop 2 div neg 0 rm col0 sh gr
% Polyline
n 2475 5940 m 3015 5940 l 3015 6435 l 2475 6435 l
cp gs col0 s gr
/Times-Roman-iso ff 180.00 scf sf
3555 6142 m
gs 1 -1 sc (Model) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Roman-iso ff 180.00 scf sf
3555 6367 m
gs 1 -1 sc (check) dup sw pop 2 div neg 0 rm col0 sh gr
% Polyline
n 3285 5940 m 3825 5940 l 3825 6435 l 3285 6435 l
cp gs col0 s gr
/Times-Roman-iso ff 180.00 scf sf
1395 7065 m
gs 1 -1 sc (Consistency) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Roman-iso ff 180.00 scf sf
1395 7290 m
gs 1 -1 sc (check) dup sw pop 2 div neg 0 rm col0 sh gr
% Polyline
n 855 6840 m 1935 6840 l 1935 7425 l 855 7425 l
cp gs col0 s gr
% Polyline
n 900 6885 m 1890 6885 l 1890 7380 l 900 7380 l
cp gs col0 s gr
/Times-Roman-iso ff 180.00 scf sf
4905 7065 m
gs 1 -1 sc (Consistency) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Roman-iso ff 180.00 scf sf
4905 7290 m
gs 1 -1 sc (check) dup sw pop 2 div neg 0 rm col0 sh gr
% Polyline
n 4410 6885 m 5400 6885 l 5400 7380 l 4410 7380 l
cp gs col0 s gr
% Polyline
n 4365 6840 m 5445 6840 l 5445 7425 l 4365 7425 l
cp gs col0 s gr
/Times-Roman-iso ff 180.00 scf sf
3150 7065 m
gs 1 -1 sc (Consistency) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Roman-iso ff 180.00 scf sf
3150 7290 m
gs 1 -1 sc (check) dup sw pop 2 div neg 0 rm col0 sh gr
% Polyline
n 2655 6885 m 3645 6885 l 3645 7380 l 2655 7380 l
cp gs col0 s gr
% Polyline
n 2610 6840 m 3690 6840 l 3690 7425 l 2610 7425 l
cp gs col0 s gr
% Polyline
n 540 7875 m 2520 7875 l 2520 8235 l 540 8235 l
cp gs col0 s gr
% Polyline
n 585 7920 m 2475 7920 l 2475 8190 l 585 8190 l
cp gs col0 s gr
/Times-Roman-iso ff 180.00 scf sf
1530 8100 m
gs 1 -1 sc (Cross-comparison test) dup sw pop 2 div neg 0 rm col0 sh gr
% Polyline
n 3825 7920 m 5715 7920 l 5715 8190 l 3825 8190 l
cp gs col0 s gr
% Polyline
n 3780 7875 m 5760 7875 l 5760 8235 l 3780 8235 l
cp gs col0 s gr
/Times-Roman-iso ff 180.00 scf sf
4770 8100 m
gs 1 -1 sc (Cross-comparison test) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Roman-iso ff 180.00 scf sf
1170 3375 m
gs 1 -1 sc (translator 1) dup sw pop 2 div neg 0 rm col0 sh gr
/Times-Roman-iso ff 180.00 scf sf
1170 3150 m
gs 1 -1 sc (LTL-to-B\374chi) dup sw pop 2 div neg 0 rm col0 sh gr
% Polyline
n 540 2970 m 1800 2970 l 1800 3465 l 540 3465 l
cp gs col0 s gr
% Polyline
7.500 slw
gs clippath
1001 2966 m 1052 2998 l 1134 2871 l 1044 2956 l 1083 2838 l cp
eoclip
n 1440 2340 m
1035 2970 l gs col0 s gr gr
% arrowhead
n 1083 2838 m 1044 2956 l 1134 2871 l 1083 2838 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
4505 3003 m 4523 2945 l 4379 2900 l 4485 2965 l 4361 2957 l cp
eoclip
n 2475 2340 m
4500 2970 l gs col0 s gr gr
% arrowhead
n 4361 2957 m 4485 2965 l 4379 2900 l 4361 2957 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
2689 3001 m 2731 2959 l 2625 2852 l 2689 2959 l 2582 2895 l cp
eoclip
n 2070 2340 m
2700 2970 l gs col0 s gr gr
% arrowhead
n 2582 2895 m 2689 2959 l 2625 2852 l 2582 2895 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
1773 2949 m 1799 3003 l 1936 2937 l 1815 2963 l 1910 2883 l cp
eoclip
n 3105 2340 m
1800 2970 l gs col0 s gr gr
% arrowhead
n 1910 2883 m 1815 2963 l 1936 2937 l 1910 2883 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
3117 2963 m 3164 3000 l 3257 2881 l 3160 2957 l 3210 2844 l cp
eoclip
n 3645 2340 m
3150 2970 l gs col0 s gr gr
% arrowhead
n 3210 2844 m 3160 2957 l 3257 2881 l 3210 2844 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
4841 2997 m 4893 2968 l 4818 2836 l 4852 2956 l 4766 2866 l cp
eoclip
n 4500 2340 m
4860 2970 l gs col0 s gr gr
% arrowhead
n 4766 2866 m 4852 2956 l 4818 2836 l 4766 2866 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
960 4110 m 1020 4110 l 1020 3959 l 990 4079 l 960 3959 l cp
eoclip
n 990 3465 m
990 4095 l gs col0 s gr gr
% arrowhead
n 960 3959 m 990 4079 l 1020 3959 l 960 3959 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
2146 4125 m 2192 4086 l 2093 3972 l 2149 4083 l 2048 4011 l cp
eoclip
n 1620 3465 m
2160 4095 l gs col0 s gr gr
% arrowhead
n 2048 4011 m 2149 4083 l 2093 3972 l 2048 4011 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
5280 4110 m 5340 4110 l 5340 3959 l 5310 4079 l 5280 3959 l cp
eoclip
n 5310 3465 m
5310 4095 l gs col0 s gr gr
% arrowhead
n 5280 3959 m 5310 4079 l 5340 3959 l 5280 3959 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
4107 4086 m 4153 4125 l 4251 4011 l 4151 4083 l 4206 3972 l cp
eoclip
n 4680 3465 m
4140 4095 l gs col0 s gr gr
% arrowhead
n 4206 3972 m 4151 4083 l 4251 4011 l 4206 3972 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
2760 4875 m 2820 4875 l 2820 4724 l 2790 4844 l 2760 4724 l cp
eoclip
n 2790 3465 m
2790 4860 l gs col0 s gr gr
% arrowhead
n 2760 4724 m 2790 4844 l 2820 4724 l 2760 4724 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
3482 4879 m 3542 4870 l 3517 4720 l 3507 4844 l 3458 4730 l cp
eoclip
n 3285 3465 m
3510 4860 l gs col0 s gr gr
% arrowhead
n 3458 4730 m 3507 4844 l 3517 4720 l 3458 4730 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
870 5955 m 930 5955 l 930 5804 l 900 5924 l 870 5804 l cp
eoclip
n 900 4590 m
900 5940 l gs col0 s gr gr
% arrowhead
n 870 5804 m 900 5924 l 930 5804 l 870 5804 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
1722 5949 m 1782 5959 l 1807 5810 l 1758 5924 l 1748 5800 l cp
eoclip
n 1980 4590 m
1755 5940 l gs col0 s gr gr
% arrowhead
n 1748 5800 m 1758 5924 l 1807 5810 l 1748 5800 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
5550 5955 m 5610 5955 l 5610 5804 l 5580 5924 l 5550 5804 l cp
eoclip
n 5580 4590 m
5580 5940 l gs col0 s gr gr
% arrowhead
n 5550 5804 m 5580 5924 l 5610 5804 l 5550 5804 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
4744 5961 m 4802 5947 l 4767 5800 l 4766 5924 l 4709 5813 l cp
eoclip
n 4455 4590 m
4770 5940 l gs col0 s gr gr
% arrowhead
n 4709 5813 m 4766 5924 l 4767 5800 l 4709 5813 l cp gs 0.00 setgray ef gr col0 s
% Polyline
n 315 1620 m
315 5580 l gs col0 s gr
% Polyline
gs clippath
2854 5961 m 2912 5947 l 2878 5800 l 2876 5924 l 2819 5813 l cp
eoclip
n 2745 5355 m
2880 5940 l gs col0 s gr gr
% arrowhead
n 2819 5813 m 2876 5924 l 2878 5800 l 2819 5813 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
3611 5945 m 3669 5963 l 3713 5819 l 3650 5925 l 3656 5801 l cp
eoclip
n 3825 5355 m
3645 5940 l gs col0 s gr gr
% arrowhead
n 3656 5801 m 3650 5925 l 3713 5819 l 3656 5801 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
2943 6861 m 3002 6848 l 2969 6700 l 2966 6824 l 2910 6713 l cp
eoclip
n 2880 6435 m
2970 6840 l gs col0 s gr gr
% arrowhead
n 2910 6713 m 2966 6824 l 2969 6700 l 2910 6713 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
3297 6848 m 3356 6861 l 3389 6713 l 3334 6824 l 3330 6700 l cp
eoclip
n 3420 6435 m
3330 6840 l gs col0 s gr gr
% arrowhead
n 3330 6700 m 3334 6824 l 3389 6713 l 3330 6700 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
1498 6851 m 1558 6858 l 1575 6708 l 1532 6824 l 1515 6701 l cp
eoclip
n 1575 6435 m
1530 6840 l gs col0 s gr gr
% arrowhead
n 1515 6701 m 1532 6824 l 1575 6708 l 1515 6701 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
1151 6867 m 1203 6838 l 1129 6706 l 1162 6826 l 1077 6735 l cp
eoclip
n 945 6435 m
1170 6840 l gs col0 s gr gr
% arrowhead
n 1077 6735 m 1162 6826 l 1129 6706 l 1077 6735 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
4741 6858 m 4801 6851 l 4784 6701 l 4768 6824 l 4724 6708 l cp
eoclip
n 4725 6435 m
4770 6840 l gs col0 s gr gr
% arrowhead
n 4724 6708 m 4768 6824 l 4784 6701 l 4724 6708 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
5096 6838 m 5148 6867 l 5222 6735 l 5138 6826 l 5170 6706 l cp
eoclip
n 5355 6435 m
5130 6840 l gs col0 s gr gr
% arrowhead
n 5170 6706 m 5138 6826 l 5222 6735 l 5170 6706 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
645 7890 m 705 7890 l 705 7739 l 675 7859 l 645 7739 l cp
eoclip
n 675 6435 m
675 7875 l gs col0 s gr gr
% arrowhead
n 645 7739 m 675 7859 l 705 7739 l 645 7739 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
5595 7890 m 5655 7890 l 5655 7739 l 5625 7859 l 5595 7739 l cp
eoclip
n 5625 6435 m
5625 7875 l gs col0 s gr gr
% arrowhead
n 5595 7739 m 5625 7859 l 5655 7739 l 5595 7739 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
1946 7879 m 2003 7898 l 2052 7756 l 1985 7860 l 1995 7736 l cp
eoclip
n 2475 6435 m
1980 7875 l gs col0 s gr gr
% arrowhead
n 1995 7736 m 1985 7860 l 2052 7756 l 1995 7736 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
4296 7898 m 4353 7879 l 4304 7736 l 4315 7860 l 4247 7756 l cp
eoclip
n 3825 6435 m
4320 7875 l gs col0 s gr gr
% arrowhead
n 4247 7756 m 4315 7860 l 4304 7736 l 4247 7756 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
2498 7849 m 2512 7907 l 2659 7872 l 2536 7871 l 2645 7813 l cp
eoclip
n 4365 6435 m 3825 7560 l
2520 7875 l gs col0 s gr gr
% arrowhead
n 2645 7813 m 2536 7871 l 2659 7872 l 2645 7813 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
3787 7907 m 3801 7849 l 3654 7813 l 3764 7871 l 3640 7872 l cp
eoclip
n 1935 6435 m 2475 7560 l
3780 7875 l gs col0 s gr gr
% arrowhead
n 3640 7872 m 3764 7871 l 3654 7813 l 3640 7872 l cp gs 0.00 setgray ef gr col0 s
% Polyline
15.000 slw
[15 45] 45 sd
n 202 1305 m 1237 1305 l 1237 1620 l 202 1620 l
cp gs col0 s gr [] 0 sd
% Polyline
[15 45] 45 sd
n 1260 2025 m 2475 2025 l 2475 2340 l 1260 2340 l
cp gs col0 s gr [] 0 sd
% Polyline
[15 45] 45 sd
n 3105 2025 m 5040 2025 l 5040 2340 l 3105 2340 l
cp gs col0 s gr [] 0 sd
% Polyline
[15 45] 45 sd
n 540 4095 m 1440 4095 l 1440 4590 l 540 4590 l
cp gs col0 s gr [] 0 sd
% Polyline
[15 45] 45 sd
n 1710 4095 m 2610 4095 l 2610 4590 l 1710 4590 l
cp gs col0 s gr [] 0 sd
% Polyline
[15 45] 45 sd
n 3690 4095 m 4590 4095 l 4590 4590 l 3690 4590 l
cp gs col0 s gr [] 0 sd
% Polyline
[15 45] 45 sd
n 4860 4095 m 5760 4095 l 5760 4590 l 4860 4590 l
cp gs col0 s gr [] 0 sd
% Polyline
[15 45] 45 sd
n 2025 4860 m 2925 4860 l 2925 5355 l 2025 5355 l
cp gs col0 s gr [] 0 sd
% Polyline
7.500 slw
[15 45] 45 sd
n 3375 4860 m 4275 4860 l 4275 5355 l 3375 5355 l
cp gs col0 s gr [] 0 sd
/Times-Roman-iso ff 180.00 scf sf
720 1507 m
gs 1 -1 sc (State space) dup sw pop 2 div neg 0 rm col0 sh gr
% Polyline
n 744 5435 m 4997 5435 l 4997 5427 l 744 5427 l
cp gs col7 1.00 shd ef gr gs col7 s gr
% Polyline
n 744 5480 m 4967 5480 l 4967 5465 l 744 5465 l
cp gs col7 1.00 shd ef gr gs col7 s gr
% Polyline
n 744 5601 m 4974 5601 l 4974 5646 l 744 5646 l
cp gs col7 1.00 shd ef gr gs col7 s gr
% Polyline
n 744 5713 m 4997 5713 l 4997 5721 l 744 5721 l
cp gs col7 1.00 shd ef gr gs col7 s gr
% Polyline
n 744 5668 m 4967 5668 l 4967 5683 l 744 5683 l
cp gs col7 1.00 shd ef gr gs col7 s gr
% Polyline
n 751 5599 m 4974 5599 l 4974 5502 l 751 5502 l
cp gs col7 1.00 shd ef gr gs col7 s gr
% Polyline
n 315 5580 m
5175 5580 l gs col0 s gr
% Polyline
gs clippath
684 5968 m 735 5936 l 654 5808 l 693 5926 l 603 5840 l cp
eoclip
n 477 5580 m
702 5940 l gs col0 s gr gr
% arrowhead
n 603 5840 m 693 5926 l 654 5808 l 603 5840 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
1552 5968 m 1603 5936 l 1522 5808 l 1561 5926 l 1471 5840 l cp
eoclip
n 1345 5580 m
1570 5940 l gs col0 s gr gr
% arrowhead
n 1471 5840 m 1561 5926 l 1522 5808 l 1471 5840 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
2633 5968 m 2684 5936 l 2603 5808 l 2642 5926 l 2552 5840 l cp
eoclip
n 2426 5580 m
2651 5940 l gs col0 s gr gr
% arrowhead
n 2552 5840 m 2642 5926 l 2603 5808 l 2552 5840 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
3447 5968 m 3498 5936 l 3417 5808 l 3456 5926 l 3366 5840 l cp
eoclip
n 3240 5580 m
3465 5940 l gs col0 s gr gr
% arrowhead
n 3366 5840 m 3456 5926 l 3417 5808 l 3366 5840 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
4498 5968 m 4549 5936 l 4468 5808 l 4507 5926 l 4417 5840 l cp
eoclip
n 4291 5580 m
4516 5940 l gs col0 s gr gr
% arrowhead
n 4417 5840 m 4507 5926 l 4468 5808 l 4417 5840 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
5382 5968 m 5433 5936 l 5352 5808 l 5391 5926 l 5301 5840 l cp
eoclip
n 5175 5580 m
5400 5940 l gs col0 s gr gr
% arrowhead
n 5301 5840 m 5391 5926 l 5352 5808 l 5301 5840 l cp gs 0.00 setgray ef gr col0 s
$F2psEnd
rs

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

View file

@ -1,55 +0,0 @@
,,,,,,,,,,,,,,,
: State space :
'''''''''''''''
|
| ,,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,,,,,,,,,,,,
| : LTL formula `f' :_____ : Negated LTL formula `!f' :
| '''''''T''''''T'''' \ ___'''''''T'''''''''''T''''''''
| | \ ___X / |
| | \ ___/ \______ / |
| | ___X X_______ |
| | / \ / \ |
| V V V V V V
| :::::::::::::::: :::::::::::::::: ::::::::::::::::
| : LTL-to-Buchi : : LTL-to-Buchi : . . . : LTL-to-Buchi :
| : translator 1 : : translator 2 : : translator n :
| :::::::::::::::: :::::::::::::::: ::::::::::::::::
| | | | | / |
| | | | | / |
| V V | | V V
| ,,,,,,,,,,,,, ,,,,,,,,,,,,,, | | ,,,,,,,,,,,,, ,,,,,,,,,,,,,,
| : Automaton : : Automaton : | | : Automaton : : Automaton :
| : 1 for `f' : : 1 for `!f' : | | : n for `f' : : n for `!f' :
| ''T'''''''''' '''T'''''''''' | | ''''''''''T'' '''''''''''T''
| | _/ V V \_____ \_
| | / ,,,,,,,,,,,,, ,,,,,,,,,,,,,, \ \
| | | : Automaton : : Automaton : | |
| | | : 2 for `f' : : 2 for `!f' : | |
| | | '''''''''T''' '''''''T'''''' | |
| ! ! ! ! ! |
|__________________________________________________________ |
| . \ . \ . \ . \ . \ |
| : \ : \ : \ : \ : \ |
| | \ | \ | \ | \ | \ |
V V V V V V V V V V V V
::::::::: ::::::::: ::::::::: ::::::::: ::::::::: :::::::::
: Model : : Model : : Model : : Model : : Model : : Model :
: check : : check : : check : : check : : check : : check :
::::::::: ::::::::: ::::::::: ::::::::: ::::::::: :::::::::
| \ | \ / | | \ / | / |
| \ | \ / | | \ / | / |
| \ | \ / | | \ / | / |
| V V X V V X V V |
| ############### / \ ############### / \ ############### |
| # Consistency # | | # Consistency # | | # Consistency # |
| # check # | | # check # | | # check # |
| ############### | | ############### | | ############### |
\______ | \_______ _______/ | ______/
\ | \ / | /
| | X | |
| | _/ \_ | |
V V V V V V
######################### #########################
# Cross-comparison test # # Cross-comparison test #
######################### #########################

View file

@ -1,52 +0,0 @@
dnl Adapted from the predefined _AC_LANG_COMPILER_GNU.
m4_define([_AC_LANG_COMPILER_INTEL],
[AC_CACHE_CHECK([whether we are using the INTEL _AC_LANG compiler],
[ac_cv_[]_AC_LANG_ABBREV[]_compiler_intel],
[
_AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [[#ifndef __INTEL_COMPILER
choke me
#endif
]])],
[ac_compiler_intel=yes],
[ac_compiler_intel=no])
ac_cv_[]_AC_LANG_ABBREV[]_compiler_intel=$ac_compiler_intel
])])# _AC_LANG_COMPILER_INTEL
dnl The list of warnings that must be disabled.
m4_define([_INTEL_IGNORE_WARNINGS],
[ 913 dnl Warn when multibyte character are used (for example "Büchi").
]) # _INTEL_IGNORE_WARNINGS
dnl Add extra flags when icpc is used.
AC_DEFUN([lbtt_INTEL],
[_AC_LANG_COMPILER_INTEL
AC_CACHE_CHECK([to add extra CXXFLAGS for the INTEL C++ compiler],
[ac_cv_intel_cxxflags],
[ dnl
if test x"$ac_cv_[]_AC_LANG_ABBREV[]_compiler_intel" = x"yes"; then
disabled_warnings=''
for warning in _INTEL_IGNORE_WARNINGS; do
disabled_warnings="$disabled_warnings,$warning"
done
# Remove the extra "," and extra whitespaces.
disabled_warnings=`echo "$disabled_warnings" | sed "s/^,//;s/[[[:space:]]]//g"`
INTEL_CXXFLAGS="-w1 -Werror -wd${disabled_warnings}"
[ac_cv_intel_cxxflags="$INTEL_CXXFLAGS"]
else
[ac_cv_intel_cxxflags=""]
fi])
if test x"$ac_cv_[]_AC_LANG_ABBREV[]_compiler_intel" = x"yes"; then
# -W does not exist for icpc in CXXFLAGS.
CXXFLAGS=`echo "$CXXFLAGS" | sed 's/-W[[[:space:]]]//g;s/-W$//'`
# Even if the icpc preprocessor defines __GNUC__, it is not a GNU compiler.
GXX=
CXXFLAGS="$CXXFLAGS $ac_cv_intel_cxxflags"
fi
AC_SUBST([INTEL_CXXFLAGS])
]) # lbtt_INTEL

View file

@ -1,15 +0,0 @@
.deps
.libs
*.lo
*.la
Makefile
Makefile.in
lbtt
lbtt-translate
Config-lex.cc
Config-parse.cc
Config-parse.h
Graph.h
NeverClaim-lex.cc
NeverClaim-parse.cc
NeverClaim-parse.h

20
lbtt/src/.gitignore vendored
View file

@ -1,20 +0,0 @@
.deps
.libs
*.lo
*.la
Makefile
Makefile.in
lbtt
lbtt-translate
Config-lex.cc
Config-parse.cc
Config-parse.c
Config-parse.h
Graph.h
NeverClaim-lex.cc
NeverClaim-parse.cc
NeverClaim-parse.c
NeverClaim-parse.h
Ltl-parse.cc
Ltl-parse.c
Ltl-parse.h

View file

@ -1,453 +0,0 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* 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.
*/
#include <config.h>
#ifdef HAVE_SSTREAM
#include <sstream>
#else
#include <strstream>
#endif /* HAVE_SSTREAM */
#include "BitArray.h"
#include "Exception.h"
/******************************************************************************
*
* `bit_counts[i]' tells the number of 1-bits in the 8-bit integer `i'.
*
*****************************************************************************/
const unsigned char BitArray::bit_counts[] =
{0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2,
3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3,
3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3,
4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4,
3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5,
6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4,
4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5,
6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 2, 3, 3, 4, 3, 4, 4, 5,
3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 3,
4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6,
6, 7, 6, 7, 7, 8};
/******************************************************************************
*
* Function definitions for class BitArray.
*
*****************************************************************************/
/* ========================================================================= */
BitArray::BitArray(const unsigned long int size)
/* ----------------------------------------------------------------------------
*
* Description: Constructor for class BitArray. Creates a bit array of a
* given size.
*
* Argument: size -- Number of bits to allocate.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
unsigned long int bsize = (size + 7) >> 3;
bits = new unsigned char[bsize];
}
/* ========================================================================= */
BitArray::~BitArray()
/* ----------------------------------------------------------------------------
*
* Description: Destructor for class BitArray. Deallocates the memory used by
* the bit array.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
delete[] bits;
}
/* ========================================================================= */
void BitArray::copy
(const BitArray& bitarray, const unsigned long int bit_count)
/* ----------------------------------------------------------------------------
*
* Description: Copy the first `bit_count' bits from `bitarray' to `this'
* BitArray object. (As a side effect, the capacity of `this'
* bit array is set to `bit_count'.)
*
* Argument: bitarray -- Reference to a constant bit array which should
* be copied.
* bit_count -- Number of bits to copy.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
if (this != &bitarray)
{
delete[] bits;
unsigned long int bsize = (bit_count + 7) >> 3;
bits = new unsigned char[bsize];
memcpy(static_cast<void*>(bits), static_cast<const void*>(bitarray.bits),
bsize);
}
}
/* ========================================================================= */
bool BitArray::equal
(const BitArray& bitarray, const unsigned long int bit_count) const
/* ----------------------------------------------------------------------------
*
* Description: Test whether the first `bit_count' bits of `this' BitArray
* are equal to the correspoding bits of `bitarray'.
*
* Argument: bitarray -- Target of the comparison.
* bit_count -- Number of bits to compare.
*
* Returns: `true' if the compared bits agree and `false' otherwise.
*
* ------------------------------------------------------------------------- */
{
if (bit_count > 0)
{
unsigned long int bsize = bit_count >> 3;
for (unsigned long int i = 0; i < bsize; ++i)
{
if (bits[i] != bitarray.bits[i])
return false;
}
if ((bit_count & 0x07) == 0)
return true;
unsigned char mask = (1 << (bit_count & 0x07)) - 1;
if (((bits[bsize] ^ bitarray.bits[bsize]) & mask) != 0)
return false;
}
return true;
}
/* ========================================================================= */
BitArray& BitArray::bitwiseOr
(const BitArray& bitarray, const unsigned long int bit_count)
/* ----------------------------------------------------------------------------
*
* Description: Compute the bitwise disjunction of the first `bit_count' bits
* of two BitArrays (storing the result in `this' BitArray).
*
* Arguments: bitarray -- A reference to a constant BitArray.
* bit_count -- Number of bits to include in the computation.
*
* Returns: A reference to `this' BitArray.
*
* ------------------------------------------------------------------------- */
{
unsigned long int bsize = bit_count >> 3;
for (unsigned long int i = 0; i < bsize; ++i)
bits[i] |= bitarray.bits[i];
if ((bit_count & 0x07) != 0)
bits[bsize] |= (bitarray.bits[bsize] & ((1 << (bit_count & 7)) - 1));
return *this;
}
/* ========================================================================= */
BitArray& BitArray::bitwiseAnd
(const BitArray& bitarray, const unsigned long int bit_count)
/* ----------------------------------------------------------------------------
*
* Description: Compute the bitwise conjunction of the first `bit_count' bits
* of two BitArrays (storing the result in `this' BitArray).
*
* Arguments: bitarray -- A reference to a constant BitArray.
* bit_count -- Number of bits to include in the computation.
*
* Returns: A reference to `this' BitArray.
*
* ------------------------------------------------------------------------- */
{
unsigned long int bsize = bit_count >> 3;
for (unsigned long int i = 0; i < bsize; ++i)
bits[i] &= bitarray.bits[i];
if ((bit_count & 0x07) != 0)
bits[bsize] &= (bitarray.bits[bsize] | ~((1 << (bit_count & 7)) - 1));
return *this;
}
/* ========================================================================= */
BitArray& BitArray::bitwiseXor
(const BitArray& bitarray, const unsigned long int bit_count)
/* ----------------------------------------------------------------------------
*
* Description: Compute the bitwise "exclusive or" of the first `bit_count'
* bits of two BitArrays (storing the result in `this'
* BitArray).
*
* Arguments: bitarray -- A reference to a constant BitArray.
* bit_count -- Number of bits to include in the computation.
*
* Returns: A reference to `this' BitArray.
*
* ------------------------------------------------------------------------- */
{
unsigned long int bsize = bit_count >> 3;
for (unsigned long int i = 0; i < bsize; ++i)
bits[i] ^= bitarray.bits[i];
if ((bit_count & 0x07) != 0)
bits[bsize] ^= (bitarray.bits[bsize] & ((1 << (bit_count & 7)) - 1));
return *this;
}
/* ========================================================================= */
bool BitArray::subset
(const BitArray& bitarray, const unsigned long int bit_count) const
/* ----------------------------------------------------------------------------
*
* Description: Tests whether the first `bit_count' bits of `this' BitArray
* are set also in `bitarray'.
*
* Argument bitarray -- Target of the comparison.
* bit_count -- Number of bits to test.
*
* Returns: Truth value depending on the result of the test.
*
* ------------------------------------------------------------------------- */
{
if (bit_count > 0)
{
unsigned long int bsize = bit_count >> 3;
for (unsigned long int i = 0; i < bsize; ++i)
{
if ((bits[i] & ~bitarray.bits[i]) != 0)
return false;
}
if ((bit_count & 0x07) == 0)
return true;
unsigned char mask = (1 << (bit_count & 7)) - 1;
if (((bits[bsize] & ~bitarray.bits[bsize]) & mask) != 0)
return false;
}
return true;
}
/* ========================================================================= */
unsigned long int BitArray::count(const unsigned long int bit_count) const
/* ----------------------------------------------------------------------------
*
* Description: Counts the number of 1-bits in the first `bit_count' bits of
* the BitArray.
*
* Arguments: bit_count -- Number of bits to include in the computation.
*
* Returns: Number of 1-bits in the first `bit_count' bits of the
* BitArray.
*
* ------------------------------------------------------------------------- */
{
if (bit_count == 0)
return 0;
unsigned long int bsize = bit_count >> 3;
unsigned long int result = 0;
for (unsigned long int i = 0; i < bsize; ++i)
result += bit_counts[bits[i]];
if ((bit_count & 0x07) == 0)
return result;
unsigned char mask = (1 << (bit_count & 7)) - 1;
result += bit_counts[bits[bsize] & mask];
return result;
}
/* ========================================================================= */
unsigned long int BitArray::hammingDistance
(const BitArray& bitarray, const unsigned long int bit_count) const
/* ----------------------------------------------------------------------------
*
* Description: Computes the Hamming distance (the number of bit positions in
* which two bit vectors differ) between two bit vectors
* comprising the first `bit_count' bits of two bit arrays.
*
* Argument: bitarray -- A reference to a constant BitArray.
* bit_count -- Number of bits to include in the computation.
*
* Returns: The Hamming distance between the leftmost `bit_count' bits of
* two BitArrays.
*
* ------------------------------------------------------------------------- */
{
unsigned long int result = 0;
unsigned long int bsize = bit_count >> 3;
for (unsigned long int i = 0; i < bsize; ++i)
result += bit_counts[bits[i] ^ bitarray.bits[i]];
if ((bit_count & 0x07) == 0)
return result;
unsigned char mask = (1 << (bit_count & 7)) - 1;
result += bit_counts[(bits[bsize] ^ bitarray.bits[bsize]) & mask];
return result;
}
/* ========================================================================= */
void BitArray::flip(const unsigned long int bit_count)
/* ----------------------------------------------------------------------------
*
* Description: Changes the state of the first `bit_count' bits in the
* bit array.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
unsigned long bsize = (bit_count + 7) >> 3;
for (unsigned long int i = 0; i < bsize; ++i)
bits[i] ^= 0xFF;
}
/* ========================================================================= */
unsigned long int BitArray::find(const unsigned long int max_count) const
/* ----------------------------------------------------------------------------
*
* Description: Finds the first 1-bit in the bit array with an index less
* than `max_count'.
*
* Arguments: max_count -- Upper bound for the bit index.
*
* Returns: Index of the first 1-bit with an index less than `max_count'
* or `max_count' if there are no 1-bits with such an index in
* the array.
*
* ------------------------------------------------------------------------- */
{
unsigned long int bsize = (max_count + 7) >> 3;
unsigned long int i;
for (i = 0; i < bsize && bits[i] == 0; ++i)
;
if (i == bsize)
return max_count;
unsigned char c = bits[i];
i <<= 3;
while ((c & 0x01) == 0 && i < max_count)
{
c >>= 1;
++i;
}
return i;
}
/* ========================================================================= */
string BitArray::toString(const unsigned long int bit_count) const
/* ----------------------------------------------------------------------------
*
* Description: Converts the first `bit_count' bits of the bit array to a
* string (a sequence of characters `0' and `1'). The leftmost
* bit in the string corresponds to the first bit in the array.
*
* Arguments: bit_count -- Number of bits to convert into a string.
*
* Returns: String representation of the first `bit_count' bits of the
* bit array.
*
* ------------------------------------------------------------------------- */
{
#ifdef HAVE_SSTREAM
ostringstream bitstring;
print(bit_count, bitstring);
return bitstring.str();
#else
ostrstream bitstring;
print(bit_count, bitstring);
bitstring << ends;
string result(bitstring.str());
bitstring.freeze(0);
return result;
#endif /* HAVE_SSTREAM */
}
/* ========================================================================= */
void BitArray::print(const unsigned long int bit_count, ostream& stream) const
/* ----------------------------------------------------------------------------
*
* Description: Prints the first `bit_count' bits of the bit array as a
* sequence of characters `0' and `1'. The bits are printed in
* the same order as they are in the array; thus, the first
* printed bit corresponds to the bit with the lowest index in
* the array.
*
* Arguments: bit_count -- Number of bits to print.
* stream -- A reference to the output stream.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
unsigned long int i, j, bsize = (bit_count + 7) >> 3;
unsigned short int maskbit;
Exceptional_ostream estream(&stream, ios::failbit | ios::badbit);
j = 0;
for (i = 0; i < bsize; ++i)
{
maskbit = 1;
while (j < bit_count && maskbit <= 0x80)
{
estream << ((bits[i] & maskbit) ? '1' : '0');
++j;
maskbit <<= 1;
}
}
}

View file

@ -1,432 +0,0 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* 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 BITARRAY_H
#define BITARRAY_H
#include <config.h>
#include <cstring>
#include <string>
#include <iostream>
using namespace std;
class Bitset;
/******************************************************************************
*
* A class for arrays of bits.
*
*****************************************************************************/
class BitArray
{
public:
explicit BitArray /* Constructor. */
(const unsigned long int size = 0);
~BitArray(); /* Destructor. */
private:
BitArray(const BitArray& bitarray); /* Prevent copying and */
BitArray& operator=(const BitArray& bitarray); /* assignment of
* BitArray objects.
* (Copying and
* assignment requires
* information about
* the number of bits in
* the bit array; this
* information is not
* included in the
* object itself.)
*/
public:
bool operator[](const unsigned long int index) /* Tell the value of a */
const; /* bit in a given array */
bool test(const unsigned long int index) const; /* index.
*/
void copy /* Duplicate a bit */
(const BitArray& bitarray, /* array. */
const unsigned long int bit_count);
void copy(const Bitset& bitset); /* Copy bits from a */
BitArray& operator=(const Bitset& bitset); /* Bitset. */
bool equal /* Test whether the */
(const BitArray& bitarray, /* first `bit_count' */
const unsigned long int bit_count) const; /* bits of two BitArrays
* are equal.
*/
bool equal(const Bitset& bitset) const; /* Compare a BitArray to */
bool operator==(const Bitset& bitset) const; /* a Bitset. */
BitArray& bitwiseOr /* Compute the bitwise */
(const BitArray& bitarray, /* disjunction of the */
const unsigned long int bit_count); /* first `bit_count'
* bits of two
* BitArrays.
*/
BitArray& bitwiseAnd /* Compute the bitwise */
(const BitArray& bitarray, /* conjunction of the */
const unsigned long int bit_count); /* first `bit_count'
* bits of two
* BitArrays.
*/
BitArray& bitwiseXor /* Compute the bitwise */
(const BitArray& bitarray, /* "exclusive or" of the */
const unsigned long int bit_count); /* first `bit_count'
* bits of two
* BitArrays.
*/
bool subset /* Test whether the */
(const BitArray& bitarray, /* first `bit_count' */
const unsigned long int bit_count) const; /* bits of `this'
* BitArray are included
* in another BitArray.
*/
bool subset(const Bitset& bitset) const; /* Test for inclusion */
bool operator<=(const Bitset& bitset) const; /* into a Bitset. */
unsigned long int count /* Compute the number of */
(const unsigned long int bit_count) const; /* 1-bits in the first
* `bit_count' bits of
* the BitArray.
*/
unsigned long int hammingDistance /* Compute the Hamming */
(const BitArray& bitarray, /* distance between two */
const unsigned long int bit_count) const; /* bit vectors
* consisting of the
* first `bit_count'
* bits of two
* BitArrays.
*/
unsigned long int hammingDistance /* Compute the Hamming */
(const Bitset& bitset) const; /* distance between a
* BitArray and a
* Bitset.
*/
void set(const unsigned long int bit_count); /* Set a given number of
* bits in the bit array.
*/
void setBit(const unsigned long int index); /* Set a single bit in the
* bit array.
*/
void clear(const unsigned long int bit_count); /* Clear the first
* `bit_count' bits in the
* bit array.
*/
void clearBit(const unsigned long int index); /* Clear a single bit in
* the bit array.
*/
void flip(const unsigned long int bit_count); /* Flip the first
* `bit_count' bits in the
* bit array.
*/
void flipBit(const unsigned long int index); /* Flip a single bit in the
* bit array.
*/
unsigned long int find /* Return the index of */
(const unsigned long int max_count) const; /* the first 1-bit in
* the bit array with a
* bit index less than
* `max_count'.
*/
void print /* Print the first */
(const unsigned long int bit_count, /* `bit_count' bits of */
ostream& stream = cout) const; /* the bit array. */
string toString /* Convert a prefix of */
(const unsigned long int bit_count) const; /* a BitArray into a
* string of 0's and
* 1's.
*/
private:
unsigned char* bits; /* Storage for the bits. */
static const unsigned char bit_counts[]; /* `bit_counts[i]' gives
* the number of bits in
* the 8-bit integer `i'.
* (Used by the member
* function `count'.)
*/
friend class Bitset;
};
#include "Bitset.h"
/******************************************************************************
*
* Inline function definitions for class BitArray.
*
*****************************************************************************/
/* ========================================================================= */
inline bool BitArray::operator[](const unsigned long int index) const
/* ----------------------------------------------------------------------------
*
* Description: Tells the state of a bit in a bit array.
*
* Argument: index -- Index of the bit to test.
*
* Returns: State of the bit in the bit array.
*
* ------------------------------------------------------------------------- */
{
return ((bits[index >> 3] & (1 << (index & 7))) != 0);
}
/* ========================================================================= */
inline void BitArray::copy(const Bitset& bitset)
/* ----------------------------------------------------------------------------
*
* Description: Initializes the BitArray with bits in a Bitset.
*
* Argument: bitset -- Bitset to copy.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
return copy(bitset, bitset.capacity());
}
/* ========================================================================= */
inline BitArray& BitArray::operator=(const Bitset& bitset)
/* ----------------------------------------------------------------------------
*
* Description: Initializes the BitArray with bits in a Bitset.
*
* Argument: bitset -- Bitset to copy.
*
* Returns: A reference to `this' BitArray.
*
* ------------------------------------------------------------------------- */
{
copy(bitset, bitset.capacity());
return *this;
}
/* ========================================================================= */
inline bool BitArray::equal(const Bitset& bitset) const
/* ----------------------------------------------------------------------------
*
* Description: Compares the `bitset.capacity()' first bits of the BitArray
* to `bitset'. The BitArray is assumed to be at least as large
* as the Bitset.
*
* Argument: bitset -- Target of the comparison.
*
* Returns: Truth value based on the result of the test.
*
* ------------------------------------------------------------------------- */
{
return equal(bitset, bitset.capacity());
}
/* ========================================================================= */
inline bool BitArray::operator==(const Bitset& bitset) const
/* ----------------------------------------------------------------------------
*
* Description: Compares the `bitset.capacity()' first bits of the BitArray
* to `bitset'. The BitArray is assumed to be at least as large
* as the Bitset.
*
* Argument: bitset -- Target of the comparison.
*
* Returns: Truth value according to the result of the test.
*
* ------------------------------------------------------------------------- */
{
return equal(bitset, bitset.capacity());
}
/* ========================================================================= */
inline bool BitArray::subset(const Bitset& bitset) const
/* ----------------------------------------------------------------------------
*
* Description: Tests whether all of the first `bitset.capacity()' bits of
* the BitArray are included in `bitset'. The BitArray should
* be at least as large as the Bitset.
*
* Argument: bitset -- Target of the comparison.
*
* Returns: Truth value according to the result of the test.
*
* ------------------------------------------------------------------------- */
{
return subset(bitset, bitset.capacity());
}
/* ========================================================================= */
inline bool BitArray::operator<=(const Bitset& bitset) const
/* ----------------------------------------------------------------------------
*
* Description: Tests whether all of the first `bitset.capacity()' bits of
* the BitArray are included in `bitset'. The BitArray should be
* at least as large as the Bitset.
*
* Argument: bitset -- Target of the comparison.
*
* Returns: Truth value according to the result of the test.
*
* ------------------------------------------------------------------------- */
{
return subset(bitset, bitset.capacity());
}
/* ========================================================================= */
inline unsigned long int BitArray::hammingDistance(const Bitset& bitset) const
/* ----------------------------------------------------------------------------
*
* Description: Computer the Hamming distance (number of differing bits)
* between the first `bitset.capacity()' bits of `bitset' and
* the BitArray.
*
* Argument: bitset -- Target of the computation.
*
* Returns: The Hamming distance between `bitset' and the BitArray.
*
* ------------------------------------------------------------------------- */
{
return hammingDistance(bitset, bitset.capacity());
}
/* ========================================================================= */
inline bool BitArray::test(const unsigned long int index) const
/* ----------------------------------------------------------------------------
*
* Description: Tells the state of a bit in a bit array.
*
* Argument: index -- Index of bit to test.
*
* Returns: Truth value according to the state of the bit.
*
* ------------------------------------------------------------------------- */
{
return operator[](index);
}
/* ========================================================================= */
inline void BitArray::set(const unsigned long int bit_count)
/* ----------------------------------------------------------------------------
*
* Description: Fills the first `bit_count' bits of the bit array with
* 1-bits.
*
* Arguments: bit_count -- Number of bits to set to 1.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
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;
}
/* ========================================================================= */
inline void BitArray::setBit(const unsigned long int index)
/* ----------------------------------------------------------------------------
*
* Description: Sets a single bit in the bit array.
*
* Argument: index -- Index of the bit to be set.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
bits[index >> 3] |= 1 << (index & 7);
}
/* ========================================================================= */
inline void BitArray::clear(const unsigned long int bit_count)
/* ----------------------------------------------------------------------------
*
* Description: Fills the first `bit_count' bits of the bit array with
* 0-bits.
*
* Arguments: bit_count -- Number of bits to set to 0.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
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);
}
/* ========================================================================= */
inline void BitArray::clearBit(const unsigned long int index)
/* ----------------------------------------------------------------------------
*
* Description: Clears a single bit in the bit array.
*
* Argument: index -- Index of the bit to be cleared.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
bits[index >> 3] &= ~(1 << (index & 7));
}
/* ========================================================================= */
inline void BitArray::flipBit(const unsigned long int index)
/* ----------------------------------------------------------------------------
*
* Description: Switches the state of a single bit in the bit array.
*
* Arguments: index -- Index of the bit.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
bits[index >> 3] ^= (1 << (index & 7));
}
#endif /* !BITARRAY_H */

View file

@ -1,626 +0,0 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* 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 BITSET_H
#define BITSET_H
#include <config.h>
#include <string>
#include <iostream>
#include "Exception.h"
using namespace std;
/******************************************************************************
*
* A class for sets of bits.
*
*****************************************************************************/
class Bitset
{
public:
explicit Bitset /* Creates an empty bit */
(const unsigned long int capacity = 0); /* set. */
explicit Bitset /* Creates a bit set */
(const BitArray& bitarray, /* from a bit array. */
const unsigned long int capacity);
Bitset(const Bitset& bitset); /* Copy constructor. */
~Bitset(); /* Destructor. */
operator const BitArray&() const; /* A Bitset can always be
* cast into a constant
* BitArray.
*/
Bitset& operator=(const Bitset& bitset); /* Assignment operator. */
bool operator[](const unsigned long int index) /* Tell the value of a */
const; /* bit in a given index. */
bool test(const unsigned long int index) const;
bool operator==(const Bitset& bitset) const; /* Test whether two */
bool equal(const Bitset& bitset) const; /* Bitsets are equal. */
bool operator<=(const Bitset& bitset) const; /* Test whether `this' */
bool subset(const Bitset& bitset) const; /* Bitset is a subset
* of another Bitset.
*/
unsigned long int capacity() const; /* Tells the capacity of
* the bit set.
*/
unsigned long int count() const; /* Compute the number of
* 1-bits in the Bitset.
*/
unsigned long int hammingDistance /* Compute the Hamming */
(const Bitset& bitset) const; /* distance between two
* Bitsets.
*/
void set(); /* Set all bits in the bit
* set.
*/
void setBit(const unsigned long int index); /* Set a single bit in the
* bit set.
*/
void clear(); /* Clear all bits in the
* bit set.
*/
void clearBit(const unsigned long int index); /* Clear a single bit in
* the bit set.
*/
void flip(); /* Flip all bits in the
* bit set.
*/
void flipBit(const unsigned long int index); /* Flip a single bit in the
* bit set.
*/
unsigned long int find() const; /* Return the index of the
* first 1-bit in the bit
* set.
*/
void print(ostream& stream = cout) const; /* Print the bit set. */
string toString() const; /* Convert the Bitset into
* a string if 0's and 1's.
*/
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
class BitIndexException; /* An exception class for
* reporting indexing
* errors.
*/
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
private:
unsigned long int number_of_bits; /* Capacity of the bit
* set.
*/
BitArray bits; /* Storage for the bits. */
};
/******************************************************************************
*
* An exception class for reporting bitset indexing errors.
*
*****************************************************************************/
class Bitset::BitIndexException : public Exception
{
public:
BitIndexException(); /* Constructor. */
/* default copy constructor */
~BitIndexException() throw(); /* Destructor. */
BitIndexException& /* Assignment operator. */
operator=(const BitIndexException& e);
/* `what' inherited from class Exception */
};
/******************************************************************************
*
* Inline function definitions for class Bitset.
*
*****************************************************************************/
/* ========================================================================= */
inline Bitset::Bitset(const unsigned long int capacity) :
number_of_bits(capacity), bits(capacity)
/* ----------------------------------------------------------------------------
*
* Description: Constructor for class Bitset.
*
* Argument: capacity -- Number of bits to allocate.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
inline Bitset::Bitset
(const BitArray& bitarray, const unsigned long int capacity) :
number_of_bits(capacity), bits(capacity)
/* ----------------------------------------------------------------------------
*
* Description: Constructor for class Bitset. Creates a Bitset from the
* first `capacity' bits of a BitArray.
*
* Arguments: bitarray -- A reference to a constant BitArray.
* capacity -- Capacity of the new bit set.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
memcpy(static_cast<void*>(bits.bits),
static_cast<const void*>(bitarray.bits),
(capacity + 7) >> 3);
}
/* ========================================================================= */
inline Bitset::Bitset(const Bitset& bitset) :
number_of_bits(bitset.number_of_bits), bits(bitset.number_of_bits)
/* ----------------------------------------------------------------------------
*
* Description: Copy constructor for class Bitset.
*
* Argument: bitset -- Bitset to be copied.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
memcpy(static_cast<void*>(bits.bits),
static_cast<const void*>(bitset.bits.bits),
(number_of_bits + 7) >> 3);
}
/* ========================================================================= */
inline Bitset::~Bitset()
/* ----------------------------------------------------------------------------
*
* Description: Destructor for class Bitset.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
inline Bitset::operator const BitArray&() const
/* ----------------------------------------------------------------------------
*
* Description: Converts a Bitset into a BitArray.
*
* Arguments: None.
*
* Returns: The bits associated with the Bitset object as a reference to
* a constant BitArray.
*
* ------------------------------------------------------------------------- */
{
return bits;
}
/* ========================================================================= */
inline Bitset& Bitset::operator=(const Bitset& bitset)
/* ----------------------------------------------------------------------------
*
* Description: Assignment operator for class Bitset.
*
* Arguments: bitset -- A reference to a Bitset to be assigned to `this'
* Bitset.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
if (&bitset != this)
{
if ((number_of_bits >> 3) != (bitset.number_of_bits >> 3))
bits.copy(bitset.bits, number_of_bits);
else
memcpy(static_cast<void*>(bits.bits),
static_cast<const void*>(bitset.bits.bits),
(bitset.number_of_bits + 7) >> 3);
number_of_bits = bitset.number_of_bits;
}
return *this;
}
/* ========================================================================= */
inline bool Bitset::operator[](const unsigned long int index) const
/* ----------------------------------------------------------------------------
*
* Description: Tells the state of a bit in a bit set.
*
* Argument: index -- Index of the bit to test.
*
* Returns: Truth value according to the state of the bit.
*
* ------------------------------------------------------------------------- */
{
if (index >= number_of_bits)
throw BitIndexException();
return bits[index];
}
/* ========================================================================= */
inline bool Bitset::test(const unsigned long int index) const
/* ----------------------------------------------------------------------------
*
* Description: Tells the state of a bit in a bit set.
*
* Argument: index -- Index of bit to test.
*
* Returns: Truth value according to the state of the bit.
*
* ------------------------------------------------------------------------- */
{
return operator[](index);
}
/* ========================================================================= */
inline bool Bitset::operator==(const Bitset& bitset) const
/* ----------------------------------------------------------------------------
*
* Description: Compares two bitsets for equality.
*
* Argument: bitset -- Target of the comparison.
*
* Returns: `true' if the bit sets have the same capacity and contents.
*
* ------------------------------------------------------------------------- */
{
return (number_of_bits == bitset.number_of_bits
&& bits.equal(bitset.bits, number_of_bits));
}
/* ========================================================================= */
inline bool Bitset::equal(const Bitset& bitset) const
/* ----------------------------------------------------------------------------
*
* Description: Compares two bitsets for equality.
*
* Argument: bitset -- Target of the comparison.
*
* Returns: `true' if the bit sets have the same capacity and contents.
*
* ------------------------------------------------------------------------- */
{
return operator==(bitset);
}
/* ========================================================================= */
inline bool Bitset::operator<=(const Bitset& bitset) const
/* ----------------------------------------------------------------------------
*
* Description: Tests whether `this' bitset is a subset of another Bitset.
*
* Argument: bitset -- Target of the comparison.
*
* Returns: `true' if the capacity of `this' bitset is at most equal to
* the capacity of the target bitset and all bits set in `this'
* Bitset are also set in the other set.
*
* ------------------------------------------------------------------------- */
{
return (number_of_bits <= bitset.number_of_bits
&& bits.subset(bitset.bits, number_of_bits));
}
/* ========================================================================= */
inline bool Bitset::subset(const Bitset& bitset) const
/* ----------------------------------------------------------------------------
*
* Description: Tests whether `this' bitset is a subset of another Bitset.
*
* Argument: bitset -- Target of the comparison.
*
* Returns: `true' if the capacity of `this' bitset is at most equal to
* the capacity of the target bitset and all bits set in `this'
* Bitset are also set in the other set.
*
* ------------------------------------------------------------------------- */
{
return operator<=(bitset);
}
/* ========================================================================= */
inline unsigned long int Bitset::capacity() const
/* ----------------------------------------------------------------------------
*
* Description: Tells the capacity of the bit set.
*
* Arguments: None.
*
* Returns: Capacity of the bit set.
*
* ------------------------------------------------------------------------- */
{
return number_of_bits;
}
/* ========================================================================= */
inline unsigned long int Bitset::count() const
/* ----------------------------------------------------------------------------
*
* Description: Computes the number of 1-bits in the Bitset.
*
* Arguments: None.
*
* Returns: Number of 1-bits in the Bitset.
*
* ------------------------------------------------------------------------- */
{
return bits.count(number_of_bits);
}
/* ========================================================================= */
inline unsigned long int Bitset::hammingDistance(const Bitset& bitset) const
/* ----------------------------------------------------------------------------
*
* Description: Computes the Hamming distance between two Bitsets (or between
* maximal prefixes of both Bitsets if the sets are of
* different capacity).
*
* Argument: bitset -- A reference to a constant Bitset.
*
* Returns: The Hamming distance between the bitsets (or their maximal
* prefixes of equal length).
*
* ------------------------------------------------------------------------- */
{
return bits.hammingDistance(bitset.bits,
number_of_bits <= bitset.number_of_bits
? number_of_bits
: bitset.number_of_bits);
}
/* ========================================================================= */
inline void Bitset::set()
/* ----------------------------------------------------------------------------
*
* Description: Fills the bit set with 1-bits.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
bits.set(number_of_bits);
}
/* ========================================================================= */
inline void Bitset::setBit(const unsigned long int index)
/* ----------------------------------------------------------------------------
*
* Description: Sets a single bit in the bit set.
*
* Argument: index -- Index of the bit to be set.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
if (index >= number_of_bits)
throw BitIndexException();
bits.setBit(index);
}
/* ========================================================================= */
inline void Bitset::clear()
/* ----------------------------------------------------------------------------
*
* Description: Fills the bit set with 0-bits.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
bits.clear(number_of_bits);
}
/* ========================================================================= */
inline void Bitset::clearBit(const unsigned long int index)
/* ----------------------------------------------------------------------------
*
* Description: Clears a single bit in the bit set.
*
* Argument: index -- Index of the bit to be cleared.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
if (index >= number_of_bits)
throw BitIndexException();
bits.clearBit(index);
}
/* ========================================================================= */
inline void Bitset::flip()
/* ----------------------------------------------------------------------------
*
* Description: Flips all bits in the bit set.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
bits.flip(number_of_bits);
}
/* ========================================================================= */
inline void Bitset::flipBit(const unsigned long int index)
/* ----------------------------------------------------------------------------
*
* Description: Switches the state of a single bit in the bit set.
*
* Arguments: index -- Index of the bit.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
if (index >= number_of_bits)
throw BitIndexException();
bits.flipBit(index);
}
/* ========================================================================= */
inline unsigned long int Bitset::find() const
/* ----------------------------------------------------------------------------
*
* Description: Finds the index of the first 1-bit in the bit set.
*
* Arguments: None.
*
* Returns: Index of the first 1-bit in the bit set (or
* `this->number_of_bits' if the bit set is empty).
*
* ------------------------------------------------------------------------- */
{
return bits.find(number_of_bits);
}
/* ========================================================================= */
inline void Bitset::print(ostream& stream) const
/* ----------------------------------------------------------------------------
*
* Description: Writes the Bitset into a stream.
*
* Argument: stream -- A reference to an output stream.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
bits.print(number_of_bits, stream);
}
/* ========================================================================= */
inline string Bitset::toString() const
/* ----------------------------------------------------------------------------
*
* Description: Converts the Bitset into a string.
*
* Arguments: None.
*
* Returns: A string representation of the Bitset.
*
* ------------------------------------------------------------------------- */
{
return bits.toString(number_of_bits);
}
/******************************************************************************
*
* Inline function definitions for class Bitset::BitIndexException.
*
*****************************************************************************/
/* ========================================================================= */
inline Bitset::BitIndexException::BitIndexException() :
Exception("Index out of range.")
/* ----------------------------------------------------------------------------
*
* Description: Constructor for class Bitset::BitIndexException. Creates a
* new exception object.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
inline Bitset::BitIndexException::~BitIndexException() throw()
/* ----------------------------------------------------------------------------
*
* Description: Destructor for class Bitset::BitIndexException.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
inline Bitset::BitIndexException& Bitset::BitIndexException::operator=
(const Bitset::BitIndexException& e)
/* ----------------------------------------------------------------------------
*
* Description: Assignment operator for class Bitset::BitIndexException.
*
* Arguments: e -- A reference to another Bitset::BitIndexException.
*
* Returns: A reference to the assigned exception object.
*
* ------------------------------------------------------------------------- */
{
Exception::operator=(e);
return *this;
}
#endif /* !BITSET_H */

View file

@ -1,880 +0,0 @@
/* -*- coding: utf-8 -*-
*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* 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.
*/
#include <config.h>
#include <deque>
#include <stack>
#include <utility>
#include <vector>
#include "BuchiAutomaton.h"
#include "StringUtil.h"
namespace Graph
{
/******************************************************************************
*
* Function definitions for class BuchiAutomaton.
*
*****************************************************************************/
/* ========================================================================= */
BuchiAutomaton::BuchiAutomaton
(const size_type initial_number_of_states, const size_type initstate,
const unsigned long int number_of_accept_sets) :
initial_state(initstate), number_of_acceptance_sets(number_of_accept_sets)
/* ----------------------------------------------------------------------------
*
* Description: Constructor for class BuchiAutomaton. Initializes an
* automaton with a given number of states and a given
* initial state.
*
* Arguments: initial_number_of_states -- Initial size of the automaton
* (can be grown later).
* initstate -- Index of the automaton's
* initial state.
* number_of_accept_sets -- Number of acceptance sets in
* the automaton.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
if (initstate >= initial_number_of_states
&& !(initial_number_of_states == 0 && initstate == 0))
throw NodeIndexException();
nodes.reserve(initial_number_of_states);
for (size_type i = 0; i < initial_number_of_states; ++i)
nodes.push_back(new BuchiState(number_of_accept_sets));
}
/* ========================================================================= */
BuchiAutomaton::BuchiAutomaton(const BuchiAutomaton& automaton) :
Graph<GraphEdgeContainer>(),
initial_state(automaton.initial_state),
number_of_acceptance_sets(automaton.number_of_acceptance_sets)
/* ----------------------------------------------------------------------------
*
* Description: Copy constructor for class BuchiAutomaton. Creates a copy of
* a BuchiAutomaton object.
*
* Argument: automaton -- Automaton to be copied.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
expand(automaton.size());
for (size_type state = 0; state < size(); ++state)
{
for (GraphEdgeContainer::const_iterator transition
= automaton[state].edges().begin();
transition != automaton[state].edges().end();
++transition)
connect(state,
static_cast<const BuchiTransition*>(*transition)->targetNode(),
static_cast<const BuchiTransition*>(*transition)->guard(),
static_cast<const BuchiTransition*>(*transition)
->acceptanceSets());
operator[](state).acceptanceSets().copy(automaton[state].acceptanceSets(),
number_of_acceptance_sets);
}
}
/* ========================================================================= */
BuchiAutomaton& BuchiAutomaton::operator=(const BuchiAutomaton& automaton)
/* ----------------------------------------------------------------------------
*
* Description: Assignment operator for class BuchiAutomaton. Assigns the
* contents of a BuchiAutomaton to another one.
*
* Argument: automaton -- A constant reference to a BuchiAutomaton whose
* contents are to be copied.
*
* Returns: A reference to the BuchiAutomaton assigned to.
*
* ------------------------------------------------------------------------- */
{
if (&automaton != this)
{
initial_state = automaton.initial_state;
number_of_acceptance_sets = automaton.number_of_acceptance_sets;
clear();
expand(automaton.size());
for (size_type state = 0; state < size(); ++state)
{
for (GraphEdgeContainer::const_iterator transition
= automaton[state].edges().begin();
transition != automaton[state].edges().end();
++transition)
connect(state,
static_cast<const BuchiTransition*>(*transition)->targetNode(),
static_cast<const BuchiTransition*>(*transition)->guard(),
static_cast<const BuchiTransition*>(*transition)
->acceptanceSets());
operator[](state).acceptanceSets().copy
(automaton[state].acceptanceSets(), number_of_acceptance_sets);
}
}
return *this;
}
/* ========================================================================= */
void BuchiAutomaton::clear()
/* ----------------------------------------------------------------------------
*
* Description: Makes the automaton empty.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
Graph<GraphEdgeContainer>::clear();
initial_state = 0;
number_of_acceptance_sets = 0;
}
/* ========================================================================= */
BuchiAutomaton::size_type BuchiAutomaton::expand(size_type node_count)
/* ----------------------------------------------------------------------------
*
* Description: Inserts a given number of states to a BuchiAutomaton.
*
* Argument: node_count -- Number of states to be inserted.
*
* Returns: The index of the last inserted state.
*
* ------------------------------------------------------------------------- */
{
nodes.reserve(nodes.size() + node_count);
BuchiState* new_buchi_state;
while (node_count > 0)
{
new_buchi_state = new BuchiState(number_of_acceptance_sets);
try
{
nodes.push_back(new_buchi_state);
}
catch (...)
{
delete new_buchi_state;
throw;
}
node_count--;
}
return nodes.size() - 1;
}
/* ========================================================================= */
void BuchiAutomaton::read(istream& input_stream)
/* ----------------------------------------------------------------------------
*
* Description: Reads an automaton description (which may represent a
* generalized Büchi automaton) from a stream and stores it
* into the automaton object.
*
* Argument: input_stream -- A reference to an input stream.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
size_type number_of_states, current_state, neighbor_state;
unsigned long int acceptance_set;
Exceptional_istream einput_stream(&input_stream, ios::failbit | ios::badbit);
clear();
try
{
/* Read the number of states in the generalized Büchi automaton. */
einput_stream >> number_of_states;
/* If the automaton is empty, do nothing. */
if (number_of_states == 0)
return;
/*
* 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
* from the generalized Büchi automaton.
*/
nodes.reserve(number_of_states);
for (size_type i = 0; i < number_of_states; ++i)
nodes.push_back(new BuchiState(number_of_acceptance_sets));
/*
* The automaton state numbers will be mapped from input file identifiers
* to the interval [0...(number of states - 1)].
*/
map<long int, size_type> state_number_map;
pair<long int, size_type> state_mapping(0, 0);
pair<map<long int, size_type>::const_iterator, bool> state_finder;
/*
* Also the acceptance set numbers will be mapped to the interval
* [0...(number of acceptance sets - 1)].
*/
map<long int, unsigned long int> acceptance_set_map;
pair<long int, unsigned long int> acceptance_set_mapping(0, 0);
pair<map<long int, unsigned long int>::const_iterator, bool>
acceptance_set_finder;
/*
* A bit array is used to keep information about states which have been
* processed. (This is used to verify that each state is defined exactly
* once in the input.)
*/
BitArray processed_states(number_of_states);
processed_states.clear(number_of_states);
unsigned long int number_of_processed_states = 0;
bool initial_state_fixed = false; /* will be set to true after */
/* processing the initial state */
/* of the automaton */
int is_initial;
::Ltl::LtlFormula* guard;
for (size_type i = 0; i < number_of_states; ++i)
{
/*
* Begin processing a new state by reading a state id from the stream.
*/
einput_stream >> state_mapping.first;
/*
* Try to insert a new state mapping into the state identifier map.
* If an insertion actually occurs (there is no element in the map with
* key equal to `state_mapping.first'), increment the state counter. In
* any case, set the value of `current_state' to the map value.
* (Note: It is an error to redefine a state that has already been
* processed.)
*/
state_finder = state_number_map.insert(state_mapping);
if (!state_finder.second) /* no insertion occurred */
{
current_state = (state_finder.first)->second;
if (processed_states[current_state])
throw AutomatonParseException("state redefinition encountered");
}
else
{
if (state_mapping.second >= number_of_states)
throw AutomatonParseException("number of different state "
"identifiers does not match the size"
" of the Büchi automaton");
current_state = state_mapping.second;
state_mapping.second++;
}
/*
* Check whether the current state is an initial state. (There must be
* exactly one initial state.)
*/
einput_stream >> is_initial;
if (is_initial != 0)
{
if (!initial_state_fixed)
{
initial_state = current_state;
initial_state_fixed = true;
}
else
throw AutomatonParseException("multiple initial state definitions");
}
/*
* Determine which acceptance sets the current state belongs to.
* The numbers of the acceptance sets are mapped to the proper
* interval, again by introducing mappings for acceptance set numbers
* whenever necessary.
*/
operator[](current_state).acceptanceSets().clear
(number_of_acceptance_sets);
if (acceptance_sets_on_states)
{
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;
}
operator[](current_state).acceptanceSets().setBit(acceptance_set);
}
}
/*
* Process the transitions from the state to other states. Read a
* target state id and add a mapping for it in the translation table if
* necessary. If the automaton is allowed to have acceptance sets
* associated with transitions, read an additional list of acceptance
* sets. Finally, read the propositional formula guarding the
* transition and connect the current state to the target using the
* guard formula.
*/
while (1)
{
einput_stream >> state_mapping.first;
if (state_mapping.first == -1)
break;
state_finder = state_number_map.insert(state_mapping);
if (!state_finder.second)
neighbor_state = (state_finder.first)->second;
else
{
if (state_mapping.second >= number_of_states)
throw AutomatonParseException("number of different state "
"identifiers does not match the size"
" of the Büchi automaton");
neighbor_state = 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
{
guard = ::Ltl::LtlFormula::read(input_stream);
}
catch (const ::Ltl::LtlFormula::ParseErrorException& e)
{
throw AutomatonParseException(e.what());
}
if (!guard->propositional())
{
::Ltl::LtlFormula::destruct(guard);
throw AutomatonParseException("illegal operators in guard formula");
}
connect(current_state, neighbor_state, guard, acc_sets);
}
processed_states.setBit(current_state);
++number_of_processed_states;
}
if (!initial_state_fixed)
throw AutomatonParseException("no initial state specified");
if (number_of_processed_states != number_of_states)
throw AutomatonParseException("incomplete automaton definition");
}
catch (const IOException& e)
{
clear();
if (input_stream.eof())
throw AutomatonParseException("unexpected end of input");
else
throw;
}
catch (...)
{
clear();
throw;
}
}
/* ========================================================================= */
void BuchiAutomaton::print
(ostream& stream, const int indent, const GraphOutputFormat fmt) const
/* ----------------------------------------------------------------------------
*
* Description: Writes information about a BuchiAutomaton 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 format of the output.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
Exceptional_ostream estream(&stream, ios::failbit | ios::badbit);
if (fmt == DOT)
estream << string(indent, ' ') + "digraph G {\n";
if (nodes.empty())
{
if (fmt == NORMAL)
estream << string(indent, ' ') + "The Büchi automaton is empty.\n";
}
else
{
if (fmt == NORMAL)
{
pair<size_type, unsigned long int> statistics = stats();
pair<size_type, unsigned long int> reachable_part_statistics
= subgraphStats(initial_state);
estream << string(indent, ' ') + "The Büchi automaton consists of\n"
+ string(indent + 4, ' ')
<< statistics.first
<< " states and\n" + string(indent + 4, ' ')
<< statistics.second
<< " transitions.\n" + string(indent, ' ')
+ "The automaton has "
<< number_of_acceptance_sets
<< " acceptance sets.\n" + string(indent, ' ')
+ "The reachable part of the automaton contains\n"
+ string(indent + 4, ' ')
<< reachable_part_statistics.first
<< " states and\n" + string(indent + 4, ' ')
<< reachable_part_statistics.second
<< " transitions.\n" + string(indent, ' ') + "Initial state: "
<< initial_state
<< '\n';
}
else if (fmt == DOT)
{
estream << string(indent, ' ') + " init [style=invis];\n"
+ string(indent, ' ') + " init->n"
<< initial_state
<< ";\n";
}
size_type s = nodes.size();
for (size_type state = 0; state < s; ++state)
{
estream << string(indent, ' ');
if (fmt == NORMAL)
{
estream << "State " << state << ":\n";
operator[](state).print(stream, indent + 4, NORMAL,
number_of_acceptance_sets);
}
else if (fmt == DOT)
{
GraphEdgeContainer::const_iterator transition;
bool first_printed = false;
estream << " n"
<< state
<< string(" [shape=circle,label=\"")
<< state
<< "\\n{";
for (unsigned long int accept_set = 0;
accept_set < number_of_acceptance_sets;
accept_set++)
{
if (operator[](state).acceptanceSets().test(accept_set))
{
if (first_printed)
estream << ',';
else
first_printed = true;
estream << accept_set;
}
}
estream << "}\",fontsize=12];\n";
for (transition = nodes[state]->edges().begin();
transition != nodes[state]->edges().end();
++transition)
{
estream << string(indent + 2, ' ') + 'n' << state;
static_cast<const BuchiTransition*>(*transition)
->print(stream, indent, fmt, number_of_acceptance_sets);
estream << ";\n";
}
}
}
}
if (fmt == DOT)
estream << string(indent, ' ') + "}\n";
estream.flush();
}
/* ========================================================================= */
bool BuchiAutomaton::BuchiState::isDeterministic() const
/* ----------------------------------------------------------------------------
*
* Description: Checks whether there is any nondeterminism
* on the outgoing transitions.
*
* Arguments: None.
*
* Returns: True iff the state is deterministic.
*
* ------------------------------------------------------------------------- */
{
size_type size = edges().size();
if (size <= 1)
return true;
for (int i = 0; i < size - 1; i++)
{
for (int j = i + 1; j < size; j++)
{
Ltl::LtlFormula *f =
&Ltl::And::construct((static_cast<BuchiTransition*> (edges()[i]))->guard(),
(static_cast<BuchiTransition*> (edges()[j]))->guard());
if (f->satisfiable())
{
Ltl::LtlFormula::destruct(f);
return false;
}
else
{
Ltl::LtlFormula::destruct(f);
}
}
}
return true;
}
/* ========================================================================= */
bool BuchiAutomaton::isDeterministic() const
/* ----------------------------------------------------------------------------
*
* Description: Checks whether the automaton is deterministic.
*
* Arguments: None.
*
* Returns: True iff the automaton is deterministic.
*
* ------------------------------------------------------------------------- */
{
unsigned long int index = 0;
vector<Node*>::const_iterator node;
for (node = nodes.begin(); node != nodes.end(); ++node)
if (!(static_cast<BuchiState*>(*node))->isDeterministic())
return false;
return true;
}
/* ========================================================================= */
unsigned long int BuchiAutomaton::nondeterminismIndex() const
/* ----------------------------------------------------------------------------
*
* Description: Computes the nondeterminism index for the automaton.
* I.e., the number for nondeterministic states.
*
* Arguments: None.
*
* Returns: Nondeterminism index.
*
* ------------------------------------------------------------------------- */
{
unsigned long int index = 0;
vector<Node*>::const_iterator node;
for (node = nodes.begin(); node != nodes.end(); ++node)
if (!(static_cast<BuchiState*>(*node))->isDeterministic())
index++;
return index;
}
/******************************************************************************
*
* Function definitions for class BuchiAutomaton::BuchiTransition.
*
*****************************************************************************/
/* ========================================================================= */
void BuchiAutomaton::BuchiTransition::print
(ostream& stream, const int indent, const GraphOutputFormat fmt,
const unsigned long int number_of_acceptance_sets) const
/* ----------------------------------------------------------------------------
*
* Description: Writes information about a transition between two states of
* a Büchi automaton.
*
* Arguments: stream -- A reference to an output
* stream.
* indent -- Number of spaces to leave to
* the left of output.
* fmt -- Determines the format of
* output.
* number_of_acceptance_sets -- Number of acceptance sets in
* the automaton to which the
* transition belongs.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
Exceptional_ostream estream(&stream, ios::failbit | ios::badbit);
if (fmt == NORMAL)
estream << string(indent, ' ') + "Transition to state "
<< targetNode()
<< " [ acc.: ";
else if (fmt == DOT)
{
string formula(StringUtil::toString(*guard_formula));
estream << " -> n" << targetNode() << " [label=\"";
for (unsigned long int i = 0; i < formula.length(); ++i)
{
if (formula[i] == '/')
{
estream << "&&";
i++;
}
else if (formula[i] == '\\')
{
estream << "||";
i++;
}
else
estream << formula[i];
}
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();
}
/******************************************************************************
*
* Function definitions for class BuchiAutomaton::BuchiState.
*
*****************************************************************************/
/* ========================================================================= */
void BuchiAutomaton::BuchiState::print
(ostream& stream, const int indent, const GraphOutputFormat fmt,
const unsigned long int number_of_acceptance_sets) const
/* ----------------------------------------------------------------------------
*
* Description: Writes information about a state of a Büchi automaton.
*
* Arguments: stream -- A reference to an output
* stream.
* indent -- Number of spaces to leave to
* the left of output.
* fmt -- Determines the output format
* of the state.
* number_of_acceptance_sets -- Number of acceptance sets in
* the automaton in which the
* state belongs.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------ */
{
if (fmt == DOT)
return;
Exceptional_ostream estream(&stream, ios::failbit | ios::badbit);
estream << string(indent, ' ') + "Member of acceptance sets {";
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 << "}\n";
if (!edges().empty())
{
GraphEdgeContainer::const_iterator edge;
for (edge = edges().begin(); edge != edges().end(); ++edge)
static_cast<const BuchiAutomaton::BuchiTransition*>(*edge)
->print(stream, indent, fmt, number_of_acceptance_sets);
} else
estream << string(indent, ' ') + "No transitions to other states.\n";
estream.flush();
}
}

View file

@ -1,925 +0,0 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* 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 BUCHIAUTOMATON_H
#define BUCHIAUTOMATON_H
#include <config.h>
#include <cstdlib>
#include <iostream>
#include <map>
#include <string>
#include "LbttAlloc.h"
#include "BitArray.h"
#include "EdgeContainer.h"
#include "Exception.h"
#include "Graph.h"
#include "LtlFormula.h"
using namespace std;
namespace Graph
{
/******************************************************************************
*
* A class for representing generalized Büchi automata.
*
*****************************************************************************/
class BuchiAutomaton : public Graph<GraphEdgeContainer>
{
public:
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
class BuchiTransition; /* A class for representing
* the transitions between
* the states of the
* automaton.
*/
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
class BuchiState : /* A class for */
public Graph<GraphEdgeContainer>::Node /* representing the */
{ /* states of the
* automaton.
*/
public:
explicit BuchiState /* Constructor. */
(const unsigned long int
num_of_acceptance_sets);
~BuchiState(); /* Destructor. */
/* `edges' inherited from Graph<GraphEdgeContainer>::Node */
BitArray& acceptanceSets(); /* Tell the acceptance */
const BitArray& acceptanceSets() const; /* status of the state. */
void print /* Writes information */
(ostream& stream, /* about the state to a */
const int indent, /* stream. */
const GraphOutputFormat fmt) const;
void print /* Writes information */
(ostream& stream, /* about the state to a */
const int indent, /* stream. */
const GraphOutputFormat fmt,
const unsigned long int
number_of_acceptance_sets)
const;
bool isDeterministic() const; /* Checks wheter there is
* any nondeterminism on
* outgoing transitions.
*/
private:
BuchiState(const BuchiState&); /* Prevent copying and */
BuchiState& operator=(const BuchiState&); /* assignment of
* BuchiState objects.
*/
BitArray acceptance_sets; /* Acceptance status of the
* state.
*/
};
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
explicit BuchiAutomaton /* Constructor. */
(const size_type initial_number_of_states = 0,
const size_type initstate = 0,
const unsigned long int
number_of_accept_sets = 0);
BuchiAutomaton(const BuchiAutomaton& automaton); /* Copy constructor. */
~BuchiAutomaton(); /* Destructor. */
BuchiAutomaton& /* Assignment operator. */
operator=(const BuchiAutomaton& automaton);
BuchiState& operator[] /* Indexing operator. No */
(const size_type index) const; /* range check is
* performed on the
* argument.
*/
BuchiState& 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.
*/
size_type expand(size_type node_count = 1); /* Inserts states to the
* automaton.
*/
void connect /* Connects two states */
(const size_type father, /* of the automaton with */
const size_type child); /* an unguarded
* transition with no
* associated acceptance
* sets.
*/
void connect /* Connects two states */
(const size_type father, const size_type child, /* of the automaton with */
::Ltl::LtlFormula& guard, /* a transition guarded */
const BitArray& acc_sets); /* by a propositional */
void connect /* formula. */
(const size_type father, const size_type child,
::Ltl::LtlFormula* guard,
const BitArray& acc_sets);
/* `disconnect' inherited from Graph<GraphEdgeContainer> */
/* `connected' inherited from Graph<GraphEdgeContainer> */
/* `stats' inherited from Graph<GraphEdgeContainer> */
/* `subgraphStats' inherited from Graph<GraphEdgeContainer> */
size_type initialState() const; /* Get or set the */
size_type& initialState(); /* initial state of the *
* automaton.
*/
unsigned long int numberOfAcceptanceSets() const; /* Returns the number of
* acceptance sets in the
* automaton.
*/
void read(istream& input_stream); /* Reads the automaton
* from a stream.
*/
void print /* Writes information */
(ostream& stream = cout, /* about the automaton */
const int indent = 0, /* to a stream in */
const GraphOutputFormat fmt = NORMAL) const; /* various formats
* (determined by the
* `fmt' argument).
*/
bool isDeterministic() const; /* Checks whether
* the automaton
* is deterministic.
*/
unsigned long int nondeterminismIndex() const; /* Computes the
* nondeterminism index.
*/
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
class AutomatonParseException; /* Class for reporting
* parse errors when
* reading an automaton
* description from a
* stream.
*/
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
private:
size_type initial_state; /* Identifier of the
* initial state of the
* automaton.
*/
unsigned long int number_of_acceptance_sets; /* Number of acceptance
* sets in the automaton.
*/
};
/******************************************************************************
*
* A class for representing the transitions of a Büchi automaton.
*
*****************************************************************************/
class BuchiAutomaton::BuchiTransition : public Graph<GraphEdgeContainer>::Edge
{
public:
BuchiTransition /* Constructor. */
(const size_type target,
::Ltl::LtlFormula* formula,
const BitArray& acc_sets,
unsigned long int num_acc_sets);
~BuchiTransition(); /* Destructor. */
/* `targetNode' inherited from Graph<GraphEdgeContainer>::Edge */
bool enabled /* These functions test */
(const BitArray& truth_assignment, /* whether the */
const unsigned long int assignment_size) /* transition is */
const; /* enabled in a given */
/* truth assignment for */
bool enabled /* the atomic */
(const Bitset& truth_assignment) const; /* propositions. */
::Ltl::LtlFormula& guard() const; /* Returns the
* propositional formula
* guarding the transition.
*/
BitArray& acceptanceSets(); /* Returns the */
const BitArray& acceptanceSets() const; /* acceptance sets
* associated with the
* the transition.
*/
void print /* Writes information */
(ostream& stream, /* about the transition */
const int indent, /* (as a plain graph */
const GraphOutputFormat fmt) const; /* edge) to a stream. */
void print /* Writes information */
(ostream& stream, /* about the transition */
const int indent, /* to a stream in */
const GraphOutputFormat fmt, /* various formats */
const unsigned long int /* (determined by the */
number_of_acceptance_sets) const; /* `fmt' argument). */
private:
BuchiTransition(const BuchiTransition&); /* Prevent copying and */
BuchiTransition& operator= /* assignment of */
(const BuchiTransition&); /* BuchiTransition
* objects.
*/
bool operator== /* Equality test. Used */
(const Graph<GraphEdgeContainer>::Edge& /* for sorting */
transition) const; /* transitions in an STL
* container.
*/
bool operator< /* `Less than' relation. */
(const Graph<GraphEdgeContainer>::Edge& /* Used for sorting */
transition) const; /* transitions in an STL
* container.
*/
::Ltl::LtlFormula* guard_formula; /* The propositional
* formula guarding the
* transition.
*/
BitArray acceptance_sets; /* Acceptance sets
* associated with the
* transition.
*/
};
/******************************************************************************
*
* A class for reporting parse errors when reading an automaton description
* from a stream.
*
*****************************************************************************/
class BuchiAutomaton::AutomatonParseException : public Exception
{
public:
AutomatonParseException /* Constructor. */
(const string& msg = "parse error");
/* default copy constructor */
~AutomatonParseException() throw(); /* Destructor. */
AutomatonParseException& /* Assignment operator. */
operator=(const AutomatonParseException& e);
/* `what' inherited from class Exception */
};
/******************************************************************************
*
* Inline function definitions for class BuchiAutomaton.
*
*****************************************************************************/
/* ========================================================================= */
inline BuchiAutomaton::~BuchiAutomaton()
/* ----------------------------------------------------------------------------
*
* Description: Destructor for class BuchiAutomaton.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
inline BuchiAutomaton::BuchiState& BuchiAutomaton::operator[]
(const size_type index) const
/* ----------------------------------------------------------------------------
*
* Description: Indexing operator for class BuchiAutomaton. This function can
* be used to refer to the individual states of the automaton.
* No range check will be performed on the argument.
*
* Argument: index -- Index of a state.
*
* Returns: A reference to a state of the automaton.
*
* ------------------------------------------------------------------------- */
{
return static_cast<BuchiState&>(*nodes[index]);
}
/* ========================================================================= */
inline BuchiAutomaton::BuchiState& BuchiAutomaton::node
(const size_type index) const
/* ----------------------------------------------------------------------------
*
* Description: Function for referring to a single state of a BuchiAutomaton.
* This function will perform a range check on the argument.
*
* Argument: index -- Index of a state.
*
* Returns: A reference to a state of the automaton.
*
* ------------------------------------------------------------------------- */
{
return static_cast<BuchiState&>(Graph<GraphEdgeContainer>::node(index));
}
/* ========================================================================= */
inline void BuchiAutomaton::connect
(const size_type father, const size_type child)
/* ----------------------------------------------------------------------------
*
* Description: Connects two states of a BuchiAutomaton to each other with an
* unguarded transition (actually, a transition with a guard
* that is always true) with an empty set of acceptance
* conditions.
*
* Arguments: father -- Source state identifier.
* child -- Target state identifier.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
BitArray acc_sets(number_of_acceptance_sets);
acc_sets.clear(number_of_acceptance_sets);
connect(father, child, &(::Ltl::True::construct()), acc_sets);
}
/* ========================================================================= */
inline void BuchiAutomaton::connect
(const size_type father, const size_type child, ::Ltl::LtlFormula& guard,
const BitArray& acc_sets)
/* ----------------------------------------------------------------------------
*
* Description: Connects two states of a BuchiAutomaton to each other, using
* a LtlFormula (which is actually a propositional formula) to
* guard the transition between the states.
*
* Arguments: father -- Source state.
* child -- Target state.
* guard -- A reference to an LtlFormula (a propositional
* formula) guarding the transition.
* acc_sets -- A reference to a BitArray giving the
* acceptance sets associated with the transition.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
connect(father, child, guard.clone(), acc_sets);
}
/* ========================================================================= */
inline void BuchiAutomaton::connect
(const size_type father, const size_type child, ::Ltl::LtlFormula* guard,
const BitArray& acc_sets)
/* ----------------------------------------------------------------------------
*
* Description: Connects two states of a BuchiAutomaton to each other, using
* a LtlFormula (which is actually a propositional formula) to
* guard the transition between the states.
*
* Arguments: father -- Source state.
* child -- Target state.
* guard -- A pointer to an LtlFormula (a propositional
* formula) guarding the transition. The
* transition will "own" the guard formula.
* acc_sets -- A reference to a BitArray giving the acceptance
* sets associated with the transition.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
BuchiTransition* new_buchi_transition
= new BuchiTransition(child, guard, acc_sets, number_of_acceptance_sets);
try
{
nodes[father]->outgoing_edges.insert(new_buchi_transition);
}
catch (...)
{
delete new_buchi_transition;
throw;
}
}
/* ========================================================================= */
inline BuchiAutomaton::size_type BuchiAutomaton::initialState() const
/* ----------------------------------------------------------------------------
*
* Description: Returns the initial state of the BuchiAutomaton by value.
*
* Arguments: None.
*
* Returns: Index of the initial state of the automaton.
*
* ------------------------------------------------------------------------- */
{
return initial_state;
}
/* ========================================================================= */
inline BuchiAutomaton::size_type& BuchiAutomaton::initialState()
/* ----------------------------------------------------------------------------
*
* Description: Returns the initial state of the BuchiAutomaton by reference.
* This function can therefore be used to change the initial
* state.
*
* Arguments: None.
*
* Returns: A reference to the value of the initial state.
*
* ------------------------------------------------------------------------- */
{
return initial_state;
}
/* ========================================================================= */
inline unsigned long int BuchiAutomaton::numberOfAcceptanceSets() const
/* ----------------------------------------------------------------------------
*
* Description: Returns the number of acceptance sets in the automaton.
*
* Arguments: None.
*
* Returns: The number of acceptance sets in the automaton.
*
* ------------------------------------------------------------------------- */
{
return number_of_acceptance_sets;
}
/* ========================================================================= */
inline istream& operator>>(istream& stream, BuchiAutomaton& automaton)
/* ----------------------------------------------------------------------------
*
* Description: Defines an alternative method for reading an automaton from
* a stream by using the >> operator.
*
* Arguments: stream -- A reference to an input stream.
* automaton -- A reference to the BuchiAutomaton.
*
* Returns: A reference to the input stream.
*
* ------------------------------------------------------------------------- */
{
automaton.read(stream);
return stream;
}
/******************************************************************************
*
* Inline function definitions for class BuchiAutomaton::BuchiTransition.
*
*****************************************************************************/
/* ========================================================================= */
inline BuchiAutomaton::BuchiTransition::BuchiTransition
(const size_type target, ::Ltl::LtlFormula* formula,
const BitArray& acc_sets, unsigned long int num_acc_sets) :
Edge(target), guard_formula(formula), acceptance_sets(num_acc_sets)
/* ----------------------------------------------------------------------------
*
* Description: Constructor for class BuchiAutomaton::BuchiTransition.
* Initializes a new transition to a BuchiState, guarded by an
* LtlFormula (which is actually a propositional formula).
*
* Arguments: target -- Identifier of the target state of the
* automaton.
* formula -- A pointer to a propositional formula guarding
* the transition.
* acc_sets -- A reference to a constant BitArray containing
* the acceptance sets associated with the
* transition.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
acceptance_sets.copy(acc_sets, num_acc_sets);
}
/* ========================================================================= */
inline BuchiAutomaton::BuchiTransition::~BuchiTransition()
/* ----------------------------------------------------------------------------
*
* Description: Destructor for class BuchiAutomaton::BuchiTransition.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
::Ltl::LtlFormula::destruct(guard_formula);
}
/* ========================================================================= */
inline bool BuchiAutomaton::BuchiTransition::operator==
(const Graph<GraphEdgeContainer>::Edge& transition) const
/* ----------------------------------------------------------------------------
*
* Description: Equality relation for comparing two BuchiTransitions. Two
* transitions are `equal' if and only if their target nodes
* have the same identifier and if their guard formulae are
* identical according to the `less<class ::Ltl::LtlFormula>'
* relation.
*
* Argument: transition -- A reference to a constant Edge.
*
* Returns: Truth value according to the relationship between the two
* transitions.
*
* ------------------------------------------------------------------------- */
{
/*
* This function is called only when comparing two edges stored in the
* `outgoing_edges' GraphEdgeContainer of some state in a BuchiAutomaton.
* Since (pointers to) BuchiTransitions are never mixed with other types in
* that container, it is always safe to static_cast `transition' to a
* reference to a BuchiTransition.
*/
return (Edge::operator==(transition)
&& !(guard_formula < static_cast<const BuchiTransition&>(transition)
.guard_formula)
&& !(static_cast<const BuchiTransition&>(transition).guard_formula
< guard_formula));
}
/* ========================================================================= */
inline bool BuchiAutomaton::BuchiTransition::operator<
(const Graph<GraphEdgeContainer>::Edge& transition) const
/* ----------------------------------------------------------------------------
*
* Description: `Less than' relation for comparing two BuchiTransitions. A
* BuchiTransition is `less than' another if and only if the
* identifier of its target node is less than that of the other
* or the target nodes agree but the guard formula of the
* first transition is `less than' the other according to the
* `less<class ::Ltl::LtlFormula>' relation.
*
* Argument: transition -- A reference to a constant Edge.
*
* Returns: Truth value according to the relationship between the two
* transitions.
*
* ------------------------------------------------------------------------- */
{
/*
* This function is called only when comparing two edges stored in the
* `outgoing_edges' GraphEdgeContainer of some state in a BuchiAutomaton.
* Since (pointers to) BuchiTransitions are never mixed with other types in
* that container, it is always safe to static_cast `transition' to a
* reference to a BuchiTransition.
*/
return (Edge::operator<(transition)
|| (Edge::operator==(transition)
&& guard_formula
< static_cast<const BuchiTransition&>(transition)
.guard_formula));
}
/* ========================================================================= */
inline bool BuchiAutomaton::BuchiTransition::enabled
(const BitArray& truth_assignment, const unsigned long int assignment_size)
const
/* ----------------------------------------------------------------------------
*
* Description: Determines whether the transition is enabled in a given
* truth assignment for propositional variables.
*
* Arguments: truth_assignment -- A reference to a constant BitArray
* representing an assignment of truth
* values to propositional variables.
* assignment_size -- Number of propositions in the
* truth assignment.
*
* Returns: A truth value telling whether the transition is enabled in
* the truth assignment.
*
* ------------------------------------------------------------------------- */
{
return guard_formula->evaluate(truth_assignment, assignment_size);
}
/* ========================================================================= */
inline bool BuchiAutomaton::BuchiTransition::enabled
(const Bitset& truth_assignment) const
/* ----------------------------------------------------------------------------
*
* Description: See above.
*
* Arguments: truth_assignment -- A reference to a constant Bitset
* representing an assignment of truth
* values to propositional variables.
*
* Returns: A truth value telling whether the transition is enabled in
* the truth assignment.
*
* ------------------------------------------------------------------------- */
{
return enabled(truth_assignment, truth_assignment.capacity());
}
/* ========================================================================= */
inline ::Ltl::LtlFormula& BuchiAutomaton::BuchiTransition::guard() const
/* ----------------------------------------------------------------------------
*
* Description: Returns the propositional formula guarding the transition
* (a LtlFormula object).
*
* Arguments: None.
*
* Returns: A reference to the constant propositional formula guarding
* the transition.
*
* ------------------------------------------------------------------------- */
{
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);
}
/******************************************************************************
*
* Inline function definitions for class BuchiAutomaton::BuchiState.
*
*****************************************************************************/
/* ========================================================================= */
inline BuchiAutomaton::BuchiState::BuchiState
(const unsigned long int num_of_acceptance_sets) :
Node(), acceptance_sets(num_of_acceptance_sets)
/* ----------------------------------------------------------------------------
*
* Description: Constructor for class BuchiAutomaton::BuchiState. Initializes
* a new state for the automaton.
*
* Argument: num_of_acceptance_sets -- Number of acceptance sets in the
* automaton to which the state
* belongs.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
acceptance_sets.clear(num_of_acceptance_sets);
}
/* ========================================================================= */
inline BuchiAutomaton::BuchiState::~BuchiState()
/* ----------------------------------------------------------------------------
*
* Description: Destructor for class BuchiAutomaton::BuchiState.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
inline BitArray& BuchiAutomaton::BuchiState::acceptanceSets()
/* ----------------------------------------------------------------------------
*
* Description: Returns the acceptance status of the BuchiState, i.e. the
* BitArray indicating the acceptance sets to which the state
* belongs.
*
* Arguments: None.
*
* Returns: A reference to a BitArray object telling the acceptance sets
* to which the state belongs.
*
* ------------------------------------------------------------------------- */
{
return acceptance_sets;
}
/* ========================================================================= */
inline const BitArray& BuchiAutomaton::BuchiState::acceptanceSets() const
/* ----------------------------------------------------------------------------
*
* Description: Returns the acceptance status of the BuchiState, i.e. the
* BitArray indicating the acceptance sets to which the state
* belongs.
*
* Arguments: None.
*
* Returns: A reference to a constant BitArray object telling the
* acceptance sets to which the state belongs.
*
* ------------------------------------------------------------------------- */
{
return acceptance_sets;
}
/* ========================================================================= */
inline void BuchiAutomaton::BuchiState::print
(ostream& stream, const int indent, const GraphOutputFormat fmt) const
/* ----------------------------------------------------------------------------
*
* Description: Writes information about a state of a Büchi automaton,
* assuming that the (unspecified) maximum number of acceptance
* sets in the automaton is 0. [Note: This function is used
* to override the `print' function defined in the base class
* `Graph::Node'.]
*
* 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 state.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------ */
{
this->print(stream, indent, fmt, 0);
}
/******************************************************************************
*
* Inline function definitions for class
* BuchiAutomaton::AutomatonParseException.
*
*****************************************************************************/
/* ========================================================================= */
inline BuchiAutomaton::AutomatonParseException::AutomatonParseException
(const string& msg) :
Exception(msg)
/* ----------------------------------------------------------------------------
*
* Description: Constructor for class
* BuchiAutomaton::AutomatonParseException. Initializes a new
* exception object with an error message.
*
* Argument: msg -- A reference to a constant string containing the
* error message.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
inline BuchiAutomaton::AutomatonParseException::~AutomatonParseException()
throw()
/* ----------------------------------------------------------------------------
*
* Description: Destructor for class BuchiAutomaton::AutomatonParseException.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
inline BuchiAutomaton::AutomatonParseException&
BuchiAutomaton::AutomatonParseException::operator=
(const AutomatonParseException& e)
/* ----------------------------------------------------------------------------
*
* Description: Assignment operator for class
* BuchiAutomaton::AutomatonParseException. Assigns the contents
* of another object of the same type to the exception object.
*
* Argument: e -- A reference to a constant exception object of the
* same type.
*
* Returns: A reference to the exception object assigned to.
*
* ------------------------------------------------------------------------- */
{
Exception::operator=(e);
return *this;
}
}
#endif /* !BUCHIAUTOMATON_H */

View file

@ -1,96 +0,0 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* 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.
*/
#include "BuchiProduct.h"
namespace Graph
{
/******************************************************************************
*
* Static member definitions for class BuchiProduct.
*
*****************************************************************************/
map< ::Ltl::LtlFormula*, BuchiProduct::SatisfiabilityMapping>
BuchiProduct::sat_cache;
/******************************************************************************
*
* Function definitions for class BuchiProduct.
*
*****************************************************************************/
/* ========================================================================= */
bool BuchiProduct::synchronizable
(const Graph<GraphEdgeContainer>::Edge& transition_1,
const Graph<GraphEdgeContainer>::Edge& transition_2)
/* ----------------------------------------------------------------------------
*
* Description: Tests whether two transitions of two Büchi automata are
* synchronizable by checking whether the conjunction of their
* guard formulas is satisfiable.
*
* Arguments: transition_1, -- Constant references to the transitions.
* transition_2
*
* Returns: true iff the transitions are synchronizable. The result is
* also stored into `this->sat_cache' for later reference.
*
* ------------------------------------------------------------------------- */
{
using ::Ltl::LtlFormula;
using ::Ltl::And;
LtlFormula* guard_1 = &static_cast<const BuchiAutomaton::BuchiTransition&>
(transition_1).guard();
LtlFormula* guard_2 = &static_cast<const BuchiAutomaton::BuchiTransition&>
(transition_2).guard();
if (guard_2 > guard_1)
{
LtlFormula* swap_guard = guard_2;
guard_2 = guard_1;
guard_1 = swap_guard;
}
map<LtlFormula*, SatisfiabilityMapping>::iterator
sat_cache_element = sat_cache.find(guard_1);
if (sat_cache_element == sat_cache.end())
sat_cache_element = sat_cache.insert
(make_pair(guard_1, SatisfiabilityMapping())).first;
else
{
SatisfiabilityMapping::const_iterator sat_result
= sat_cache_element->second.find(guard_2);
if (sat_result != sat_cache_element->second.end())
return sat_result->second;
}
LtlFormula* f = &And::construct(*guard_1, *guard_2);
const bool result = f->satisfiable();
LtlFormula::destruct(f);
sat_cache_element->second.insert(make_pair(guard_2, result));
return result;
}
}

View file

@ -1,510 +0,0 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* 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 BUCHIPRODUCT_H
#define BUCHIPRODUCT_H
#include <config.h>
#include <deque>
#include <iostream>
#include <map>
#include <string>
#include <vector>
#include "BitArray.h"
#include "BuchiAutomaton.h"
#include "EdgeContainer.h"
#include "Graph.h"
#include "LtlFormula.h"
using namespace std;
namespace Graph
{
/******************************************************************************
*
* A class with operations for checking the intersection of two Büchi automata
* (represented as two BuchiAutomaton objects) for emptiness.
*
*****************************************************************************/
class BuchiProduct
{
public:
BuchiProduct /* Constructor. */
(const Graph<GraphEdgeContainer>& a1,
const Graph<GraphEdgeContainer>& a2);
/* default copy constructor */
~BuchiProduct(); /* Destructor. */
/* default assignment operator */
bool empty() const; /* Tells whether the
* intersection of the
* Büchi automata
* associated with the
* product object is
* (trivially) empty.
*/
unsigned long int numberOfAcceptanceSets() const; /* Tells the number of
* acceptance sets in the
* intersection of the
* automata associated with
* the object.
*/
const BuchiAutomaton::BuchiState& firstComponent /* Mappings between an */
(const Graph<GraphEdgeContainer>::size_type /* intersection state */
state_id) const; /* identifier and states */
const BuchiAutomaton::BuchiState& secondComponent /* of the underlying */
(const Graph<GraphEdgeContainer>::size_type /* automata. */
state_id) const;
void mergeAcceptanceInformation /* Merges the acceptance */
(const Graph<GraphEdgeContainer>::Node& state1, /* sets associated with */
const Graph<GraphEdgeContainer>::Node& state2, /* a pair of states into */
BitArray& acceptance_sets) const; /* a collection of sets. */
void mergeAcceptanceInformation /* Merges the acceptance */
(const Graph<GraphEdgeContainer>::Edge& /* sets associated with */
transition1, /* a pair of */
const Graph<GraphEdgeContainer>::Edge& /* transitions into a */
transition2, /* collection of sets. */
BitArray& acceptance_sets) const;
void validateEdgeIterators /* Ensures that a pair */
(const Graph<GraphEdgeContainer>::Node& /* of transition */
state_1, /* iterators points to a */
const Graph<GraphEdgeContainer>::Node& /* transition beginning */
state_2, /* from a given state in */
GraphEdgeContainer::const_iterator& /* the intersection of */
transition_1, /* two Büchi automata. */
GraphEdgeContainer::const_iterator&
transition_2);
void incrementEdgeIterators /* Updates a pair of */
(const Graph<GraphEdgeContainer>::Node& /* transition iterators */
state_1, /* to make them point to */
const Graph<GraphEdgeContainer>::Node& /* the "next" transition */
state_2, /* starting from a given */
GraphEdgeContainer::const_iterator& /* state in the */
transition_1, /* intersection of two */
GraphEdgeContainer::const_iterator& /* Büchi automata. */
transition_2);
static void clearSatisfiabilityCache(); /* Clears information about
* the satisfiability of
* the guards of product
* transitions.
*/
private:
void mergeAcceptanceInformation /* Bitwise or between */
(const BitArray& sets1, const BitArray& sets2, /* two "component" */
BitArray& result) const; /* acceptance set
* vectors and a result
* vector.
*/
bool synchronizable /* Tests whether a pair */
(const Graph<GraphEdgeContainer>::Edge& /* of transitions of two */
transition_1, /* Büchi automata is */
const Graph<GraphEdgeContainer>::Edge& /* synchronizable. */
transition_2);
const BuchiAutomaton& automaton_1; /* Automata associated */
const BuchiAutomaton& automaton_2; /* with the BuchiProduct */
/* object. */
const unsigned long int /* Number of acceptance */
number_of_acceptance_sets; /* sets in the
* intersection of the
* automata.
*/
typedef map< ::Ltl::LtlFormula*, bool> /* Type definition for */
SatisfiabilityMapping; /* storing information
* about the
* satisfiability of the
* guards of product
* transitions.
*/
static map< ::Ltl::LtlFormula*, /* Result cache for */
SatisfiabilityMapping> /* satisfiability tests. */
sat_cache;
};
/******************************************************************************
*
* Inline function definitions for class BuchiProduct.
*
*****************************************************************************/
/* ========================================================================= */
inline BuchiProduct::BuchiProduct
(const Graph<GraphEdgeContainer>& a1, const Graph<GraphEdgeContainer>& a2) :
automaton_1(static_cast<const BuchiAutomaton&>(a1)),
automaton_2(static_cast<const BuchiAutomaton&>(a2)),
number_of_acceptance_sets(static_cast<const BuchiAutomaton&>(a1)
.numberOfAcceptanceSets()
+ static_cast<const BuchiAutomaton&>(a2)
.numberOfAcceptanceSets())
/* ----------------------------------------------------------------------------
*
* Description: Constructor for class BuchiProduct. Initializes a new object
* with operations for checking the emptiness of two Büchi
* automata.
*
* Arguments: a1, a2 -- Constant references to two
* Graph<GraphEdgeContainer> objects, assumed to be
* BüchiAutomaton objects to which to apply the
* operations.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
inline BuchiProduct::~BuchiProduct()
/* ----------------------------------------------------------------------------
*
* Description: Destructor for class BuchiProduct.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
inline bool BuchiProduct::empty() const
/* ----------------------------------------------------------------------------
*
* Description: Tells whether the intersection of the Büchi automata
* associated with a BuchiProduct object is (trivially) empty.
*
* Arguments: None.
*
* Returns: true iff either of the automata associated with the
* BuchiProduct object is (trivially) empty (i.e., whether
* either of the automata has no states).
*
* ------------------------------------------------------------------------- */
{
return (automaton_1.empty() || automaton_2.empty());
}
/* ========================================================================= */
inline unsigned long int BuchiProduct::numberOfAcceptanceSets() const
/* ----------------------------------------------------------------------------
*
* Description: Tells the number of acceptance sets in the intersection of
* the two Büchi automata associated with a BuchiProduct object.
*
* Arguments: None.
*
* Returns: The number of acceptance sets in the intersection.
*
* ------------------------------------------------------------------------- */
{
return number_of_acceptance_sets;
}
/* ========================================================================= */
inline const BuchiAutomaton::BuchiState& BuchiProduct::firstComponent
(const Graph<GraphEdgeContainer>::size_type state_id) const
/* ----------------------------------------------------------------------------
*
* Description: Function for accessing states of the "first" component
* automaton in the intersection of two Büchi automata.
*
* Argument: state_id -- Identifier of a state in the component
* automaton.
*
* Returns: A constant reference to a state in the component automaton.
*
* ------------------------------------------------------------------------- */
{
return automaton_1[state_id];
}
/* ========================================================================= */
inline const BuchiAutomaton::BuchiState& BuchiProduct::secondComponent
(const Graph<GraphEdgeContainer>::size_type state_id) const
/* ----------------------------------------------------------------------------
*
* Description: Function for accessing states of the "second" component
* automaton in the intersection of two Büchi automata.
*
* Argument: state_id -- Identifier of a state in the component
* automaton.
*
* Returns: A constant reference to a state in the component automaton.
*
* ------------------------------------------------------------------------- */
{
return automaton_2[state_id];
}
/* ========================================================================= */
inline void BuchiProduct::mergeAcceptanceInformation
(const Graph<GraphEdgeContainer>::Node& state1,
const Graph<GraphEdgeContainer>::Node& state2,
BitArray& acceptance_sets) const
/* ----------------------------------------------------------------------------
*
* Description: Merges the acceptance sets associated with a pair of states
* of two Büchi automata into a collection of sets.
*
* Arguments: state1, state2 -- Constant references to the states of the
* automata.
* acceptance_sets -- A reference to a BitArray for storing
* the result. The BitArray is assumed to
* have capacity for
* `this->number_of_acceptance_sets' bits.
*
* Returns: Nothing. Let n=`this->automaton_1.numberOfAcceptanceSets()';
* after the operation, `acceptance_sets[i] = true' holds if
* either
* 0 <= i < n and
* `state1.acceptanceSets().test(i) == true'
* or 0 <= i - n < `this->automaton_2.numberOfAcceptanceSets()'
* and `state2.acceptanceSets().test(i - n) == true'.
*
* ------------------------------------------------------------------------- */
{
mergeAcceptanceInformation
(static_cast<const BuchiAutomaton::BuchiState&>(state1).acceptanceSets(),
static_cast<const BuchiAutomaton::BuchiState&>(state2).acceptanceSets(),
acceptance_sets);
}
/* ========================================================================= */
inline void BuchiProduct::mergeAcceptanceInformation
(const Graph<GraphEdgeContainer>::Edge& transition1,
const Graph<GraphEdgeContainer>::Edge& transition2,
BitArray& acceptance_sets) const
/* ----------------------------------------------------------------------------
*
* Description: Merges the acceptance sets associated with a pair of
* transitions of two Büchi automata into a collection of
* acceptance sets.
*
* Arguments: transition1, -- Constant references to the transitions
* transition2 of the automata.
* acceptance_sets -- A reference to a BitArray for storing
* the result. The BitArray is assumed to
* have capacity for
* `this->number_of_acceptance_sets' bits.
*
* Returns: Nothing. Let n=`this->automaton_1.numberOfAcceptanceSets()';
* after the operation, `acceptance_sets[i] = true' holds if
* either
* 0 <= i < n and
* `transition1.acceptanceSets().test(i) == true'
* or 0 <= i - n < `this->automaton_2.numberOfAcceptanceSets()'
* and `transition2.acceptanceSets().test(i - n) == true'.
*
* ------------------------------------------------------------------------- */
{
mergeAcceptanceInformation
(static_cast<const BuchiAutomaton::BuchiTransition&>(transition1)
.acceptanceSets(),
static_cast<const BuchiAutomaton::BuchiTransition&>(transition2)
.acceptanceSets(),
acceptance_sets);
}
/* ========================================================================= */
inline void BuchiProduct::mergeAcceptanceInformation
(const BitArray& sets1, const BitArray& sets2, BitArray& result) const
/* ----------------------------------------------------------------------------
*
* Description: Bitwise or between two acceptance set vectors and a result
* vector.
*
* Arguments: sets1, -- Constant references to two BitArrays having (at
* sets2 least) capacities
* `automaton_1.numberOfAcceptanceSets()' and
* `automaton_2.numberOfAcceptanceSets()',
* respectively.
* result -- A BitArray for storing the result, assumed to
* have room for at least
* `this->number_of_acceptance_sets' bits.
*
* Returns: Nothing. Let n=`this->automaton_1.numberOfAcceptanceSets()';
* after the operation, `result[i] = true' holds if
* either
* 0 <= i < n and `sets1[i] == true'
* or 0 <= i - n < `this->automaton_2.numberOfAcceptanceSets()'
* and `sets2[i - n] == true'.
*
* ------------------------------------------------------------------------- */
{
const unsigned long int shift
= automaton_1.numberOfAcceptanceSets();
unsigned long int acceptance_set;
for (acceptance_set = 0; acceptance_set < shift; ++acceptance_set)
{
if (sets1[acceptance_set])
result.setBit(acceptance_set);
}
for ( ; acceptance_set < number_of_acceptance_sets; ++acceptance_set)
{
if (sets2[acceptance_set - shift])
result.setBit(acceptance_set);
}
}
/* ========================================================================= */
inline void BuchiProduct::validateEdgeIterators
(const Graph<GraphEdgeContainer>::Node& state_1,
const Graph<GraphEdgeContainer>::Node& state_2,
GraphEdgeContainer::const_iterator& transition_1,
GraphEdgeContainer::const_iterator& transition_2)
/* ----------------------------------------------------------------------------
*
* Description: Checks whether a pair of transition iterators corresponds to
* a transition beginning from a state in the intersection of
* two Büchi automata; if this is not the case, increments the
* iterators to make them point to a valid transition beginning
* from the state in the intersection (or to the "end" of the
* collection of transitions beginning from the state if no
* valid transition can be found by incrementing the iterators).
*
* Arguments: state_1, -- These variables determine the state in
* state_2 the intersection automaton; `state_1' and
* `state_2' should both be references to
* BuchiAutomaton::BuchiState objects.
* transition_1, -- References to the transition iterators.
* transition_2 Initially, `transition_1' and
* `transition_2' should point to two
* transitions starting from `state_1' and
* `state_2', respectively.
*
* Returns: Nothing. Upon return, `transition_1' and `transition_2' will
* either equal `state_1.edges().end()' and
* `state_2.edges().end()', respectively, or they will point to
* a pair of transitions beginning from `state_1' and `state_2'
* such that this pair of transitions corresponds to a
* transition starting from the intersection state determined by
* `state_1' and `state_2'.
*
* ------------------------------------------------------------------------- */
{
const GraphEdgeContainer& transitions_1 = state_1.edges();
const GraphEdgeContainer& transitions_2 = state_2.edges();
if (transition_1 == transitions_1.end())
{
transition_2 = transitions_2.end();
return;
}
if (transition_2 == transitions_2.end())
{
transition_1 = transitions_1.end();
return;
}
if (!synchronizable(**transition_1, **transition_2))
incrementEdgeIterators(state_1, state_2, transition_1, transition_2);
}
/* ========================================================================= */
inline void BuchiProduct::incrementEdgeIterators
(const Graph<GraphEdgeContainer>::Node& state_1,
const Graph<GraphEdgeContainer>::Node& state_2,
GraphEdgeContainer::const_iterator& transition_1,
GraphEdgeContainer::const_iterator& transition_2)
/* ----------------------------------------------------------------------------
*
* Description: Increments a pair of transition iterators to point to the
* "next" transition beginning from a state in the intersection
* of two Büchi automata. If no "next" transition exists, makes
* the iterators point to the "end" of the collection of
* transitions beginning from the state.
*
* Arguments: state_1, -- These variables determine the state in
* state_2 the intersection automaton; `state_1' and
* `state_2' should both be references to
* BuchiAutomaton::BuchiState objects.
* transition_1, -- References to the transition iterators.
* transition_2 Initially, `transition_1' and
* `transition_2' should point to two
* transitions starting from `state_1' and
* `state_2', respectively.
*
* Returns: Nothing. Upon return, `transition_1' and `transition_2' will
* either equal `state_1.edges().end()' and
* `state_2.edges().end()', respectively, or they will point to
* a pair of transitions beginning from `state_1' and `state_2'
* such that this pair of transitions corresponds to a
* transition starting from the intersection state determined by
* `state_1' and `state_2'.
*
* ------------------------------------------------------------------------- */
{
const GraphEdgeContainer& transitions_1 = state_1.edges();
const GraphEdgeContainer& transitions_2 = state_2.edges();
do
{
++transition_2;
if (transition_2 == transitions_2.end())
{
++transition_1;
if (transition_1 == transitions_1.end())
return;
transition_2 = transitions_2.begin();
}
}
while (!synchronizable(**transition_1, **transition_2));
}
/* ========================================================================= */
inline void BuchiProduct::clearSatisfiabilityCache()
/* ----------------------------------------------------------------------------
*
* Description: Clears information about the satisfiability of the guard
* formulas of product transitions.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
sat_cache.clear();
}
}
#endif /* !BUCHIPRODUCT_H */

View file

@ -1,130 +0,0 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* 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.
*/
%{
#include <config.h>
#include "Configuration.h"
#include "Config-parse.h"
extern int config_file_line_number;
%}
%option case-insensitive
%option never-interactive
%option noyywrap
%option nounput
%x ATTR EQ VAL
SQSTR [^\'\n]*
DQSTR ([^\"\\\n]|\\.)*
UQC [^\'\"\\ \t\n]
UQSTR ({UQC}+|\\.)({UQC}*|\\.)*
OKVAL \'{SQSTR}\'|\"{DQSTR}\"|{UQSTR}
%%
<*>[ \t]* { /* Skip whitespace everywhere. */ }
<*>"#".*$ { /* Skip comments everywhere. */ }
<INITIAL,ATTR>"\n" { /* Skip newlines, but update the line number. */
config_file_line_number++;
}
"{" { BEGIN(ATTR); return CFG_LBRACE; }
algorithm|implementation|translator { return CFG_ALGORITHM; }
globaloptions { return CFG_GLOBALOPTIONS; }
statespaceoptions { return CFG_STATESPACEOPTIONS; }
formulaoptions { return CFG_FORMULAOPTIONS; }
[^ \t\n]+ { return CFG_UNKNOWN; }
<ATTR>enabled { BEGIN(EQ); return CFG_ENABLED; }
<ATTR>name { BEGIN(EQ); return CFG_NAME; }
<ATTR>parameters { BEGIN(EQ); return CFG_PARAMETERS; }
<ATTR>path { BEGIN(EQ); return CFG_PROGRAMPATH; }
<ATTR>comparisoncheck { BEGIN(EQ); return CFG_COMPARISONTEST; }
<ATTR>comparisontest { BEGIN(EQ); return CFG_COMPARISONTEST; }
<ATTR>consistencycheck { BEGIN(EQ); return CFG_CONSISTENCYTEST; }
<ATTR>consistencytest { BEGIN(EQ); return CFG_CONSISTENCYTEST; }
<ATTR>interactive { BEGIN(EQ); return CFG_INTERACTIVE; }
<ATTR>intersectioncheck { BEGIN(EQ); return CFG_INTERSECTIONTEST; }
<ATTR>intersectiontest { BEGIN(EQ); return CFG_INTERSECTIONTEST; }
<ATTR>modelcheck { BEGIN(EQ); return CFG_MODELCHECK; }
<ATTR>rounds { BEGIN(EQ); return CFG_ROUNDS; }
<ATTR>translatortimeout { BEGIN(EQ); return CFG_TRANSLATORTIMEOUT; }
<ATTR>verbosity { BEGIN(EQ); return CFG_VERBOSITY; }
<ATTR>edgeprobability { BEGIN(EQ); return CFG_EDGEPROBABILITY; }
<ATTR>propositions { BEGIN(EQ); return CFG_PROPOSITIONS; }
<ATTR>size { BEGIN(EQ); return CFG_SIZE; }
<ATTR>truthprobability { BEGIN(EQ); return CFG_TRUTHPROBABILITY; }
<ATTR>changeinterval { BEGIN(EQ); return CFG_CHANGEINTERVAL; }
<ATTR>randomseed { BEGIN(EQ); return CFG_RANDOMSEED; }
<ATTR>abbreviatedoperators { BEGIN(EQ); return CFG_ABBREVIATEDOPERATORS; }
<ATTR>andpriority { BEGIN(EQ); return CFG_ANDPRIORITY; }
<ATTR>beforepriority { BEGIN(EQ); return CFG_BEFOREPRIORITY; }
<ATTR>defaultoperatorpriority {
BEGIN(EQ); return CFG_DEFAULTOPERATORPRIORITY;
}
<ATTR>equivalencepriority { BEGIN(EQ); return CFG_EQUIVALENCEPRIORITY; }
<ATTR>falsepriority { BEGIN(EQ); return CFG_FALSEPRIORITY; }
<ATTR>finallypriority { BEGIN(EQ); return CFG_FINALLYPRIORITY; }
<ATTR>generatemode { BEGIN(EQ); return CFG_GENERATEMODE; }
<ATTR>globallypriority { BEGIN(EQ); return CFG_GLOBALLYPRIORITY; }
<ATTR>implicationpriority { BEGIN(EQ); return CFG_IMPLICATIONPRIORITY; }
<ATTR>nextpriority { BEGIN(EQ); return CFG_NEXTPRIORITY; }
<ATTR>notpriority { BEGIN(EQ); return CFG_NOTPRIORITY; }
<ATTR>orpriority { BEGIN(EQ); return CFG_ORPRIORITY; }
<ATTR>outputmode { BEGIN(EQ); return CFG_OUTPUTMODE; }
<ATTR>propositionpriority { BEGIN(EQ); return CFG_PROPOSITIONPRIORITY; }
<ATTR>releasepriority { BEGIN(EQ); return CFG_RELEASEPRIORITY; }
<ATTR>strongreleasepriority { BEGIN(EQ); return CFG_STRONGRELEASEPRIORITY; }
<ATTR>truepriority { BEGIN(EQ); return CFG_TRUEPRIORITY; }
<ATTR>untilpriority { BEGIN(EQ); return CFG_UNTILPRIORITY; }
<ATTR>weakuntilpriority { BEGIN(EQ); return CFG_WEAKUNTILPRIORITY; }
<ATTR>xorpriority { BEGIN(EQ); return CFG_XORPRIORITY; }
<ATTR>"}" { BEGIN(INITIAL); return CFG_RBRACE; }
<ATTR>"="?[^= \t\n]* { return CFG_UNKNOWN; }
<EQ>"=" { BEGIN(VAL); return CFG_EQUALS; }
<EQ>. { return CFG_UNKNOWN; }
<VAL>\\|{OKVAL}+(\\)? {
yylval.value = yytext;
BEGIN(ATTR);
return CFG_VALUE;
}
<VAL>{OKVAL}*(\'{SQSTR}|\"{DQSTR})(\\)? {
throw Configuration::ConfigurationException
(config_file_line_number,
"unmatched quotes");
}
<EQ,VAL>"\n" { return CFG_UNKNOWN; }
%%

View file

@ -1,663 +0,0 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2009
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* 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.
*/
%{
#include <config.h>
#include <string>
#include "Configuration.h"
#include "StringUtil.h"
using namespace ::StringUtil;
/******************************************************************************
*
* Variables for parsing the configuration file.
*
*****************************************************************************/
static string algorithm_name, algorithm_path, /* Implementation */
algorithm_parameters; /* attributes read from */
static bool algorithm_enabled; /* an `Algorithm' block
* in the configuration
* file.
*/
static int algorithm_begin_line; /* Input file line number
* denoting the beginning
* of the most recently
* encountered `Algorithm'
* block.
*/
static int expected_token; /* Type of a token to be
* encountered next when
* reading the
* configuration file.
*/
static Configuration* parser_cfg; /* Pointer to a
* Configuration data
* structure in which
* the configuration will
* be stored.
*/
int config_file_line_number; /* Number of the current
* line in the
* configuration
* file.
*/
/******************************************************************************
*
* Declarations for external functions and variables (provided by the lexer)
* used when parsing the configuration file.
*
*****************************************************************************/
#ifdef YYTEXT_POINTER
extern char* yytext; /* Current token in the */
#else /* input (provided by */
extern char yytext[]; /* the lexer). */
#endif /* YYTEXT_POINTER */
extern void yyrestart(FILE*); /* Changes the input stream
* for the lexer (provided
* by the lexer).
*/
extern int yylex(); /* Reads the next token
* from the input (this
* function is provided by
* the lexer).
*/
void yyerror(const char* error_message); /* Fwd. definition. See below. */
%}
/******************************************************************************
*
* Declarations for terminal and nonterminal symbols used in the grammar rules
* below.
*
*****************************************************************************/
/* Data type for configuration file option values. */
%union
{
const char* value;
}
/* Keywords. */
%token CFG_ALGORITHM CFG_ENABLED CFG_NAME CFG_PARAMETERS CFG_PROGRAMPATH
%token CFG_GLOBALOPTIONS CFG_COMPARISONTEST CFG_CONSISTENCYTEST CFG_INTERACTIVE
CFG_INTERSECTIONTEST CFG_MODELCHECK CFG_ROUNDS CFG_TRANSLATORTIMEOUT
CFG_VERBOSITY
%token CFG_STATESPACEOPTIONS CFG_EDGEPROBABILITY CFG_PROPOSITIONS CFG_SIZE
CFG_TRUTHPROBABILITY CFG_CHANGEINTERVAL CFG_RANDOMSEED
%token CFG_FORMULAOPTIONS CFG_ABBREVIATEDOPERATORS CFG_ANDPRIORITY
CFG_BEFOREPRIORITY CFG_DEFAULTOPERATORPRIORITY CFG_EQUIVALENCEPRIORITY
CFG_FALSEPRIORITY CFG_FINALLYPRIORITY CFG_GENERATEMODE
CFG_GLOBALLYPRIORITY CFG_IMPLICATIONPRIORITY CFG_NEXTPRIORITY
CFG_NOTPRIORITY CFG_ORPRIORITY CFG_OUTPUTMODE CFG_PROPOSITIONPRIORITY
CFG_RELEASEPRIORITY CFG_STRONGRELEASEPRIORITY CFG_TRUEPRIORITY
CFG_UNTILPRIORITY CFG_WEAKUNTILPRIORITY CFG_XORPRIORITY
/* Punctuation symbols. */
%token CFG_LBRACE CFG_RBRACE CFG_EQUALS
/* Block and option identifiers. */
%token CFG_BLOCK_ID CFG_OPTION_ID
/* Uninterpreted option values. */
%token <value> CFG_VALUE
%type <value> equals_value
/* The `unknown' token. */
%token CFG_UNKNOWN
/******************************************************************************
*
* Grammar rule definitions.
*
*****************************************************************************/
%%
configuration_file: configuration_blocks
;
equals_value: { expected_token = CFG_EQUALS; }
CFG_EQUALS
{ expected_token = CFG_VALUE; }
CFG_VALUE
{ $$ = $4; }
;
configuration_blocks: /* empty */
| configuration_blocks
{ expected_token = CFG_BLOCK_ID; }
configuration_block
;
configuration_block: algorithm_option_block
| global_option_block
| statespace_option_block
| formula_option_block
;
algorithm_option_block: CFG_ALGORITHM
{
algorithm_name = "";
algorithm_path = "";
algorithm_parameters = "";
algorithm_enabled = true;
algorithm_begin_line = config_file_line_number;
expected_token = CFG_LBRACE;
}
CFG_LBRACE algorithm_options CFG_RBRACE
{
parser_cfg->registerAlgorithm
(algorithm_name, algorithm_path,
algorithm_parameters, algorithm_enabled,
algorithm_begin_line);
}
;
algorithm_options: /* empty */
| algorithm_options
{ expected_token = CFG_OPTION_ID; }
algorithm_option
;
algorithm_option: CFG_ENABLED equals_value
{
parser_cfg->readTruthValue
(algorithm_enabled,
$2);
}
| CFG_NAME equals_value
{ algorithm_name = unquoteString($2); }
| CFG_PARAMETERS equals_value
{
algorithm_parameters = unquoteString($2);
}
| CFG_PROGRAMPATH equals_value
{ algorithm_path = unquoteString($2); }
;
global_option_block: CFG_GLOBALOPTIONS
{ expected_token = CFG_LBRACE; }
CFG_LBRACE global_options CFG_RBRACE
;
global_options: /* empty */
| global_options
{ expected_token = CFG_OPTION_ID; }
global_option
;
global_option: CFG_COMPARISONTEST equals_value
{
parser_cfg->readTruthValue
(parser_cfg->global_options.
do_comp_test,
$2);
}
| CFG_CONSISTENCYTEST equals_value
{
parser_cfg->readTruthValue
(parser_cfg->global_options.
do_cons_test,
$2);
}
| CFG_INTERACTIVE equals_value
{ parser_cfg->readInteractivity($2); }
| CFG_INTERSECTIONTEST equals_value
{
parser_cfg->readTruthValue
(parser_cfg->global_options.
do_intr_test,
$2);
}
| CFG_MODELCHECK equals_value
{ parser_cfg->readProductType($2); }
| CFG_ROUNDS equals_value
{
parser_cfg->readInteger
(parser_cfg->global_options.number_of_rounds,
$2,
Configuration::ROUND_COUNT_RANGE);
}
| CFG_TRANSLATORTIMEOUT equals_value
{ parser_cfg->readTranslatorTimeout($2); }
| CFG_VERBOSITY equals_value
{
parser_cfg->readInteger
(parser_cfg->global_options.verbosity,
$2,
Configuration::VERBOSITY_RANGE);
}
;
statespace_option_block: CFG_STATESPACEOPTIONS
{ expected_token = CFG_LBRACE; }
CFG_LBRACE statespace_options CFG_RBRACE
;
statespace_options: /* empty */
| statespace_options
{ expected_token = CFG_OPTION_ID; }
statespace_option
;
statespace_option: CFG_CHANGEINTERVAL equals_value
{
parser_cfg->readInteger
(parser_cfg->global_options.
statespace_change_interval,
$2);
}
| CFG_EDGEPROBABILITY equals_value
{
parser_cfg->readProbability
(parser_cfg->statespace_generator.
edge_probability,
$2);
}
| CFG_GENERATEMODE equals_value
{ parser_cfg->readStateSpaceMode($2); }
| CFG_PROPOSITIONS equals_value
{
parser_cfg->readInteger
(parser_cfg->statespace_generator.
atoms_per_state,
$2);
}
| CFG_RANDOMSEED equals_value
{
parser_cfg->readInteger
(parser_cfg->global_options.
statespace_random_seed,
$2,
Configuration::RANDOM_SEED_RANGE);
}
| CFG_SIZE equals_value
{
parser_cfg->readSize
(Configuration::OPT_STATESPACESIZE,
$2);
}
| CFG_TRUTHPROBABILITY equals_value
{
parser_cfg->readProbability
(parser_cfg->statespace_generator.
truth_probability,
$2);
}
;
formula_option_block: CFG_FORMULAOPTIONS
{ expected_token = CFG_LBRACE; }
CFG_LBRACE formula_options CFG_RBRACE
;
formula_options: /* empty */
| formula_options
{ expected_token = CFG_OPTION_ID; }
formula_option
;
formula_option: CFG_ABBREVIATEDOPERATORS equals_value
{
parser_cfg->readTruthValue
(parser_cfg->formula_options.
allow_abbreviated_operators,
$2);
}
| CFG_ANDPRIORITY equals_value
{
parser_cfg->readInteger
(parser_cfg->formula_options.symbol_priority
[::Ltl::LTL_CONJUNCTION],
$2,
Configuration::OPERATOR_PRIORITY_RANGE);
}
| CFG_BEFOREPRIORITY equals_value
{
parser_cfg->readInteger
(parser_cfg->formula_options.symbol_priority
[::Ltl::LTL_BEFORE],
$2,
Configuration::OPERATOR_PRIORITY_RANGE);
}
| CFG_CHANGEINTERVAL equals_value
{
parser_cfg->readInteger
(parser_cfg->global_options.
formula_change_interval,
$2);
}
| CFG_DEFAULTOPERATORPRIORITY equals_value
{
parser_cfg->readInteger
(parser_cfg->formula_options.
default_operator_priority,
$2,
Configuration::OPERATOR_PRIORITY_RANGE);
}
| CFG_EQUIVALENCEPRIORITY equals_value
{
parser_cfg->readInteger
(parser_cfg->formula_options.symbol_priority
[::Ltl::LTL_EQUIVALENCE],
$2,
Configuration::OPERATOR_PRIORITY_RANGE);
}
| CFG_FALSEPRIORITY equals_value
{
parser_cfg->readInteger
(parser_cfg->formula_options.symbol_priority
[::Ltl::LTL_FALSE],
$2,
Configuration::ATOMIC_PRIORITY_RANGE);
}
| CFG_FINALLYPRIORITY equals_value
{
parser_cfg->readInteger
(parser_cfg->formula_options.symbol_priority
[::Ltl::LTL_FINALLY],
$2,
Configuration::OPERATOR_PRIORITY_RANGE);
}
| CFG_GENERATEMODE equals_value
{
parser_cfg->readFormulaMode
(parser_cfg->formula_options.generate_mode,
$2);
}
| CFG_GLOBALLYPRIORITY equals_value
{
parser_cfg->readInteger
(parser_cfg->formula_options.symbol_priority
[::Ltl::LTL_GLOBALLY],
$2,
Configuration::OPERATOR_PRIORITY_RANGE);
}
| CFG_IMPLICATIONPRIORITY equals_value
{
parser_cfg->readInteger
(parser_cfg->formula_options.symbol_priority
[::Ltl::LTL_IMPLICATION],
$2,
Configuration::OPERATOR_PRIORITY_RANGE);
}
| CFG_NEXTPRIORITY equals_value
{
parser_cfg->readInteger
(parser_cfg->formula_options.symbol_priority
[::Ltl::LTL_NEXT],
$2,
Configuration::OPERATOR_PRIORITY_RANGE);
}
| CFG_NOTPRIORITY equals_value
{
parser_cfg->readInteger
(parser_cfg->formula_options.symbol_priority
[::Ltl::LTL_NEGATION],
$2,
Configuration::OPERATOR_PRIORITY_RANGE);
}
| CFG_ORPRIORITY equals_value
{
parser_cfg->readInteger
(parser_cfg->formula_options.symbol_priority
[::Ltl::LTL_DISJUNCTION],
$2,
Configuration::OPERATOR_PRIORITY_RANGE);
}
| CFG_OUTPUTMODE equals_value
{
parser_cfg->readFormulaMode
(parser_cfg->formula_options.output_mode,
$2);
}
| CFG_PROPOSITIONPRIORITY equals_value
{
parser_cfg->readInteger
(parser_cfg->formula_options.symbol_priority
[::Ltl::LTL_ATOM],
$2,
Configuration::ATOMIC_PRIORITY_RANGE);
}
| CFG_PROPOSITIONS equals_value
{
parser_cfg->readInteger
(parser_cfg->formula_options.
formula_generator.
number_of_available_variables,
$2);
}
| CFG_RANDOMSEED equals_value
{
parser_cfg->readInteger
(parser_cfg->global_options.
formula_random_seed,
$2,
Configuration::RANDOM_SEED_RANGE);
}
| CFG_RELEASEPRIORITY equals_value
{
parser_cfg->readInteger
(parser_cfg->formula_options.symbol_priority
[::Ltl::LTL_V],
$2,
Configuration::OPERATOR_PRIORITY_RANGE);
}
| CFG_SIZE equals_value
{
parser_cfg->readSize
(Configuration::OPT_FORMULASIZE,
$2);
}
| CFG_STRONGRELEASEPRIORITY equals_value
{
parser_cfg->readInteger
(parser_cfg->formula_options.symbol_priority
[::Ltl::LTL_STRONG_RELEASE],
$2,
Configuration::OPERATOR_PRIORITY_RANGE);
}
| CFG_TRUEPRIORITY equals_value
{
parser_cfg->readInteger
(parser_cfg->formula_options.symbol_priority
[::Ltl::LTL_TRUE],
$2,
Configuration::ATOMIC_PRIORITY_RANGE);
}
| CFG_UNTILPRIORITY equals_value
{
parser_cfg->readInteger
(parser_cfg->formula_options.symbol_priority
[::Ltl::LTL_UNTIL],
$2,
Configuration::OPERATOR_PRIORITY_RANGE);
}
| CFG_WEAKUNTILPRIORITY equals_value
{
parser_cfg->readInteger
(parser_cfg->formula_options.symbol_priority
[::Ltl::LTL_WEAK_UNTIL],
$2,
Configuration::OPERATOR_PRIORITY_RANGE);
}
| CFG_XORPRIORITY equals_value
{
parser_cfg->readInteger
(parser_cfg->formula_options.symbol_priority
[::Ltl::LTL_XOR],
$2,
Configuration::OPERATOR_PRIORITY_RANGE);
}
;
%%
/******************************************************************************
*
* Function for reporting parse errors.
*
*****************************************************************************/
/* ========================================================================= */
void yyerror(const char* error_message)
/* ----------------------------------------------------------------------------
*
* Description: Function for reporting parse errors.
*
* Arguments: error_message -- An error message.
*
* Returns: Nothing. Instead, throws a
* Configuration::ConfigurationException initialized with the
* given error message.
*
* ------------------------------------------------------------------------- */
{
const string unknown_token(yytext);
string msg;
switch (expected_token)
{
case CFG_BLOCK_ID :
msg = "`" + unknown_token + "' is not a valid block identifier";
break;
case CFG_OPTION_ID :
if (!unknown_token.empty())
msg = "`" + unknown_token + "' is not a valid option identifier";
else
msg = "'}' expected at the end of block";
break;
case CFG_LBRACE :
msg = "`{' expected after block identifier";
break;
case CFG_EQUALS :
msg = "`=' expected after option identifier";
break;
case CFG_VALUE :
msg = "value for option expected";
break;
default :
msg = error_message;
break;
}
throw Configuration::ConfigurationException(config_file_line_number, msg);
}
/******************************************************************************
*
* Main interface to the parser.
*
*****************************************************************************/
/* ========================================================================= */
int parseConfiguration(FILE* stream, Configuration& configuration)
/* ----------------------------------------------------------------------------
*
* Description: Main interface to the configuration file parser. Parses the
* configuration file and stores the results into the given
* Configuration object.
*
* Arguments: stream -- A pointer to a file from which the
* configuration should be read. The file is
* assumed to be open for reading.
* configuration -- A reference to a Configuration object in
* which the configuration should be stored.
*
* Returns: The result of yyparse() on the file.
*
* ------------------------------------------------------------------------- */
{
yyrestart(stream);
parser_cfg = &configuration;
config_file_line_number = 1;
return yyparse();
}

View file

@ -1,16 +0,0 @@
// This is a hack to support both Automake <= 1.11.x, and Automake >=
// 1.12.x The problem with is that old versions used to create
// parse.h, and parse.cc from a parse.yxx grammar, while new versions
// create parse.hxx and parse.cc.
//
// We want to support both version of Automake, because 1.11.x is
// fairly well distributed, and 1.12 did not make it into Debian 7.0.
//
// Yet it's difficult to support both versions because of the name
// change. Our hack is to rename parse.yxx as parse.y, so that
// automake will generate rule to build parse.h and parse.c, and then
// this parse_.cc file is used to compile parse.c in C++. This way we
// always have a parse.h file regardless of the Automake version.
//
// We can fix this mess once Automake 1.12 is available everywhere.
#include "Config-parse.c"

File diff suppressed because it is too large Load diff

View file

@ -1,784 +0,0 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* 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 CONFIGURATION_H
#define CONFIGURATION_H
#include <config.h>
#include <cstdio>
#include <iostream>
#include <map>
#include <set>
#include <string>
#include <utility>
#include <vector>
#include "LbttAlloc.h"
#include "Exception.h"
#include "FormulaRandomizer.h"
#include "StateSpaceRandomizer.h"
#include "StringUtil.h"
using namespace std;
/******************************************************************************
*
* A class for storing program configuration information.
*
*****************************************************************************/
class Configuration
{
public:
Configuration(); /* Constructor. */
~Configuration(); /* Destructor. */
void read(int argc, char* argv[]); /* Reads the program
* configuration.
*/
void print /* Writes the current */
(ostream& stream = cout, int indent = 0) const; /* configuration (in a
* textual form) to a
* stream.
*/
struct AlgorithmInformation; /* See below. */
string algorithmString /* Formats the the id */
(vector<AlgorithmInformation>::size_type /* of an algorithm and */
algorithm_id) const; /* the name of the
* algorithm into a
* string.
*/
bool isInternalAlgorithm(unsigned long int id) /* Tests whether a given */
const; /* algorithm identifier
* refers to lbtt's
* internal model
* checking algorithm.
*/
static void showCommandLineHelp /* Prints the list of */
(const char* program_name); /* command line options. */
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
enum InteractionMode {NEVER, ALWAYS, ONERROR, /* Enumeration constants */
ONBREAK}; /* affecting the
* behavior of the
* program as regards
* user control.
*/
enum FormulaMode {NORMAL, NNF}; /* Enumeration constants
* affecting the generation
* and output of random
* formulae.
*/
enum StateSpaceMode {RANDOMGRAPH = 1, /* Enumeration constants */
RANDOMCONNECTEDGRAPH = 2, /* affecting the */
GRAPH = 3, /* generation of random */
RANDOMPATH = 4, /* state spaces. */
ENUMERATEDPATH = 8,
PATH = 12};
enum ProductMode {LOCAL, GLOBAL}; /* Enumeration constants
* for controlling the
* scope of synchronous
* products.
*/
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
struct AlgorithmInformation /* A structure for storing
* information about a
* particular algorithm
* (name, path to
* executable, command-line
* parameters).
*/
{
string name; /* Name of the algorithm.
*/
char** parameters; /* Command-line parameters
* required for running
* the executable. See
* the documentation for
* the registerAlgorithm
* function (in
* Configuration.cc) for
* more information.
*/
vector<string>::size_type num_parameters; /* Number of command-line
* parameters.
*/
bool enabled; /* Determines whether the
* algorithm is enabled
* (whether it will be used
* in the tests or not).
*/
};
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
struct GlobalConfiguration /* A structure for storing
* all the information
* affecting the general
* behaviour of the
* program.
*/
{
int verbosity; /* Determines the verbosity
* of program output (0-5,
* the bigger the value,
* the more information
* will be shown).
*/
InteractionMode interactive; /* Controls the behaviour
* of the program as
* regards the ability of
* the user to enter
* commands between test
* rounds. Possible values
* and their meanings are:
*
* NEVER:
* Run all tests without
* interruption.
* ALWAYS:
* Pause after each test
* round to wait for
* user commands.
* ONERROR:
* Try to run the tests
* without interruption.
* However, in case of
* an error, pause and
* wait for user
* 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 init_skip; /* Number of rounds to skip
* before starting testing.
*/
unsigned long int statespace_change_interval; /* Determines the frequency
* (in rounds) of how often
* a new state space is
* generated.
*/
StateSpaceMode statespace_generation_mode; /* Random state space
* generation mode.
* Available options are:
*
* RANDOMGRAPH:
* Generate random
* connected graphs as
* state spaces.
* RANDOMPATH:
* Generate paths as
* state spaces, choose
* the loop and the
* truth assignments for
* atomic propositions
* randomly.
* ENUMERATEDPATH:
* Generate paths as
* state spaces by
* enumerating all
* possible paths of a
* given length.
*/
unsigned long int formula_change_interval; /* Determines the frequency
* (in rounds) of how often
* a new formula is
* generated.
*/
ProductMode product_mode; /* Determines the scope of
* the synchronous products
* computed by the program.
* Possible values and
* their meanings are:
*
* LOCAL:
* The synchronous
* products are computed
* only with respect to
* the initial state of
* the system. This will
* save memory but makes
* the algorithm cross-
* comparisons less
* powerful, possibly
* at the cost of
* chances for finding
* inconsistencies in the
* results.
* GLOBAL:
* The synchronous
* products are computed
* with respect to each
* system state (i.e.
* the formula is model
* checked in each system
* state separately).
* This will usually
* require more memory
* than the other
* alternative.
*/
string cfg_filename; /* Name for the
* configuration file.
*/
string transcript_filename; /* Name for the error log
* file.
*/
string formula_input_filename; /* Name for the file from
* which to read LTL
* formulae.
*/
bool do_comp_test; /* Is the model checking
* result cross-comparison
* test enabled?
*/
bool do_cons_test; /* Is the model checking
* result consistency check
* enabled?
*/
bool do_intr_test; /* Is the automata
* intersection emptiness
* check enabled?
*/
unsigned int statespace_random_seed; /* Random seeds for the */
unsigned int formula_random_seed; /* state space and
* formula generation
* algorithms.
*/
unsigned int translator_timeout; /* Timeout (in seconds) for
* translators.
*/
};
struct FormulaConfiguration /* A structure for storing
* specific information
* affecting the generation
* of random formulae.
*/
{
int default_operator_priority; /* Default priority for all
* LTL formula symbols.
*/
map<int, int> symbol_priority; /* Priorities for LTL
* formula symbols.
*/
map<int, double> symbol_distribution; /* Expected numbers of
* occurrence for the
* different formula
* operators.
*/
bool allow_abbreviated_operators; /* Determines whether the
* operators ->, <->, xor,
* <>, [], W and M should
* be allowed when
* generating random
* formulae (these are
* `abbreviated' operators
* since they could be
* written in an equivalent
* form by using another
* operators).
*/
Configuration::FormulaMode output_mode; /* Determines whether the
* generated formulae are
* to be converted to
* negation normal form
* before passing them to
* the different
* algorithms. Possible
* values are:
*
* NORMAL:
* No conversion.
* NNF:
* Do the conversion
* (this may affect the
* size of the formulae!)
*/
Configuration::FormulaMode generate_mode; /* Determines whether the
* formulae are to be
* generated in negation
* normal form (strict
* size requirement for
* formulae). Possible
* values are:
*
* NORMAL:
* Allow more flexibility
* in the generation of
* formulae.
* NNF:
* Force generation into
* negation normal form.
*/
::Ltl::FormulaRandomizer formula_generator; /* Interface to the random
* LTL formula generation
* algorithm.
*/
};
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
vector<AlgorithmInformation> algorithms; /* A vector containing
* information about the
* algorithms used in
* the tests.
*/
map<string, unsigned long int> algorithm_names; /* Mapping between
* algorithm names and
* their numeric
* identifiers.
*/
GlobalConfiguration global_options; /* General configuration
* information.
*/
FormulaConfiguration formula_options; /* Configuration
* information for
* generating random
* formulae.
*/
Graph::StateSpaceRandomizer /* Interface to the */
statespace_generator; /* random state space
* generation
* algorithms.
*/
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
class ConfigurationException : public Exception /* A class for reporting
* errors when reading
* the configuration file.
*/
{
public:
ConfigurationException /* Constructors. */
(const string& info = "",
const string& msg = "");
ConfigurationException
(int line_number = -1,
const string& msg = "");
~ConfigurationException() throw(); /* Destructor. */
/* default copy constructor */
ConfigurationException& operator= /* Assignment operator. */
(const ConfigurationException& e);
/* `what' inherited from class Exception */
/* `changeMessage' inherited from class Exception */
string line_info; /* Error context
* information.
*/
};
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
private:
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
struct IntegerRange /* Data structure for
* representing integer-
* valued ranges of certain
* program configuration
* options.
*/
{
unsigned long int min; /* Lower bound. */
unsigned long int max; /* Upper bound. */
const char* error_message; /* Error message to be
* displayed if the value
* is not within the
* specified range.
*/
};
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/* Ranges for certain integer-valued configuration options. */
static const struct IntegerRange
DEFAULT_RANGE, VERBOSITY_RANGE,
ROUND_COUNT_RANGE, RANDOM_SEED_RANGE,
ATOMIC_PRIORITY_RANGE, OPERATOR_PRIORITY_RANGE;
/* Command line options. */
enum CommandLineOptionType
{OPT_HELP = 'h', OPT_VERSION = 'V',
OPT_COMPARISONTEST = 10000, OPT_CONFIGFILE,
OPT_CONSISTENCYTEST, OPT_DISABLE, OPT_ENABLE,
OPT_FORMULACHANGEINTERVAL,
OPT_FORMULAFILE, OPT_FORMULARANDOMSEED,
OPT_GLOBALPRODUCT, OPT_INTERACTIVE,
OPT_INTERSECTIONTEST, OPT_LOGFILE,
OPT_MODELCHECK, OPT_PROFILE, OPT_QUIET,
OPT_ROUNDS, OPT_SHOWCONFIG,
OPT_SHOWOPERATORDISTRIBUTION, OPT_SKIP,
OPT_STATESPACECHANGEINTERVAL,
OPT_STATESPACERANDOMSEED,
OPT_TRANSLATORTIMEOUT, OPT_VERBOSITY,
OPT_LOCALPRODUCT,
OPT_ABBREVIATEDOPERATORS, OPT_ANDPRIORITY,
OPT_BEFOREPRIORITY,
OPT_DEFAULTOPERATORPRIORITY,
OPT_EQUIVALENCEPRIORITY, OPT_FALSEPRIORITY,
OPT_FINALLYPRIORITY,OPT_FORMULAGENERATEMODE,
OPT_FORMULAOUTPUTMODE,
OPT_FORMULAPROPOSITIONS, OPT_FORMULASIZE,
OPT_GENERATENNF, OPT_GLOBALLYPRIORITY,
OPT_IMPLICATIONPRIORITY, OPT_NEXTPRIORITY,
OPT_NOGENERATENNF, OPT_NOOUTPUTNNF,
OPT_NOTPRIORITY, OPT_ORPRIORITY,
OPT_OUTPUTNNF, OPT_PROPOSITIONPRIORITY,
OPT_RELEASEPRIORITY,
OPT_STRONGRELEASEPRIORITY, OPT_TRUEPRIORITY,
OPT_UNTILPRIORITY, OPT_WEAKUNTILPRIORITY,
OPT_XORPRIORITY,
OPT_EDGEPROBABILITY,
OPT_ENUMERATEDPATH, OPT_RANDOMCONNECTEDGRAPH,
OPT_RANDOMGRAPH, OPT_RANDOMPATH,
OPT_STATESPACEGENERATEMODE,
OPT_STATESPACEPROPOSITIONS,
OPT_STATESPACESIZE, OPT_TRUTHPROBABILITY};
typedef map<pair<int, int>, double> /* Type definitions for */
ProbabilityMapElement; /* the result cache used */
/* for computing the */
typedef map<int, ProbabilityMapElement> /* probability */
ProbabilityMap; /* distribution of LTL
* formula operators.
*/
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
friend int yyparse();
Configuration(const Configuration& cfg); /* Prevent copying and */
Configuration& operator= /* assignment of */
(const Configuration& cfg); /* Configuration
* objects.
*/
void reset(); /* Initializes the
* configuration data
* to default values.
*/
void registerAlgorithm /* Adds a new algorithm */
(const string& name, const string& path, /* to the configuration. */
const string& parameters, bool enabled,
const int block_begin_line);
template<typename T> /* Reads an integer, */
void readInteger /* checks that it is */
(T& target, const string& value, /* within given bounds */
const IntegerRange& range = DEFAULT_RANGE); /* and stores it into
* an unsigned integer
* type variable.
*/
void readProbability /* Reads a probability */
(double& target, const string& value); /* and stores it into
* a given variable of
* type double.
*/
void readSize(int valtype, const string& value); /* Initializes formula or
* state space size
* ranges from a given
* string.
*/
void readTruthValue /* Interprets a symbolic */
(bool& target, const string& value); /* truth value. */
void readInteractivity(const string& value); /* Interprets a symbolic
* interactivity mode.
*/
void readProductType(const string& value); /* Interprets a symbolic
* model checking mode.
*/
void readFormulaMode /* Interprets a symbolic */
(FormulaMode& target, const string& mode); /* formula mode.
*/
void readStateSpaceMode(const string& mode); /* Initializes
* `global_options.
* statespace_generation
* _mode' from a
* symbolic mode
* identifier.
*/
void readTranslatorTimeout(const string& value); /* Initializes
* `global_options.
* translator_timeout'
* from a symbolic time
* specification.
*/
double operatorProbability /* Computes the */
(const int op, const int k, const int n, /* probability with */
const int total_short_unary_priority, /* which the operator */
const int total_long_unary_priority, /* `op' will occur */
const int total_binary_priority, /* exactly `k' times in */
ProbabilityMap& result_cache) const; /* a randomly generated
* formula of size `n'.
*/
};
/******************************************************************************
*
* 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 Configuration::ConfigurationException::ConfigurationException
(const string& info, const string& msg) :
Exception(msg), line_info(info)
/* ----------------------------------------------------------------------------
*
* Description: Constructor for class Configuration::ConfigurationException.
* Creates a new exception object, initializing it with an
* error message and optional context information.
*
* Arguments: info -- Configuration file line number information (for
* telling about the context of the error).
* msg -- A reference to a constant string containing the
* error message.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
inline Configuration::ConfigurationException::ConfigurationException
(int line_number, const string& msg) :
Exception(msg), line_info(line_number == -1
? string("")
: ::StringUtil::toString(line_number))
/* ----------------------------------------------------------------------------
*
* Description: Constructor for class Configuration::ConfigurationException.
* Creates a new exception object, initializing it with an
* error message and configuration file line number.
*
* Arguments: line_number -- Number of the line with an error (if -1,
* no context info is assumed to be present).
* msg -- A reference to a constant string containing
* the error message.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
inline Configuration::ConfigurationException::~ConfigurationException() throw()
/* ----------------------------------------------------------------------------
*
* Description: Destructor for class Configuration::ConfigurationException.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
inline Configuration::ConfigurationException&
Configuration::ConfigurationException::operator=
(const ConfigurationException& e)
/* ----------------------------------------------------------------------------
*
* Description: Assignment operator for class
* Configuration::ConfigurationException. Assigns the value of
* another Configuration::ConfigurationException to `this' one.
*
* Arguments: e -- A reference to a constant
* Configuration::ConfigurationException.
*
* Returns: A reference to the object whose value was changed.
*
* ------------------------------------------------------------------------- */
{
Exception::operator=(e);
line_info = e.line_info;
return *this;
}
#endif /* !CONFIGURATION_H */

View file

@ -1,179 +0,0 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* 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.
*/
#include <config.h>
#include <deque>
#include <stack>
#include "LbttAlloc.h"
#include "DispUtil.h"
/******************************************************************************
*
* Functions for displaying various statistics during testing.
*
*****************************************************************************/
namespace DispUtil
{
stack<StreamFormatting, deque<StreamFormatting> > /* Stack for storing the */
stream_formatting_stack; /* previous states of an
* output stream.
*/
/* ========================================================================= */
void changeStreamFormatting
(ostream& stream, int width, int precision, ios::fmtflags flags)
/* ----------------------------------------------------------------------------
*
* Description: Changes the formatting state of an output stream, storing its
* previous state so that it can be restored later.
*
* Arguments: stream -- A reference to an output stream.
* width -- Field width.
* precision -- Floating-point precision.
* flags -- Flags affecting e.g. output justification.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
StreamFormatting formatting;
formatting.width = stream.width(width);
formatting.precision = stream.precision(precision);
formatting.flags = stream.flags(flags);
stream_formatting_stack.push(formatting);
}
/* ========================================================================= */
void restoreStreamFormatting(ostream& stream)
/* ----------------------------------------------------------------------------
*
* Description: Restores the formatting state of an output stream whose
* previous state was saved by a call to
* changeStreamFormatting.
*
* Arguments: stream -- A reference to an output stream.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
if (!stream_formatting_stack.empty())
{
StreamFormatting formatting = stream_formatting_stack.top();
stream_formatting_stack.pop();
stream.width(formatting.width);
stream.precision(formatting.precision);
stream.flags(formatting.flags);
}
}
/* ========================================================================= */
void printTextBlock
(ostream& stream, int indent, const string& text, int max_line_len)
/* ----------------------------------------------------------------------------
*
* Description: Writes a string of text to a stream, breaking the text to
* multiple indented lines of a given maximum length if
* required.
*
* Arguments: stream -- A reference to an output stream.
* indent -- Number of spaces to leave on the left of
* each printed line.
* text -- Text to be written to the stream. '\n':s
* can be used in the text to insert
* additional line breaks to the output.
* max_line_len -- Maximum allowed line length (including the
* amount of indentation).
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
Exceptional_ostream estream(&stream, ios::failbit | ios::badbit);
string::size_type max_len, current_pos = 1;
const string ind = string(indent, ' ');
if (indent > max_line_len)
max_len = 0;
else
max_len = max_line_len - indent;
string word;
string::const_iterator c = text.begin();
while (c != text.end() || !word.empty())
{
if (c == text.end() || *c == ' ' || *c == '\t' || *c == '\n')
{
while (!word.empty())
{
if (current_pos == 1)
estream << ind;
string::size_type new_pos = current_pos + word.length();
if (current_pos > 1)
++new_pos;
if (new_pos > max_len)
{
if (current_pos == 1)
{
estream << word;
word = "";
}
estream << '\n';
current_pos = 1;
}
else
{
if (current_pos > 1)
estream << ' ';
estream << word;
word = "";
current_pos = new_pos;
}
}
if (c != text.end())
{
if (*c == '\n')
{
current_pos = 1;
estream << '\n';
}
++c;
}
}
else if (c != text.end())
{
word += *c;
++c;
}
}
estream << '\n';
estream.flush();
}
}

View file

@ -1,159 +0,0 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* 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 DISPUTIL_H
#define DISPUTIL_H
#include <config.h>
#include <iostream>
#include <string>
#include "Configuration.h"
#include "SharedTestData.h"
#include "TestRoundInfo.h"
using namespace std;
extern Configuration configuration;
/******************************************************************************
*
* Prototypes for miscellaneous routines for controlling output stream
* formatting and writing text into a stream.
*
*****************************************************************************/
namespace DispUtil
{
void changeStreamFormatting /* Changes the state of */
(ostream& stream, int width, int precision, /* an output stream and */
ios::fmtflags flags); /* saves its previous
* state.
*/
void restoreStreamFormatting(ostream& stream); /* Restores a previously
* saved state of an
* output stream.
*/
void printTextBlock /* Writes an indented */
(ostream& stream, int indent, const string& text, /* and word-wrapped */
int max_line_len); /* block of text into
* 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);
/******************************************************************************
*
* A data stucture for storing information about the state of an output stream.
*
*****************************************************************************/
struct StreamFormatting
{
int width; /* Field width. */
int precision; /* Floating-point
* precision.
*/
ios::fmtflags flags; /* Various flags affecting
* e.g. the justification
* of output.
*/
};
/******************************************************************************
*
* Functions for printing text on standard output.
*
*****************************************************************************/
/* ========================================================================= */
inline bool printText
(const char* text, const int verbosity_threshold, const int indent = 0)
/* ----------------------------------------------------------------------------
*
* Description: Writes text on the standard output if the current output
* verbosity level is greater or equal to a given threshold.
*
* Arguments: text -- Text to write.
* verbosity_threshold -- Verbosity level threshold.
* indent -- Number of spaces to print on the
* left of the text.
*
* ------------------------------------------------------------------------- */
{
if (configuration.global_options.verbosity >= verbosity_threshold)
{
if (indent > 0)
SharedTestData::round_info.cout << string(indent, ' ');
SharedTestData::round_info.cout << text;
SharedTestData::round_info.cout.flush();
return true;
}
return false;
}
/* ========================================================================= */
inline bool printText
(const string& text, const int verbosity_threshold, const int indent = 0)
/* ----------------------------------------------------------------------------
*
* Description: Writes text on the standard output if the current output
* verbosity level is greater or equal to a given threshold.
*
* Arguments: text -- Text to write.
* verbosity_threshold -- Verbosity level threshold.
* indent -- Number of spaces to print on the
* left of the text.
*
* Returns: `true' if anything was written to standard output.
*
* ------------------------------------------------------------------------- */
{
if (configuration.global_options.verbosity >= verbosity_threshold)
{
if (indent > 0)
SharedTestData::round_info.cout << string(indent, ' ');
SharedTestData::round_info.cout << text;
SharedTestData::round_info.cout.flush();
return true;
}
return false;
}
}
#endif /* !DISPUTIL_H */

View file

@ -1,28 +0,0 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* 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 EDGECONTAINER_H
#define EDGECONTAINER_H
#include <config.h>
#include "Graph.h"
typedef ::Graph::EdgeVector GraphEdgeContainer;
#endif /* !EDGECONTAINER_H */

File diff suppressed because it is too large Load diff

View file

@ -1,137 +0,0 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* 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.
*/
#include <config.h>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <sys/stat.h>
#include <sys/types.h>
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif /* HAVE_FCNTL_H */
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif /* HAVE_UNISTD_H */
#include <fstream>
#include "ExternalTranslator.h"
/******************************************************************************
*
* Function definitions for class ExternalTranslator.
*
*****************************************************************************/
/* ========================================================================= */
ExternalTranslator::~ExternalTranslator()
/* ----------------------------------------------------------------------------
*
* Description: Destructor for class ExternalTranslator.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
/*
* Delete all registered temporary files or directories in the reverse order
* of registration.
*/
while (!temporary_file_objects.empty())
{
delete temporary_file_objects.top();
temporary_file_objects.pop();
}
}
/* ========================================================================= */
const char* ExternalTranslator::registerTempFileObject
(const string& filename, const TempFsysName::NameType type,
const bool literal)
/* ----------------------------------------------------------------------------
*
* Description: Registers a temporary file or directory such that it will be
* automatically deleted when the ExternalTranslator object is
* destroyed.
*
* Arguments: filename -- Name of the temporary file or directory. If
* empty, a new name will be created.
* type -- Type of the object (TempFileObject::FILE or
* TempFileObject::DIRECTORY).
* literal -- Tells whether the file name should be
* interpreted literally.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
TempFsysName* name = new TempFsysName;
name->allocate(filename.c_str(), type, literal);
temporary_file_objects.push(name);
return name->get();
}
/* ========================================================================= */
void ExternalTranslator::translate
(const ::Ltl::LtlFormula& formula, const char* filename)
/* ----------------------------------------------------------------------------
*
* Description: Executes an external program which translates an LTL formula
* into a Büchi automaton and stores the automaton description
* in lbtt format into a file.
*
* Arguments: formula -- LTL formula to be translated.
* filename -- Name of the output file.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
const char* external_program_input_file
= registerTempFileObject("lbtt-translate");
const char* external_program_output_file
= registerTempFileObject("lbtt-translate");
string translated_formula;
translateFormula(formula, translated_formula);
ofstream input_file;
input_file.open(external_program_input_file, ios::out | ios::trunc);
if (!input_file.good())
throw FileCreationException(string("`") + external_program_input_file
+ "'");
Exceptional_ostream einput_file(&input_file, ios::failbit | ios::badbit);
formatInput(einput_file, translated_formula);
input_file.close();
string command_line = string(command_line_arguments[2])
+ commandLine(external_program_input_file,
external_program_output_file);
if (!execSuccess(system(command_line.c_str())))
throw ExecFailedException(command_line_arguments[2]);
parseAutomaton(external_program_output_file, filename);
}

View file

@ -1,309 +0,0 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* 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 EXTERNALTRANSLATOR_H
#define EXTERNALTRANSLATOR_H
#include <config.h>
#include <deque>
#include <stack>
#include <string>
#ifdef HAVE_SSTREAM
#include <sstream>
#else
#include <strstream>
#endif /* HAVE_SSTREAM */
#include "LbttAlloc.h"
#include "Exception.h"
#include "LtlFormula.h"
#include "translate.h"
#include "TempFsysName.h"
#include "TranslatorInterface.h"
/******************************************************************************
*
* Interface class for an LTL-to-Büchi translation algorithm operating as an
* external program. An actual implementation of this interface (a class
* derived from this base class) must provide definitions for the following
* functions:
*
* string commandLine
* (const string& input_filename, const string& output_filename)
* Formats the command line of the external translator such that the
* external program will read its input (i.e., an LTL formula) from
* `input_filename' and store its output into `output_filename'.
*
* The returned string should include _only_ the argument part of the
* command line (the returned string will be appended to the name of
* the program). Use input/output redirection in the string if the
* program does not have an option to explicitly specify an
* input/output file.
*
* void parseAutomaton
* (const string& input_filename, const string& output_filename)
* Reads the automaton constructed by the external program from
* `input_filename' and stores the automaton in lbtt syntax into
* `output_filename'.
*
* In addition, the implementation can override the default definitions for the
* following functions:
*
* void translateFormula
* (const LtlFormula& formula, string& translated_formula)
* Translates a given LtlFormula into the input syntax of the
* external translator. The result must be stored in
* `translated_formula'. The default implementation simply returns
* the formula in lbtt's prefix notation.
*
* void formatInput(Exceptional_ostream& stream, const string& formula)
* Prepares an input file for the external translator program.
* The default implementation simply writes `formula' (followed by a
* newline) into `stream'.
*
* bool execSuccess(int exitcode)
* Tests whether the execution of the external program was performed
* successfully by examining the exit status of the program (as
* returned by a call to `system'). The default implementation
* returns true if and only if `exitcode' has the value 0.
*
* When performing the translation, the above functions will be called in the
* following order:
* 1. translateFormula (translate the input formula into the external
* program syntax)
* 2. formatInput (write the translated formula into a file)
* 3. commandLine (construct the command line required for executing
* the external translator)
* 4. execSuccess (test whether the execution succeeded)
* 5. parseAutomaton (translate the constructed automaton into lbtt
* format)
*
* The interface class additionally provides a function to help deleting any
* temporary files or directories that might be created during the execution of
* the external program, provided that their names are static or can be derived
* from the names of the input/output files. Each of these files should be
* "registered" before calling the external program with the function
*
* const char* registerTempFileObject
* (const string& filename, const TempFsysName::NameType t,
* const bool literal)
*
* where `filename' is the prefix of a temporary file name, `t' is a type
* of the object (TempFsysName::FILE or TempFsysName::DIRECTORY), and
* `literal' specifies whether `filename' should be interpreted literally or
* not (if not, `filename' will be treated as a suggestion for the name
* of the temporary file). If the name is to be interpreted literally,
* `filename' should contain the full path name of the temporary file to be
* created. In all cases, the function returns the full path name of the
* temporary file or directory, or it throws an IOException (defined in
* Exception.h) if the creation fails.
*
* All files or directories registered using this function will be
* automatically deleted after the translation is finished or aborted.
* The files or directories will be deleted in the reverse order of
* registration, i.e., the most recently registered file/directory will be
* deleted first.
*
*****************************************************************************/
class ExternalTranslator : public TranslatorInterface
{
public:
ExternalTranslator(); /* Constructor. */
~ExternalTranslator(); /* Destructor. */
const char* registerTempFileObject /* Registers a temporary */
(const string& filename = "", /* file or directory */
const TempFsysName::NameType /* such that it will be */
t = TempFsysName::FILE, /* automatically deleted */
const bool literal = false); /* when the translation
* is complete.
*/
void translate /* Main translation */
(const ::Ltl::LtlFormula& formula, /* function. */
const char* filename);
virtual void translateFormula /* Translates an */
(const ::Ltl::LtlFormula& formula, /* LtlFormula into */
string& translated_formula); /* the syntax of some
* external program.
*/
virtual void formatInput /* Prepares an input */
(Exceptional_ostream& stream, /* file for an external */
const string& formula); /* translator. */
virtual string commandLine /* Constructs the */
(const string& input_filename, /* argument part of the */
const string& output_filename) = 0; /* command line for
* an external
* translator.
*/
virtual bool execSuccess(int exitcode); /* Tests whether the
* execution of the
* external translator was
* successful.
*/
virtual void parseAutomaton /* Translates the */
(const string& input_filename, /* automaton description */
const string& output_filename) = 0; /* into lbtt format. */
private:
ExternalTranslator(const ExternalTranslator&); /* Prevent copying and */
ExternalTranslator& operator= /* assignment of */
(const ExternalTranslator&); /* ExternalTranslator
* objects.
*/
stack<TempFsysName*, deque<TempFsysName*> > /* Stack for storing */
temporary_file_objects; /* temporary file
* information.
*/
friend class SpinWrapper; /* Friend declarations. */
friend class SpotWrapper;
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
class WriterErrorReporter /* Class for reporting */
{ /* about unsupported */
public: /* input formula */
static void write /* operators. */
(Exceptional_ostream&, int);
};
};
/******************************************************************************
*
* Inline function definitions for class ExternalTranslator.
*
*****************************************************************************/
/* ========================================================================= */
inline ExternalTranslator::ExternalTranslator()
/* ----------------------------------------------------------------------------
*
* Description: Constructor for class ExternalTranslator.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
inline void ExternalTranslator::translateFormula
(const ::Ltl::LtlFormula& formula, string& translated_formula)
/* ----------------------------------------------------------------------------
*
* Description: Converts an LtlFormula object into a string.
*
* Arguments: formula -- An LtlFormula.
* translated_formula -- A reference to a string for storing
* the result.
*
* Returns: Nothing. The result can be found in the string
* `translated_formula'.
*
* ------------------------------------------------------------------------- */
{
#ifdef HAVE_SSTREAM
ostringstream formula_stream;
formula.print(formula_stream, ::Ltl::LTL_PREFIX);
translated_formula = formula_stream.str();
#else
ostrstream formula_stream;
formula.print(formula_stream, ::Ltl::LTL_PREFIX);
formula_stream << ends;
translated_formula = formula_stream.str();
formula_stream.freeze(0);
#endif /* HAVE_SSTREAM */
}
/* ========================================================================= */
inline void ExternalTranslator::formatInput
(Exceptional_ostream& stream, const string& formula)
/* ----------------------------------------------------------------------------
*
* Description: Writes a string (assumed to contain an LTL formula in the
* input format of some external translator program) followed by
* a newline into a stream.
*
* Arguments: stream -- A reference to an Exceptional_ostream.
* formula -- A reference to a constant string assumed to
* contain an LTL formula.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
stream << formula << '\n';
}
/* ========================================================================= */
inline bool ExternalTranslator::execSuccess(int exitcode)
/* ----------------------------------------------------------------------------
*
* Description: Tests whether the exit status of an external program is 0.
*
* Arguments: exitcode -- Exit status of an external program as reported
* by a call to `system'.
*
* Returns: `true' if the exit status is equal to 0.
*
* ------------------------------------------------------------------------- */
{
return (exitcode == 0);
}
/******************************************************************************
*
* Inline function definitions for class
* ExternalTranslator::WriterErrorReporter.
*
*****************************************************************************/
/* ========================================================================= */
inline void ExternalTranslator::WriterErrorReporter::write
(Exceptional_ostream&, int)
/* ----------------------------------------------------------------------------
*
* Description: Aborts the formula translation if the formula contains an
* unsupported operator.
*
* Arguments: The arguments are required only for supporting the function
* call interface.
*
* Returns: Nothing. Instead, throws an Exception with an error message.
*
* ------------------------------------------------------------------------- */
{
throw Exception("unsupported operators in formula");
}
#endif /* !EXTERNALTRANSLATOR_H */

View file

@ -1,229 +0,0 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* 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.
*/
#include <config.h>
#include "FormulaRandomizer.h"
#include "Random.h"
namespace Ltl
{
/******************************************************************************
*
* Function definitions for class FormulaRandomizer.
*
*****************************************************************************/
/* ========================================================================= */
void FormulaRandomizer::reset()
/* ----------------------------------------------------------------------------
*
* Description: Sets the random formula generation parameters to their
* default values.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
number_of_available_variables = 5;
size = 5;
max_size = 5;
propositional_symbol_priorities.clear();
short_formula_operators.clear();
long_formula_operators.clear();
propositional_symbol_priorities.push_back(make_pair(-1, 0));
short_formula_operators.push_back(make_pair(-1, 0));
long_formula_operators.push_back(make_pair(-1, 0));
number_of_generated_formulas = 0;
proposition_statistics.clear();
symbol_statistics.clear();
}
/* ========================================================================= */
LtlFormula* FormulaRandomizer::generate()
/* ----------------------------------------------------------------------------
*
* Description: Generates a random (newly allocated) LtlFormula using the
* parameters stored in `this' object.
*
* Arguments: None.
*
* Returns: A pointer to the generated formula.
*
* ------------------------------------------------------------------------- */
{
unsigned long int target_size(size);
if (max_size > size)
target_size += LRAND(0, max_size - size + 1);
number_of_generated_formulas++;
return recGenerate(target_size);
}
/* ========================================================================= */
LtlFormula* FormulaRandomizer::recGenerate(unsigned long int target_size)
/* ----------------------------------------------------------------------------
*
* Description: Implementation of the recursive random formula generation
* algorithm.
*
* Arguments: target_size -- Size of the formula to be generated.
*
* Returns: A pointer to the generated formula.
*
* ------------------------------------------------------------------------- */
{
vector<IntegerPair>::const_iterator symbol_priority;
LtlFormula* formula;
long int x;
/*
* Select a list of allowable symbols according to the target size. If the
* size is 1, only atomic propositions and Boolean constants are allowed
* If the size is 2, only unary operators are allowed. Otherwise select the
* symbols from the set of unary and binary operators.
*/
switch (target_size)
{
case 1 :
x = LRAND(0, propositional_symbol_priorities[0].second);
symbol_priority = propositional_symbol_priorities.begin();
break;
case 2 :
x = LRAND(0, short_formula_operators[0].second);
symbol_priority = short_formula_operators.begin();
break;
default :
x = LRAND(0, long_formula_operators[0].second);
symbol_priority = long_formula_operators.begin();
break;
}
/*
* Using the selected list, choose a random symbol in the list using the
* priority distribution of the different symbols in the list. The list
* consists of <symbol, priority> pairs. The first element of the list does
* not correspond to any symbol, however; instead, it gives the sum of the
* priorities of the symbols in the list.
*/
++symbol_priority;
while (x >= symbol_priority->second)
{
x -= symbol_priority->second;
++symbol_priority;
}
symbol_statistics[symbol_priority->first]++;
switch (symbol_priority->first)
{
case LTL_ATOM :
{
unsigned long int atom = LRAND(0, number_of_available_variables);
proposition_statistics[atom]++;
formula = &Atom::construct(atom);
break;
}
case LTL_TRUE :
formula = &True::construct();
break;
case LTL_FALSE :
formula = &False::construct();
break;
case LTL_NEGATION :
formula = &Not::construct(recGenerate(target_size - 1));
break;
case LTL_NEXT :
formula = &Next::construct(recGenerate(target_size - 1));
break;
case LTL_FINALLY :
formula = &Finally::construct(recGenerate(target_size - 1));
break;
case LTL_GLOBALLY :
formula = &Globally::construct(recGenerate(target_size - 1));
break;
default :
{
unsigned long int s = LRAND(1, target_size - 1);
LtlFormula* g = recGenerate(s);
LtlFormula* h = recGenerate(target_size - s - 1);
switch (symbol_priority->first)
{
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;
}
}
}
return formula;
}
}

View file

@ -1,329 +0,0 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* 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 FORMULARANDOMIZER_H
#define FORMULARANDOMIZER_H
#include <config.h>
#include <map>
#include <vector>
#include <utility>
#include "LbttAlloc.h"
#include "LtlFormula.h"
namespace Ltl
{
/******************************************************************************
*
* Class for generating random LTL formulae.
*
*****************************************************************************/
class FormulaRandomizer
{
public:
FormulaRandomizer(); /* Constructor. */
/* default copy constructor */
~FormulaRandomizer(); /* Destructor. */
/* default assignment operator */
void reset(); /* Resets the formula
* generation parameters.
*/
void useSymbol /* Inserts an atomic */
(const int symbol, const int priority); /* symbol (an atomic
* proposition or a
* Boolean constant)
* into the set of
* operands used for
* generating random
* formulae.
*/
void useShortOperator /* Inserts an element */
(const int symbol, const int priority); /* into the set of
* operators used for
* generating random
* formulae of size
* two.
*/
void useLongOperator /* Inserts an element */
(const int symbol, const int priority); /* into the set of
* operators used for
* generating random
* formulae of size
* greater than two.
*/
LtlFormula* generate(); /* Generates a random LTL
* formula.
*/
unsigned long int numberOfFormulas() const; /* Get the number of
* generated formulas since
* the last call to
* `reset'.
*/
const map<unsigned long int, unsigned long int>& /* Get the numbers of */
propositionStatistics() const; /* different atomic
* propositions
* generated since the
* last call to `reset'.
*/
const map<int, unsigned long int>& /* Get the numbers of */
symbolStatistics() const; /* different symbols
* generated since the
* last call to `reset'.
*/
unsigned long int number_of_available_variables; /* Size of the set of
* atomic propositions used
* for generating random
* LTL formulae.
*/
unsigned long int size; /* Minimum size of the
* generated formulae
* (number of nodes in the
* formula parse tree).
*/
unsigned long int max_size; /* Maximum size of the
* generated formulae.
*/
private:
LtlFormula* recGenerate /* Implementation of */
(unsigned long int target_size); /* the random formula
* generation algorithm.
*/
typedef pair<int, int> IntegerPair;
vector<IntegerPair> /* Operand symbols and */
propositional_symbol_priorities; /* their priorities in
* random formulae.
*/
vector<IntegerPair> short_formula_operators; /* Operators and their
* priorities in random
* formulae of size two.
*/
vector<IntegerPair> long_formula_operators; /* Operators and their
* priorities in random
* formulae of size greater
* than two.
*/
unsigned long int number_of_generated_formulas; /* Number of generated
* formulas since the
* last call to `reset'.
*/
map<unsigned long int, unsigned long int> /* Number of different */
proposition_statistics; /* atomic propositions
* generated since the
* last call to `reset'
*/
map<int, unsigned long int> symbol_statistics; /* Number of different
* formula symbols
* generated since the
* last call to `reset'.
*/
};
/******************************************************************************
*
* Inline function definitions for class FormulaRandomizer.
*
*****************************************************************************/
/* ========================================================================= */
inline FormulaRandomizer::FormulaRandomizer()
/* ----------------------------------------------------------------------------
*
* Description: Constructor for class FormulaRandomizer. Creates a new
* formula parameter information object and initializes the
* generation parameters with their default values.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
reset();
}
/* ========================================================================= */
inline FormulaRandomizer::~FormulaRandomizer()
/* ----------------------------------------------------------------------------
*
* Description: Destructor for class FormulaRandomizer.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
inline void FormulaRandomizer::useSymbol(const int symbol, const int priority)
/* ----------------------------------------------------------------------------
*
* Description: Inserts an atomic symbol (an atomic proposition or a Boolean
* constant) into the set of symbols used for generating random
* LTL formulae. The symbol will then be chosen into a formula
* by the random formula generation algorithm with a given
* priority.
*
* Arguments: symbol -- A symbol type identifier (one of the LTL_
* constants defined in LtlFormula.h).
* priority -- Priority for the symbol.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
if (priority > 0)
{
propositional_symbol_priorities.push_back(make_pair(symbol, priority));
propositional_symbol_priorities[0].second += priority;
}
}
/* ========================================================================= */
inline void FormulaRandomizer::useShortOperator
(const int symbol, const int priority)
/* ----------------------------------------------------------------------------
*
* Description: Inserts a symbol into the set of operators considered when
* generating random LTL formulae with two nodes in their parse
* tree. The symbol will then be chosen into a formula by the
* random formula generation algorithm with a given priority.
*
* Arguments: symbol -- A symbol type identifier (one of the LTL_
* constants defined in LtlFormula.h).
* priority -- Priority for the symbol.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
if (priority > 0)
{
short_formula_operators.push_back(make_pair(symbol, priority));
short_formula_operators[0].second += priority;
}
}
/* ========================================================================= */
inline void FormulaRandomizer::useLongOperator
(const int symbol, const int priority)
/* ----------------------------------------------------------------------------
*
* Description: Inserts a symbol into the set of operators considered when
* generating random LTL formulae with two nodes in their parse
* tree. The symbol will then be chosen into a formula by the
* random formula generation algorithm with a given priority.
*
* Arguments: symbol -- A symbol type identifier (one of the LTL_
* constants defined in LtlFormula.h).
* priority -- Priority for the symbol.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
if (priority > 0)
{
long_formula_operators.push_back(make_pair(symbol, priority));
long_formula_operators[0].second += priority;
}
}
/* ========================================================================= */
inline unsigned long int FormulaRandomizer::numberOfFormulas() const
/* ----------------------------------------------------------------------------
*
* Description: Tells the number of formulae generated since the last call to
* `reset'.
*
* Arguments: None.
*
* Returns: Number of formulae generated since the last call to `reset'.
*
* ------------------------------------------------------------------------- */
{
return number_of_generated_formulas;
}
/* ========================================================================= */
inline const map<unsigned long int, unsigned long int>&
FormulaRandomizer::propositionStatistics() const
/* ----------------------------------------------------------------------------
*
* Description: Tells the number of different atomic propositions generated
* since the last call to `reset'.
*
* Arguments: None.
*
* Returns: A reference to a constant mapping between proposition
* identifiers and their numbers.
*
* ------------------------------------------------------------------------- */
{
return proposition_statistics;
}
/* ========================================================================= */
inline const map<int, unsigned long int>&
FormulaRandomizer::symbolStatistics() const
/* ----------------------------------------------------------------------------
*
* Description: Tells the number of different formula symbols generated since
* the last call to `reset'.
*
* Arguments: None.
*
* Returns: A reference to a constant mapping between LTL formula symbols
* and their numbers.
*
* ------------------------------------------------------------------------- */
{
return symbol_statistics;
}
}
#endif /* !FORMULARANDOMIZER_H */

View file

@ -1,450 +0,0 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* 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 FORMULAWRITER_H
#define FORMULAWRITER_H
#include "Exception.h"
#include "LtlFormula.h"
namespace Ltl
{
/******************************************************************************
*
* A function template class for writing the formula to a stream.
*
*****************************************************************************/
template<class TrueWriter, class FalseWriter, class AtomWriter,
class NotWriter, class NextWriter, class FinallyWriter,
class GloballyWriter, class AndWriter, class OrWriter,
class ImplyWriter, class EquivWriter, class XorWriter,
class UntilWriter, class ReleaseWriter, class WeakUntilWriter,
class StrongReleaseWriter, class BeforeWriter>
class FormulaWriter
{
public:
FormulaWriter(Exceptional_ostream& stream); /* Constructor. */
~FormulaWriter(); /* Destructor. */
void operator() /* Implements the write */
(const LtlFormula* f, int operand); /* operation. */
private:
Exceptional_ostream& estream; /* Output stream. */
FormulaWriter(const FormulaWriter&); /* Prevent copying and */
FormulaWriter& operator=(const FormulaWriter&); /* assignment of
* FormulaWriter
* objects.
*/
};
/******************************************************************************
*
* Class for printing atomic propositions.
*
*****************************************************************************/
class AtomWriter
{
public:
static void write /* Implements the write */
(Exceptional_ostream& estream, /* operation. */
long int atom_id);
};
/******************************************************************************
*
* Template class for printing Boolean constants.
*
*****************************************************************************/
template<const char* symbol>
class ConstantWriter
{
public:
static void write(Exceptional_ostream& estream); /* Implements the write */
}; /* operation. */
/******************************************************************************
*
* Template class for printing unary operators.
*
*****************************************************************************/
template<const char* symbol>
class UnaryOperatorWriter
{
public:
static void write /* Implements the write */
(Exceptional_ostream& estream, int operand); /* operation. */
};
/******************************************************************************
*
* Template class for printing binary operators in prefix notation.
*
*****************************************************************************/
template<const char* symbol>
class BinaryOperatorPrefixWriter
{
public:
static void write /* Implements the write */
(Exceptional_ostream& estream, int operand); /* operation. */
};
/******************************************************************************
*
* Template class for printing binary operators in infix notation.
*
*****************************************************************************/
template<const char* symbol>
class BinaryOperatorInfixWriter
{
public:
static void write /* Implements the write */
(Exceptional_ostream& estream, int operand); /* operation. */
};
/******************************************************************************
*
* Inline function definitions for template class FormulaWriter.
*
*****************************************************************************/
/* ========================================================================= */
template<class TrueWriter, class FalseWriter, class AtomWriter,
class NotWriter, class NextWriter, class FinallyWriter,
class GloballyWriter, class AndWriter, class OrWriter,
class ImplyWriter, class EquivWriter, class XorWriter,
class UntilWriter, class ReleaseWriter, class WeakUntilWriter,
class StrongReleaseWriter, class BeforeWriter>
inline FormulaWriter<TrueWriter, FalseWriter, AtomWriter, NotWriter,
NextWriter, FinallyWriter, GloballyWriter, AndWriter,
OrWriter, ImplyWriter, EquivWriter, XorWriter,
UntilWriter, ReleaseWriter, WeakUntilWriter,
StrongReleaseWriter, BeforeWriter>::
FormulaWriter(Exceptional_ostream& stream) :
estream(stream)
/* ----------------------------------------------------------------------------
*
* Description: Constructor for class FormulaWriter.
*
* Arguments: stream -- A reference to an exception-aware output
* stream.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
template<class TrueWriter, class FalseWriter, class AtomWriter,
class NotWriter, class NextWriter, class FinallyWriter,
class GloballyWriter, class AndWriter, class OrWriter,
class ImplyWriter, class EquivWriter, class XorWriter,
class UntilWriter, class ReleaseWriter, class WeakUntilWriter,
class StrongReleaseWriter, class BeforeWriter>
inline FormulaWriter<TrueWriter, FalseWriter, AtomWriter, NotWriter,
NextWriter, FinallyWriter, GloballyWriter, AndWriter,
OrWriter, ImplyWriter, EquivWriter, XorWriter,
UntilWriter, ReleaseWriter, WeakUntilWriter,
StrongReleaseWriter, BeforeWriter>::
~FormulaWriter()
/* ----------------------------------------------------------------------------
*
* Description: Destructor for class FormulaWriter.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/******************************************************************************
*
* Inline function definitions for class AtomWriter.
*
*****************************************************************************/
/* ========================================================================= */
inline void AtomWriter::write
(Exceptional_ostream& estream, long int atom_id)
/* ----------------------------------------------------------------------------
*
* Description: Writes an atomic proposition into a stream.
*
* Arguments: estream -- A reference to an exception-aware output stream.
* atom_id -- Numeric identifier of the proposition.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
estream << 'p' << atom_id;
}
/******************************************************************************
*
* Inline function definitions for template class ConstantWriter.
*
*****************************************************************************/
/* ========================================================================= */
template<const char* symbol>
inline void ConstantWriter<symbol>::write(Exceptional_ostream& estream)
/* ----------------------------------------------------------------------------
*
* Description: Writes a Boolean constant into a stream.
*
* Arguments: estream -- A reference to an exception-aware output stream.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
estream << symbol;
}
/******************************************************************************
*
* Inline function definitions for template class UnaryOperatorWriter.
*
*****************************************************************************/
/* ========================================================================= */
template<const char* symbol>
inline void UnaryOperatorWriter<symbol>::write
(Exceptional_ostream& estream, int operand)
/* ----------------------------------------------------------------------------
*
* Description: Writes an unary operator symbol into a stream.
*
* Arguments: estream -- A reference to an exception-aware output stream.
* operand -- Identifies the state of the depth-first search
* that manages the writing. The operator will be
* written to the stream if and only if `operand'
* has the value 0.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
if (operand == 0)
estream << symbol << ' ';
}
/******************************************************************************
*
* Inline function definitions for template class BinaryOperatorPrefixWriter.
*
*****************************************************************************/
/* ========================================================================= */
template<const char* symbol>
inline void BinaryOperatorPrefixWriter<symbol>::write
(Exceptional_ostream& estream, int operand)
/* ----------------------------------------------------------------------------
*
* Description: Writes a binary operator symbol into a stream.
*
* Arguments: estream -- A reference to an exception-aware output stream.
* operand -- Identifies the state of the depth-first search
* that manages thel writing. This value is used to
* decide what to write to the stream.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
if (operand == 0)
estream << symbol << ' ';
else if (operand == 1)
estream << ' ';
}
/******************************************************************************
*
* Inline function definitions for template class BinaryOperatorInfixWriter.
*
*****************************************************************************/
/* ========================================================================= */
template<const char* symbol>
inline void BinaryOperatorInfixWriter<symbol>::write
(Exceptional_ostream& estream, int operand)
/* ----------------------------------------------------------------------------
*
* Description: Writes a binary operator symbol into a stream.
*
* Arguments: estream -- A reference to an exception-aware output stream.
* operand -- Identifies the state of the depth-first search
* that manages the writing. This value is
* used to decide what to write to the stream.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
if (operand == 0)
estream << '(';
else if (operand == 1)
estream << ' ' << symbol << ' ';
else
estream << ')';
}
/******************************************************************************
*
* Function definitions for template class FormulaWriter.
*
*****************************************************************************/
/* ========================================================================= */
template<class TrueWriter, class FalseWriter, class AtomWriter,
class NotWriter, class NextWriter, class FinallyWriter,
class GloballyWriter, class AndWriter, class OrWriter,
class ImplyWriter, class EquivWriter, class XorWriter,
class UntilWriter, class ReleaseWriter, class WeakUntilWriter,
class StrongReleaseWriter, class BeforeWriter>
void FormulaWriter<TrueWriter, FalseWriter, AtomWriter, NotWriter, NextWriter,
FinallyWriter, GloballyWriter, AndWriter, OrWriter,
ImplyWriter, EquivWriter, XorWriter, UntilWriter,
ReleaseWriter, WeakUntilWriter, StrongReleaseWriter,
BeforeWriter>::
operator()(const LtlFormula* f, int operand)
/* ----------------------------------------------------------------------------
*
* Description: Implements the formula writing operation.
*
* Arguments: f -- A pointer to a constant LtlFormula.
* operand -- Used for checking when to write certain `extra'
* symbols (parentheses or spaces) to the stream.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
switch (f->what())
{
case LTL_ATOM :
AtomWriter::write(estream, static_cast<const Atom*>(f)->getId());
break;
case LTL_TRUE :
TrueWriter::write(estream);
break;
case LTL_FALSE :
FalseWriter::write(estream);
break;
case LTL_NEGATION :
NotWriter::write(estream, operand);
break;
case LTL_NEXT :
NextWriter::write(estream, operand);
break;
case LTL_FINALLY :
FinallyWriter::write(estream, operand);
break;
case LTL_GLOBALLY :
GloballyWriter::write(estream, operand);
break;
case LTL_CONJUNCTION :
AndWriter::write(estream, operand);
break;
case LTL_DISJUNCTION :
OrWriter::write(estream, operand);
break;
case LTL_IMPLICATION :
ImplyWriter::write(estream, operand);
break;
case LTL_EQUIVALENCE :
EquivWriter::write(estream, operand);
break;
case LTL_XOR :
XorWriter::write(estream, operand);
break;
case LTL_UNTIL :
UntilWriter::write(estream, operand);
break;
case LTL_V :
ReleaseWriter::write(estream, operand);
break;
case LTL_WEAK_UNTIL :
WeakUntilWriter::write(estream, operand);
break;
case LTL_STRONG_RELEASE :
StrongReleaseWriter::write(estream, operand);
break;
default : /* LTL_BEFORE */
BeforeWriter::write(estream, operand);
break;
}
}
}
#endif /* !FORMULAWRITER_H */

File diff suppressed because it is too large Load diff

View file

@ -1,186 +0,0 @@
/*
* Copyright (C) 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* 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.
*/
#include "IntervalList.h"
#include "StringUtil.h"
/******************************************************************************
*
* Function definitions for class IntervalList.
*
*****************************************************************************/
/* ========================================================================= */
void IntervalList::merge(unsigned long int min, unsigned long int max)
/* ----------------------------------------------------------------------------
*
* Description: Merges a new interval with a list of intervals.
*
* Arguments: min, max -- Upper and lower bound of the new interval.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
if (min > max)
return;
list<Interval>::iterator interval;
for (interval = intervals.begin();
interval != intervals.end() && interval->second + 1 < min;
++interval)
;
if (interval == intervals.end())
{
intervals.insert(interval, make_pair(min, max));
return;
}
if (interval->first <= min && max <= interval->second)
return;
if (max + 1 < interval->first)
{
intervals.insert(interval, make_pair(min, max));
return;
}
if (min < interval->first)
interval->first = min;
if (interval->second < max)
{
interval->second = max;
list<Interval>::iterator interval2 = interval;
++interval2;
while (interval2 != intervals.end()
&& interval2->first <= interval->second + 1)
{
if (interval->second < interval2->second)
interval->second = interval2->second;
list<Interval>::iterator interval_to_erase = interval2;
++interval2;
intervals.erase(interval_to_erase);
}
}
}
/* ========================================================================= */
void IntervalList::remove(unsigned long int min, unsigned long int max)
/* ----------------------------------------------------------------------------
*
* Description: Removes a closed interval from an interval list.
*
* Arguments: min, max -- Bounds for the interval to remove.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
if (min > max)
return;
list<Interval>::iterator interval;
for (interval = intervals.begin();
interval != intervals.end() && interval->second < min;
++interval)
;
while (interval != intervals.end())
{
if (max < interval->first) /* min <= max < imin <= imax */
return;
if (interval->first < min)
{
if (max < interval->second) /* imin < min <= max < imax */
{
intervals.insert(interval, make_pair(interval->first, min - 1));
interval->first = max + 1;
return;
}
interval->second = min - 1; /* imin < min <= imax <= max */
++interval;
}
else if (max < interval->second) /* min <= imin <= max < imax */
{
interval->first = max + 1;
return;
}
else /* min <= imin <= imax <= max */
{
list<Interval>::iterator interval_to_erase = interval;
++interval;
intervals.erase(interval_to_erase);
}
}
}
/* ========================================================================= */
bool IntervalList::covers(unsigned long int min, unsigned long int max) const
/* ----------------------------------------------------------------------------
*
* Description: Test whether an interval list covers a given interval.
*
* Arguments: min, max -- Upper and lower bound for the interval to test.
*
* Returns: True if the IntervalList covers the given interval.
*
* ------------------------------------------------------------------------- */
{
if (min > max)
return true; /* empty interval is always covered */
list<Interval>::const_iterator interval;
for (interval = intervals.begin();
interval != intervals.end() && min > interval->second;
++interval)
;
if (interval == intervals.end())
return false;
return (min >= interval->first && max <= interval->second);
}
/* ========================================================================= */
string IntervalList::toString() const
/* ----------------------------------------------------------------------------
*
* Description: Converts the interval list to a string.
*
* Arguments: None.
*
* Returns: A string listing the intervals in the interval list.
*
* ------------------------------------------------------------------------- */
{
string s;
for (list<Interval>::const_iterator interval = intervals.begin();
interval != intervals.end();
++interval)
{
if (interval != intervals.begin())
s += ',';
s += StringUtil::toString(interval->first) + "..."
+ StringUtil::toString(interval->second);
}
return s;
}

View file

@ -1,500 +0,0 @@
/*
* Copyright (C) 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* 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 INTERVALLIST_H
#define INTERVALLIST_H
#include <config.h>
#include <list>
#include <string>
#include <utility>
#include "LbttAlloc.h"
using namespace std;
/******************************************************************************
*
* The IntervalList class represents a list of disjoint closed intervals
* formed from pairs of unsigned long integers. The class supports merging
* a new interval with a list of intervals, removing an interval from a list
* of intervals and checking whether the interval list covers a given element
* (or a given interval). The elements of the intervals can also be accessed
* in increasing order via IntervalList::const_iterator.
*
*****************************************************************************/
class IntervalList
{
private:
typedef pair<unsigned long int,
unsigned long int>
Interval;
public:
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
class const_iterator /* A class for iterating */
{ /* over the elements of */
/* an IntervalList. */
public:
const_iterator(); /* Constructor. */
/* default copy constructor */
~const_iterator(); /* Destructor. */
/* default assignment operator */
bool operator==(const const_iterator& it) /* Comparison operators. */
const;
bool operator!=(const const_iterator& it)
const;
unsigned long int operator*() const; /* Dereference operator. */
unsigned long int operator++(); /* Prefix increment. */
unsigned long int operator++(int); /* Postfix increment. */
private:
const list<Interval>* interval_list; /* The interval list
* associated with the
* iterator.
*/
list<Interval>::const_iterator interval; /* An iterator pointing at
* the current intrerval
* list.
*/
unsigned long int element; /* Element currently
* pointed to by the
* iterator.
*/
friend class IntervalList;
};
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
IntervalList(); /* Constructor. */
~IntervalList(); /* Destructor. */
/* default copy constructor */
/* default assignment operator */
void merge(unsigned long int element); /* Merges a point interval
* with the list of
* intervals.
*/
void merge /* Merges a new interval */
(unsigned long int min, unsigned long int max); /* with the list of
* intervals.
*/
void remove(unsigned long int element); /* Removes an element from
* the list of intervals.
*/
void remove /* Removes an interval */
(unsigned long int min, unsigned long int max); /* from the list of
* intervals.
*/
bool covers(unsigned long int element) const; /* Tests whether the
* interval list covers an
* element.
*/
bool covers /* Tests whether the */
(unsigned long int min, unsigned long int max) /* interval list covers */
const; /* an interval. */
const_iterator begin() const; /* Returns an iterator to
* the beginning of the
* interval list.
*/
const_iterator end() const; /* Returns an iterator to
* the end of the interval
* list.
*/
typedef const_iterator iterator; /* The interval list
* cannot be modified with
* iterators.
*/
typedef list<Interval>::size_type size_type; /* Size type. */
size_type size() const; /* Tell the number of
* disjoint intervals in
* the interval list.
*/
size_type max_size() const; /* Tell the maximum
* allowable number of
* disjoint intervals in
* the interval list.
*/
bool empty() const; /* Tell whether the
* interval list is empty.
*/
void clear(); /* Makes the interval list
* empty.
*/
string toString() const; /* Converts the interval
* list to a string.
*/
private:
list<Interval> intervals; /* List of intervals. */
friend class const_iterator;
};
/******************************************************************************
*
* Inline function definitions for class IntervalList.
*
*****************************************************************************/
/* ========================================================================= */
inline IntervalList::IntervalList()
/* ----------------------------------------------------------------------------
*
* Description: Constructor for class IntervalList. Creates an empty list of
* intervals.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
inline IntervalList::~IntervalList()
/* ----------------------------------------------------------------------------
*
* Description: Destructor for class IntervalList.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
inline void IntervalList::merge(unsigned long int element)
/* ----------------------------------------------------------------------------
*
* Description: Merges an element (a point interval) with an IntervalList.
*
* Arguments: element -- Element to merge.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
merge(element, element);
}
/* ========================================================================= */
inline bool IntervalList::covers(unsigned long int element) const
/* ----------------------------------------------------------------------------
*
* Description: Tests whether an interval list covers an element.
*
* Arguments: element -- Element to test.
*
* Returns: True if the IntervalList covers the element.
*
* ------------------------------------------------------------------------- */
{
return covers(element, element);
}
/* ========================================================================= */
inline IntervalList::size_type IntervalList::size() const
/* ----------------------------------------------------------------------------
*
* Description: Tells the number of disjoint intervals in an IntervalList.
*
* Arguments: None.
*
* Returns: Number of disjoint intervals in the IntervalList.
*
* ------------------------------------------------------------------------- */
{
return intervals.size();
}
/* ========================================================================= */
inline IntervalList::size_type IntervalList::max_size() const
/* ----------------------------------------------------------------------------
*
* Description: Tells the maximum allowable number of disjoint intervals in
* an IntervalList.
*
* Arguments: None.
*
* Returns: Maximum allowable number of disjoint intervals in the
* IntervalList.
*
* ------------------------------------------------------------------------- */
{
return intervals.max_size();
}
/* ========================================================================= */
inline bool IntervalList::empty() const
/* ----------------------------------------------------------------------------
*
* Description: Tells whether an IntervalList is empty.
*
* Arguments: None.
*
* Returns: True if the IntervalList is empty.
*
* ------------------------------------------------------------------------- */
{
return intervals.empty();
}
/* ========================================================================= */
inline void IntervalList::clear()
/* ----------------------------------------------------------------------------
*
* Description: Makes an IntervalList empty.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
intervals.clear();
}
/* ========================================================================= */
inline IntervalList::const_iterator IntervalList::begin() const
/* ----------------------------------------------------------------------------
*
* Description: Returns an IntervalList::const_iterator pointing to the
* beginning of an IntervalList.
*
* Arguments: None.
*
* Returns: An IntervalList::const_iterator pointing to the beginning of
* the IntervalList.
*
* ------------------------------------------------------------------------- */
{
const_iterator it;
it.interval_list = &this->intervals;
it.interval = intervals.begin();
if (it.interval != intervals.end())
it.element = it.interval->first;
else
it.element = 0;
return it;
}
/* ========================================================================= */
inline IntervalList::const_iterator IntervalList::end() const
/* ----------------------------------------------------------------------------
*
* Description: Returns an IntervalList::const_iterator pointing to the end
* of an IntervalList.
*
* Arguments: None.
*
* Returns: An IntervalList::const_iterator pointing to the end of the
* IntervalList.
*
* ------------------------------------------------------------------------- */
{
const_iterator it;
it.interval_list = &this->intervals;
it.interval = intervals.end();
it.element = 0;
return it;
}
/******************************************************************************
*
* Inline function definitions for class IntervalList::const_iterator.
*
*****************************************************************************/
/* ========================================================================= */
inline IntervalList::const_iterator::const_iterator()
/* ----------------------------------------------------------------------------
*
* Description: Constructor for class IntervalList::const_iterator.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
inline IntervalList::const_iterator::~const_iterator()
/* ----------------------------------------------------------------------------
*
* Description: Destructor for class IntervalList::const_iterator.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
inline bool IntervalList::const_iterator::operator==
(const const_iterator& it) const
/* ----------------------------------------------------------------------------
*
* Description: Equality test for two IntervalList::const_iterators. Two
* IntervalList::const_iterators are equal if and only if they
* point to the same interval of an interval list and the same
* element in the interval.
*
* Argument: it -- A constant reference to another
* IntervalList::const_iterator.
*
* Returns: Result of the equality test (a truth value).
*
* ------------------------------------------------------------------------- */
{
return (interval_list == it.interval_list && interval == it.interval
&& element == it.element);
}
/* ========================================================================= */
inline bool IntervalList::const_iterator::operator!=
(const const_iterator& it) const
/* ----------------------------------------------------------------------------
*
* Description: Inequality test for two IntervalList::const_iterators. Two
* IntervalList::const_iterators are not equal if and only if
* they point to different intervals of an interval list or to
* different elements of the same interval in the list.
*
* Argument: it -- A constant reference to another
* IntervalList::const_iterator.
*
* Returns: Result of the inequality test (a truth value).
*
* ------------------------------------------------------------------------- */
{
return (interval_list != it.interval_list || interval != it.interval
|| element != it.element);
}
/* ========================================================================= */
inline unsigned long int IntervalList::const_iterator::operator*() const
/* ----------------------------------------------------------------------------
*
* Description: Dereferencing operator for IntervalList::const_iterator.
*
* Arguments: None.
*
* Returns: The element currently pointed to by the iterator.
*
* ------------------------------------------------------------------------- */
{
return element;
}
/* ========================================================================= */
inline unsigned long int IntervalList::const_iterator::operator++()
/* ----------------------------------------------------------------------------
*
* Description: Prefix increment operator for IntervalList::const_iterator.
*
* Arguments: None.
*
* Returns: The element following the "current" element in the interval
* list.
*
* ------------------------------------------------------------------------- */
{
if (element == interval->second)
{
++interval;
if (interval != interval_list->end())
element = interval->first;
else
element = 0;
}
else
++element;
return element;
}
/* ========================================================================= */
inline unsigned long int IntervalList::const_iterator::operator++(int)
/* ----------------------------------------------------------------------------
*
* Description: Postfix increment operator for IntervalList::const_iterator.
*
* Arguments: None.
*
* Returns: The "current" element in the interval list.
*
* ------------------------------------------------------------------------- */
{
unsigned long int current_element = element;
if (element == interval->second)
{
++interval;
if (interval != interval_list->end())
element = interval->first;
else
element = 0;
}
else
++element;
return current_element;
}
#endif /* INTERVALLIST_H */

View file

@ -1,135 +0,0 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* 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 LBTWRAPPER_H
#define LBTWRAPPER_H
#include <config.h>
#include <string>
#include "ExternalTranslator.h"
#include "translate.h"
/******************************************************************************
*
* Interface class for lbt.
*
*****************************************************************************/
class LbtWrapper : public ExternalTranslator
{
public:
LbtWrapper(); /* Constructor. */
~LbtWrapper(); /* Destructor. */
/* `translateFormula' inherited from ExternalTranslator */
/* `formatInput' inherited from ExternalTranslator */
string commandLine /* Prepares the command */
(const string& input_filename, /* line for executing */
const string&); /* lbt. */
/* `execSuccess' inherited from ExternalTranslator */
void parseAutomaton /* Dummy function, */
(const string&, const string&); /* needed to support the
* ExternalTranslator
* interface.
*/
private:
LbtWrapper(const LbtWrapper&); /* Prevent copying and */
LbtWrapper& operator=(const LbtWrapper&); /* assignment of
* LbtWrapper objects.
*/
};
/******************************************************************************
*
* Inline function definitions for class LbtWrapper.
*
*****************************************************************************/
/* ========================================================================= */
inline LbtWrapper::LbtWrapper()
/* ----------------------------------------------------------------------------
*
* Description: Constructor for class LbtWrapper.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
inline LbtWrapper::~LbtWrapper()
/* ----------------------------------------------------------------------------
*
* Description: Destructor for class LbtWrapper.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
inline string LbtWrapper::commandLine
(const string& input_filename, const string&)
/* ----------------------------------------------------------------------------
*
* Description: Prepares the command line for lbt.
*
* Arguments: input_filename -- Name of the input file.
* The other argument is only needed for supporting the
* ExternalTranslator interface; the output will be written to
* the filename stored in `command_line_arguments[4]'.
*
* Returns: The command line string.
*
* ------------------------------------------------------------------------- */
{
return string(" <") + input_filename + " >"
+ string(command_line_arguments[4]);
}
/* ========================================================================= */
inline void LbtWrapper::parseAutomaton(const string&, const string&)
/* ----------------------------------------------------------------------------
*
* Description: Dummy function which is needed to support the
* ExternalTranslator interface.
*
* Arguments: References to two constant strings.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
#endif /* !LBTWRAPPER_H */

View file

@ -1,161 +0,0 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* 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 LBTTALLOC_H
#define LBTTALLOC_H
#include <config.h>
#ifdef HAVE_OBSTACK_H
/* GNU libc 2.3.2's copy of obstack.h uses a definition of __INT_TO_PTR
which does not compile in C++. Fortunately it will not override
an existing definition. */
#ifdef GLIBC_OBSTACK_WORKAROUND
#define __INT_TO_PTR(P) ((P) + (char *) 0)
#endif
#include <obstack.h>
#include <cstdlib>
#include <new>
/******************************************************************************
*
* A wrapper class for allocating memory through an obstack.
*
*****************************************************************************/
class ObstackAllocator
{
public:
ObstackAllocator(); /* Constructor. */
~ObstackAllocator(); /* Destructor. */
void* alloc(int size); /* Allocates memory. */
void free(void* obj); /* Deallocates memory. */
static void failure(); /* Callback function for
* reporting a memory
* allocation failure.
*/
private:
ObstackAllocator(const ObstackAllocator&); /* Prevent copying and */
ObstackAllocator& operator= /* assignment of */
(const ObstackAllocator&); /* ObstackAllocator
* objects.
*/
struct obstack store; /* The obstack. */
};
#define obstack_chunk_alloc std::malloc
#define obstack_chunk_free std::free
/******************************************************************************
*
* Inline function definitions for class ObstackAllocator.
*
*****************************************************************************/
/* ========================================================================= */
inline ObstackAllocator::ObstackAllocator()
/* ----------------------------------------------------------------------------
*
* Description: Constructor for class ObstackAllocator.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
obstack_init(&store);
}
/* ========================================================================= */
inline ObstackAllocator::~ObstackAllocator()
/* ----------------------------------------------------------------------------
*
* Description: Destructor for class ObstackAllocator.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
obstack_free(&store, NULL);
}
/* ========================================================================= */
inline void* ObstackAllocator::alloc(int size)
/* ----------------------------------------------------------------------------
*
* Description: Interface to the memory allocator.
*
* Argument: size -- Number of bytes to allocate.
*
* Returns: A pointer to the beginning of the newly allocated memory.
*
* ------------------------------------------------------------------------- */
{
return obstack_alloc(&store, size);
}
/* ========================================================================= */
inline void ObstackAllocator::free(void* obj)
/* ----------------------------------------------------------------------------
*
* Description: Interface to the memory deallocation function.
*
* Argument: obj -- A pointer to the object to deallocate. (Because the
* underlying memory allocator is an obstack, freeing
* an object also releases all objects allocated after
* the given object.)
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
obstack_free(&store, obj);
}
/* ========================================================================= */
inline void ObstackAllocator::failure()
/* ----------------------------------------------------------------------------
*
* Description: Callback function for reporting memory allocation failures.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
throw std::bad_alloc();
}
#endif /* HAVE_OBSTACK_H */
#endif /* !LBTTALLOC_H */

View file

@ -1,610 +0,0 @@
/*
* Copyright (C) 2004, 2005, 2008
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* 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.
*/
%{
#include <config.h>
#include <cctype>
#include <climits>
#include <cstring>
#include <istream>
#include <set>
#include "Exception.h"
#include "LbttAlloc.h"
#include "LtlFormula.h"
using namespace Ltl;
/******************************************************************************
*
* Variables and functions used for parsing an LTL formula.
*
*****************************************************************************/
static Exceptional_istream* estream; /* Pointer to input stream.
*/
static LtlFormula* result; /* This variable stores the
* result after a call to
* ltl_parse.
*/
static std::set<LtlFormula*> intermediate_results; /* Intermediate results.
* (This set is used
* for keeping track of
* the subformulas of a
* partially constructed
* formula in case the
* memory allocated for
* the subformulas needs
* to be freed because
* of a parse error.)
*/
static int ltl_lex(); /* The lexical scanner. */
/******************************************************************************
*
* Function for reporting parse errors.
*
*****************************************************************************/
static void ltl_error(const char*)
{
throw LtlFormula::ParseErrorException("error parsing LTL formula");
}
/******************************************************************************
*
* Function for updating the set of intermediate results.
*
*****************************************************************************/
inline LtlFormula* newFormula(LtlFormula& f)
{
intermediate_results.insert(&f);
return &f;
}
%}
%name-prefix="ltl_"
/******************************************************************************
*
* Declarations for terminal and nonterminal symbols used in the grammar rules
* below.
*
*****************************************************************************/
%union {
class LtlFormula* formula;
}
/* Uninterpreted symbols. */
%token LTLPARSE_LPAR LTLPARSE_RPAR LTLPARSE_FALSE LTLPARSE_TRUE
LTLPARSE_UNKNOWN
/* Atomic propositions. */
%token <formula> LTLPARSE_ATOM
/* Operators. */
%nonassoc LTLPARSE_UNTIL LTLPARSE_RELEASE LTLPARSE_WEAK_UNTIL
LTLPARSE_STRONG_RELEASE LTLPARSE_BEFORE
%left LTLPARSE_IMPLY LTLPARSE_EQUIV LTLPARSE_XOR
%left LTLPARSE_OR
%left LTLPARSE_AND
%nonassoc LTLPARSE_NOT LTLPARSE_NEXT LTLPARSE_FINALLY LTLPARSE_GLOBALLY
%nonassoc LTLPARSE_EQUALS
/* Compound formulas. */
%type <formula> formula atomic_formula unary_formula prefix_op_formula
binary_formula prefix_b_formula infix_b_formula
/******************************************************************************
*
* Grammar rule definitions.
*
*****************************************************************************/
%%
ltl_formula: formula
{ result = $1; }
;
formula: atomic_formula
{ $$ = $1; }
| unary_formula
{ $$ = $1; }
| binary_formula
{ $$ = $1; }
| LTLPARSE_LPAR formula LTLPARSE_RPAR
{ $$ = $2; }
;
atomic_formula: LTLPARSE_ATOM
{ $$ = $1; }
| LTLPARSE_ATOM LTLPARSE_EQUALS LTLPARSE_FALSE
{
intermediate_results.erase($1);
$$ = newFormula(Not::construct($1));
}
| LTLPARSE_ATOM LTLPARSE_EQUALS LTLPARSE_TRUE
{ $$ = $1; }
| LTLPARSE_FALSE
{ $$ = newFormula(False::construct()); }
| LTLPARSE_TRUE
{ $$ = newFormula(True::construct()); }
;
unary_formula: LTLPARSE_NOT formula
{
intermediate_results.erase($2);
$$ = newFormula(Not::construct($2));
}
| LTLPARSE_NEXT formula
{
intermediate_results.erase($2);
$$ = newFormula(Next::construct($2));
}
| LTLPARSE_FINALLY formula
{
intermediate_results.erase($2);
$$ = newFormula(Finally::construct($2));
}
| LTLPARSE_GLOBALLY formula
{
intermediate_results.erase($2);
$$ = newFormula(Globally::construct($2));
}
;
prefix_op_formula: atomic_formula
{ $$ = $1; }
| unary_formula
{ $$ = $1; }
| prefix_b_formula
{ $$ = $1; }
| LTLPARSE_LPAR formula LTLPARSE_RPAR
{ $$ = $2; }
;
binary_formula: prefix_b_formula
{ $$ = $1; }
| infix_b_formula
{ $$ = $1; }
;
prefix_b_formula: LTLPARSE_AND prefix_op_formula prefix_op_formula
{
intermediate_results.erase($2);
intermediate_results.erase($3);
$$ = newFormula(And::construct($2, $3));
}
| LTLPARSE_OR prefix_op_formula prefix_op_formula
{
intermediate_results.erase($2);
intermediate_results.erase($3);
$$ = newFormula(Or::construct($2, $3));
}
| LTLPARSE_IMPLY prefix_op_formula prefix_op_formula
{
intermediate_results.erase($2);
intermediate_results.erase($3);
$$ = newFormula(Imply::construct($2, $3));
}
| LTLPARSE_EQUIV prefix_op_formula prefix_op_formula
{
intermediate_results.erase($2);
intermediate_results.erase($3);
$$ = newFormula(Equiv::construct($2, $3));
}
| LTLPARSE_XOR prefix_op_formula prefix_op_formula
{
intermediate_results.erase($2);
intermediate_results.erase($3);
$$ = newFormula(Xor::construct($2, $3));
}
| LTLPARSE_UNTIL prefix_op_formula prefix_op_formula
{
intermediate_results.erase($2);
intermediate_results.erase($3);
$$ = newFormula(Until::construct($2, $3));
}
| LTLPARSE_RELEASE prefix_op_formula prefix_op_formula
{
intermediate_results.erase($2);
intermediate_results.erase($3);
$$ = newFormula(V::construct($2, $3));
}
| LTLPARSE_WEAK_UNTIL prefix_op_formula prefix_op_formula
{
intermediate_results.erase($2);
intermediate_results.erase($3);
$$ = newFormula(WeakUntil::construct($2, $3));
}
| LTLPARSE_STRONG_RELEASE prefix_op_formula
prefix_op_formula
{
intermediate_results.erase($2);
intermediate_results.erase($3);
$$ = newFormula(StrongRelease::construct($2, $3));
}
| LTLPARSE_BEFORE prefix_op_formula prefix_op_formula
{
intermediate_results.erase($2);
intermediate_results.erase($3);
$$ = newFormula(Before::construct($2, $3));
}
;
infix_b_formula: formula LTLPARSE_AND formula
{
intermediate_results.erase($1);
intermediate_results.erase($3);
$$ = newFormula(And::construct($1, $3));
}
| formula LTLPARSE_OR formula
{
intermediate_results.erase($1);
intermediate_results.erase($3);
$$ = newFormula(Or::construct($1, $3));
}
| formula LTLPARSE_IMPLY formula
{
intermediate_results.erase($1);
intermediate_results.erase($3);
$$ = newFormula(Imply::construct($1, $3));
}
| formula LTLPARSE_EQUIV formula
{
intermediate_results.erase($1);
intermediate_results.erase($3);
$$ = newFormula(Equiv::construct($1, $3));
}
| formula LTLPARSE_XOR formula
{
intermediate_results.erase($1);
intermediate_results.erase($3);
$$ = newFormula(Xor::construct($1, $3));
}
| formula LTLPARSE_UNTIL formula
{
intermediate_results.erase($1);
intermediate_results.erase($3);
$$ = newFormula(Until::construct($1, $3));
}
| formula LTLPARSE_RELEASE formula
{
intermediate_results.erase($1);
intermediate_results.erase($3);
$$ = newFormula(V::construct($1, $3));
}
| formula LTLPARSE_WEAK_UNTIL formula
{
intermediate_results.erase($1);
intermediate_results.erase($3);
$$ = newFormula(WeakUntil::construct($1, $3));
}
| formula LTLPARSE_STRONG_RELEASE formula
{
intermediate_results.erase($1);
intermediate_results.erase($3);
$$ = newFormula(StrongRelease::construct($1, $3));
}
| formula LTLPARSE_BEFORE formula
{
intermediate_results.erase($1);
intermediate_results.erase($3);
$$ = newFormula(Before::construct($1, $3));
}
;
%%
/******************************************************************************
*
* Helper function for reading lexical tokens from a stream.
*
*****************************************************************************/
static inline size_t matchCharactersFromStream
(istream& stream, const char* chars)
{
size_t num_matched;
for (num_matched = 0; *chars != '\0' && stream.peek() == *chars; ++chars)
{
stream.ignore(1);
++num_matched;
}
return num_matched;
}
/******************************************************************************
*
* Main interface to the parser.
*
*****************************************************************************/
namespace Ltl
{
/* ========================================================================= */
LtlFormula* parseFormula(istream& stream)
/* ----------------------------------------------------------------------------
*
* Description: Parses an LTL formula from a stream. The formula should be
* in one of the formats used by the tools lbtt 1.0.x (both
* prefix and infix form), Spin/Temporal Massage Parlor/LTL2BA,
* LTL2AUT or Wring 1.1.0 (actually, the grammar is basically
* a combination of the grammars of the above tools with the
* exception that propositions should always be written in the
* form `pN' for some integer N; in principle, it is possible to
* use a mixed syntax for the formula). The input should be
* terminated with a newline.
*
* Argument: stream -- A reference to the input stream.
*
* Returns: A pointer to the formula. The function throws an
* LtlFormula::ParseErrorException if the syntax is incorrect,
* or an IOException in case of an end-of-file or another I/O
* error.
*
* ------------------------------------------------------------------------- */
{
Exceptional_istream es(&stream, ios::badbit | ios::failbit | ios::eofbit);
estream = &es;
intermediate_results.clear();
try
{
ltl_parse();
}
catch (...)
{
for (std::set<LtlFormula*>::const_iterator
f = intermediate_results.begin();
f != intermediate_results.end();
++f)
LtlFormula::destruct(*f);
throw;
}
return result;
}
}
/******************************************************************************
*
* The lexical scanner.
*
*****************************************************************************/
static int ltl_lex()
{
char c;
std::istream& stream = static_cast<istream&>(*estream);
do
{
estream->get(c);
}
while (isspace(c) && c != '\n');
switch (c)
{
case '\n' : return 0;
case '(' :
return (matchCharactersFromStream(stream, ")") == 1
? LTLPARSE_NEXT
: LTLPARSE_LPAR);
case ')' : return LTLPARSE_RPAR;
case 'f' :
switch (matchCharactersFromStream(stream, "alse"))
{
case 0 : case 4 :
return LTLPARSE_FALSE;
default:
break;
}
return LTLPARSE_UNKNOWN;
case '0' : return LTLPARSE_FALSE;
case 't' :
switch (matchCharactersFromStream(stream, "rue"))
{
case 0 : case 3 :
return LTLPARSE_TRUE;
default :
return LTLPARSE_UNKNOWN;
}
case 'T' :
return (matchCharactersFromStream(stream, "RUE") == 3
? LTLPARSE_TRUE
: LTLPARSE_UNKNOWN);
case '1' : return LTLPARSE_TRUE;
case '!' : case '~' : return LTLPARSE_NOT;
case '&' :
matchCharactersFromStream(stream, "&");
return LTLPARSE_AND;
case '/' :
return (matchCharactersFromStream(stream, "\\") == 1
? LTLPARSE_AND
: LTLPARSE_UNKNOWN);
case '*' : return LTLPARSE_AND;
case '|' :
matchCharactersFromStream(stream, "|");
return LTLPARSE_OR;
case '\\' :
return (matchCharactersFromStream(stream, "/") == 1
? LTLPARSE_OR
: LTLPARSE_UNKNOWN);
case '+' : return LTLPARSE_OR;
case '=' :
return (matchCharactersFromStream(stream, ">") == 1
? LTLPARSE_IMPLY
: LTLPARSE_EQUALS);
case '-' :
return (matchCharactersFromStream(stream, ">") == 1
? LTLPARSE_IMPLY
: LTLPARSE_UNKNOWN);
case 'i' : return LTLPARSE_IMPLY;
case '<' :
if (matchCharactersFromStream(stream, ">") == 1)
return LTLPARSE_FINALLY;
return (matchCharactersFromStream(stream, "->") == 2
|| matchCharactersFromStream(stream, "=>") == 2
? LTLPARSE_EQUIV
: LTLPARSE_UNKNOWN);
case 'e' : return LTLPARSE_EQUIV;
case 'x' :
return (matchCharactersFromStream(stream, "or") == 2
? LTLPARSE_XOR
: LTLPARSE_UNKNOWN);
case '^' : return LTLPARSE_XOR;
case 'X' : return LTLPARSE_NEXT;
case 'U' : return LTLPARSE_UNTIL;
case 'V' : case 'R' : return LTLPARSE_RELEASE;
case 'W' : return LTLPARSE_WEAK_UNTIL;
case 'M' : return LTLPARSE_STRONG_RELEASE;
case 'B' : return LTLPARSE_BEFORE;
case 'F' :
switch (matchCharactersFromStream(stream, "ALSE"))
{
case 0 :
return LTLPARSE_FINALLY;
case 4 :
return LTLPARSE_FALSE;
default :
return LTLPARSE_UNKNOWN;
}
case '[' :
return (matchCharactersFromStream(stream, "]") == 1
? LTLPARSE_GLOBALLY
: LTLPARSE_UNKNOWN);
case 'G' : return LTLPARSE_GLOBALLY;
case 'p' :
{
long int id = 0;
bool id_ok = false;
int ch = stream.peek();
while (ch >= '0' && ch <= '9')
{
id_ok = true;
estream->get(c);
if (LONG_MAX / 10 < id)
throw LtlFormula::ParseErrorException
("error parsing LTL formula (proposition identifier out of "
"range)");
id *= 10;
id += (c - '0');
ch = stream.peek();
}
if (id_ok)
{
ltl_lval.formula = newFormula(Atom::construct(id));
return LTLPARSE_ATOM;
}
return LTLPARSE_UNKNOWN;
}
default : return LTLPARSE_UNKNOWN;
}
}

View file

@ -1,16 +0,0 @@
// This is a hack to support both Automake <= 1.11.x, and Automake >=
// 1.12.x The problem with is that old versions used to create
// parse.h, and parse.cc from a parse.yxx grammar, while new versions
// create parse.hxx and parse.cc.
//
// We want to support both version of Automake, because 1.11.x is
// fairly well distributed, and 1.12 did not make it into Debian 7.0.
//
// Yet it's difficult to support both versions because of the name
// change. Our hack is to rename parse.yxx as parse.y, so that
// automake will generate rule to build parse.h and parse.c, and then
// this parse_.cc file is used to compile parse.c in C++. This way we
// always have a parse.h file regardless of the Automake version.
//
// We can fix this mess once Automake 1.12 is available everywhere.
#include "Ltl-parse.c"

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,92 +0,0 @@
BUILT_SOURCES = Config-parse.c NeverClaim-parse.c Ltl-parse.c
AM_YFLAGS = -d
bin_PROGRAMS = lbtt lbtt-translate
lbtt_SOURCES = \
BitArray.h \
Bitset.h \
BitArray.cc \
BuchiAutomaton.h \
BuchiAutomaton.cc \
BuchiProduct.h \
BuchiProduct.cc \
Config-parse_.cc \
Config-lex.ll \
Configuration.h \
Configuration.cc \
DispUtil.h \
DispUtil.cc \
EdgeContainer.h \
Exception.h \
FormulaRandomizer.h \
FormulaRandomizer.cc \
FormulaWriter.h \
IntervalList.h \
IntervalList.cc \
LbttAlloc.h \
LtlFormula.h \
LtlFormula.cc \
Ltl-parse_.cc \
main.cc \
PathEvaluator.h \
PathEvaluator.cc \
PathIterator.h \
PathIterator.cc \
Product.h \
Random.h \
SccCollection.h \
SharedTestData.h \
StatDisplay.h \
StatDisplay.cc \
StateSpace.h \
StateSpace.cc \
StateSpaceProduct.h \
StateSpaceRandomizer.h \
StateSpaceRandomizer.cc \
StringUtil.h \
StringUtil.cc \
TempFsysName.h \
TempFsysName.cc \
TestOperations.h \
TestOperations.cc \
TestRoundInfo.h \
TestStatistics.h \
TestStatistics.cc \
UserCommandReader.h \
UserCommandReader.cc \
UserCommands.h \
UserCommands.cc
EXTRA_lbtt_SOURCES = gnu-getopt.h Config-parse.y Ltl-parse.y
lbtt_LDADD = @LIBOBJS@ @READLINELIBS@
lbtt_translate_SOURCES = \
BitArray.h \
BitArray.cc \
Exception.h \
ExternalTranslator.h \
ExternalTranslator.cc \
FormulaWriter.h \
IntervalList.h \
IntervalList.cc \
LbttAlloc.h \
LbtWrapper.h \
LtlFormula.h \
LtlFormula.cc \
Ltl-parse_.cc \
NeverClaim-parse_.cc \
NeverClaim-lex.ll \
NeverClaimAutomaton.h \
NeverClaimAutomaton.cc \
SpinWrapper.h \
SpinWrapper.cc \
SpotWrapper.h \
SpotWrapper.cc \
StringUtil.h \
StringUtil.cc \
TempFsysName.h \
TempFsysName.cc \
translate.h \
translate.cc \
TranslatorInterface.h
EXTRA_lbtt_translate_SOURCES = gnu-getopt.h Ltl-parse.y NeverClaim-parse.y
lbtt_translate_LDADD = @LIBOBJS@

View file

@ -1,188 +0,0 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* 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.
*/
%{
#include <config.h>
#include <cstring>
#include <string>
#include "LtlFormula.h"
#include "NeverClaim-parse.h"
extern string current_neverclaim_line;
extern int current_neverclaim_line_number;
%}
%option never-interactive
%option noyywrap
%option nounput
%%
[ \t] {
current_neverclaim_line += yytext;
/* Skip whitespace. */
}
\n {
current_neverclaim_line = "";
current_neverclaim_line_number++;
/* Skip newlines. */
}
"/*"([^\*]*(\*[^/])?)*"*/" {
char* s = yytext, *t;
do
{
t = strchr(s, '\n');
if (t != static_cast<char*>(0))
{
current_neverclaim_line = "";
current_neverclaim_line_number++;
s = t + 1;
}
}
while (t != static_cast<char*>(0));
current_neverclaim_line += s;
/* Skip comments. */
}
never {
current_neverclaim_line += yytext;
return NC_NEVER;
}
if {
current_neverclaim_line += yytext;
return NC_IF;
}
fi {
current_neverclaim_line += yytext;
return NC_FI;
}
goto {
current_neverclaim_line += yytext;
return NC_GOTO;
}
skip {
current_neverclaim_line += yytext;
return NC_SKIP;
}
"::" {
current_neverclaim_line += yytext;
return NC_DOUBLE_COLON;
}
":" {
current_neverclaim_line += yytext;
return NC_COLON;
}
";" {
current_neverclaim_line += yytext;
return NC_SEMICOLON;
}
"{" {
current_neverclaim_line += yytext;
return NC_LBRACE;
}
"}" {
current_neverclaim_line += yytext;
return NC_RBRACE;
}
"(" {
current_neverclaim_line += yytext;
return NC_LPAREN;
}
")" {
current_neverclaim_line += yytext;
return NC_RPAREN;
}
"->" {
current_neverclaim_line += yytext;
return NC_RIGHT_ARROW;
}
"p"[0-9]+ {
current_neverclaim_line += yytext;
yylval.pf = new string(yytext);
return NC_PROPOSITION;
}
"1"|true {
current_neverclaim_line += yytext;
yylval.pf = new string;
*yylval.pf += ::Ltl::LtlTrue::prefix_symbol;
return NC_TRUE;
}
"0"|false {
current_neverclaim_line += yytext;
yylval.pf = new string;
*yylval.pf += ::Ltl::LtlFalse::prefix_symbol;
return NC_FALSE;
}
"||" {
current_neverclaim_line += yytext;
return NC_OR;
}
"&&" {
current_neverclaim_line += yytext;
return NC_AND;
}
"!" {
current_neverclaim_line += yytext;
return NC_NOT;
}
[A-Za-z_][A-Za-z0-9_]* {
current_neverclaim_line += yytext;
yylval.str = new string(yytext);
return NC_LABEL;
}
%%
/* ========================================================================= */
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();
}

View file

@ -1,301 +0,0 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* 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.
*/
%{
#include <config.h>
#include <cstdio>
#include <string>
#include "LtlFormula.h"
#include "NeverClaimAutomaton.h"
/******************************************************************************
*
* Variables used when parsing a never claim.
*
*****************************************************************************/
static NeverClaimAutomaton* automaton; /* Automaton in which the
* results are stored.
*/
string current_neverclaim_line; /* Current input line. */
int current_neverclaim_line_number; /* Number of the current
* line in the never claim
* file.
*/
/******************************************************************************
*
* Declarations for external functions and variables (provided by the lexer)
* used when parsing a never claim.
*
*****************************************************************************/
extern void yyrestart(FILE*); /* Changes the input stream
* for the lexer (provided
* by the lexer).
*/
extern int yylex(); /* Reads the next token
* from the input (this
* function is provided by
* the lexer).
*/
extern int getCharacter(); /* Returns the next
* character in the lexer
* input stream (defined
* in NeverClaim-lex.ll).
*/
extern int yyleng; /* Length of the last
* token parsed from the
* input (provided by the
* lexer).
*/
/******************************************************************************
*
* Function to be called in case of a parse error.
*
*****************************************************************************/
/* ========================================================================= */
void yyerror(const char*)
/* ----------------------------------------------------------------------------
*
* Description: Function for reporting never claim parse errors.
*
* Arguments: A pointer to a char (required to satisfy the function
* interface).
*
* Returns: Nothing. Instead, throws an exception with information about
* the location of the error.
*
* ------------------------------------------------------------------------- */
{
int c;
string::size_type error_pos = current_neverclaim_line.length();
if (error_pos > static_cast<unsigned long int>(yyleng))
error_pos -= yyleng;
do
{
c = getCharacter();
if (c != EOF && c != '\n')
current_neverclaim_line += static_cast<char>(c);
}
while (c != EOF && c != '\n');
throw ParseErrorException
(current_neverclaim_line, current_neverclaim_line_number, error_pos);
}
%}
/******************************************************************************
*
* Declarations for terminal and nonterminal symbols used in the grammar rules
* below.
*
*****************************************************************************/
/* Data types. */
%union {
string* pf;
string* str;
}
/* Keywords. */
%token NC_NEVER NC_IF NC_FI NC_GOTO NC_SKIP
/* State labels. */
%token <str> NC_LABEL
/* Punctuation symbols. */
%token NC_COLON NC_SEMICOLON NC_DOUBLE_COLON NC_LBRACE NC_RBRACE NC_LPAREN
NC_RPAREN NC_RIGHT_ARROW
/* Propositional formulae. */
%token <pf> NC_PROPOSITION NC_TRUE NC_FALSE
%right NC_OR
%right NC_AND
%nonassoc NC_NOT
%type <pf> formula
%%
/******************************************************************************
*
* Grammar rule definitions.
*
*****************************************************************************/
never_claim: NC_NEVER NC_LBRACE states optional_semicolon NC_RBRACE
;
optional_semicolon: NC_SEMICOLON
| /* empty */
;
states: state
| states NC_SEMICOLON state
;
state: {
automaton->addNewState();
}
state_labels state_body
;
state_labels: NC_LABEL NC_COLON
{
automaton->addNewLabel(*$1);
delete $1;
}
| state_labels NC_LABEL NC_COLON
{
automaton->addNewLabel(*$2);
delete $2;
}
;
state_body: NC_IF transitions NC_FI
| NC_SKIP
| NC_FALSE
{
automaton->currentState()->accepting() = false;
}
| NC_IF NC_DOUBLE_COLON NC_FALSE NC_FI
{
automaton->currentState()->accepting() = false;
}
;
transitions: transition
| transitions transition
;
transition: NC_DOUBLE_COLON formula NC_RIGHT_ARROW NC_GOTO NC_LABEL
{
automaton->currentState()->addTransition(*$5, $2);
delete $5;
}
;
formula: NC_PROPOSITION
{
$$ = $1;
}
| NC_TRUE
{
$$ = $1;
}
| NC_FALSE
{
$$ = $1;
}
| NC_NOT formula
{
$$ = new string;
*$$ += ::Ltl::LtlNegation::prefix_symbol;
*$$ += ' ';
*$$ += *$2;
delete $2;
}
| formula NC_AND formula
{
$$ = new string;
*$$ += ::Ltl::LtlConjunction::prefix_symbol;
*$$ += ' ';
*$$ += *$1;
*$$ += ' ';
*$$ += *$3;
delete $1;
delete $3;
}
| formula NC_OR formula
{
$$ = new string;
*$$ += ::Ltl::LtlDisjunction::prefix_symbol;
*$$ += ' ';
*$$ += *$1;
*$$ += ' ';
*$$ += *$3;
delete $1;
delete $3;
}
| NC_LPAREN formula NC_RPAREN
{
$$ = $2;
}
;
%%
/******************************************************************************
*
* Main interface to the parser.
*
*****************************************************************************/
/* ========================================================================= */
int parseNeverClaim(FILE* stream, NeverClaimAutomaton& a)
/* ----------------------------------------------------------------------------
*
* Description: Main interface to the never claim file parser. Parses a
* never claim and stores the results into the given
* NeverClaimAutomaton object.
*
* Arguments: stream -- A pointer to a file from which the never claim
* should be read. The file is assumed to be open
* for reading.
* a -- A reference to a NeverClaimAutomaton object in
* which the results should be stored.
*
* Returns:
*
* ------------------------------------------------------------------------- */
{
yyrestart(stream);
automaton = &a;
current_neverclaim_line_number = 1;
return yyparse();
}

View file

@ -1,16 +0,0 @@
// This is a hack to support both Automake <= 1.11.x, and Automake >=
// 1.12.x The problem with is that old versions used to create
// parse.h, and parse.cc from a parse.yxx grammar, while new versions
// create parse.hxx and parse.cc.
//
// We want to support both version of Automake, because 1.11.x is
// fairly well distributed, and 1.12 did not make it into Debian 7.0.
//
// Yet it's difficult to support both versions because of the name
// change. Our hack is to rename parse.yxx as parse.y, so that
// automake will generate rule to build parse.h and parse.c, and then
// this parse_.cc file is used to compile parse.c in C++. This way we
// always have a parse.h file regardless of the Automake version.
//
// We can fix this mess once Automake 1.12 is available everywhere.
#include "NeverClaim-parse.c"

View file

@ -1,317 +0,0 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* 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.
*/
#include <config.h>
#include <cstdio>
#include <fstream>
#include "LtlFormula.h"
#include "NeverClaimAutomaton.h"
#include "StringUtil.h"
/******************************************************************************
*
* Declarations for functions and variables provided by the parser.
*
*****************************************************************************/
#include "NeverClaim-parse.h" /* Include declarations for
* the tokens that may be
* present in a never claim
* file.
*/
extern int parseNeverClaim /* Parser interface. */
(FILE*, NeverClaimAutomaton&);
extern int current_neverclaim_line_number; /* Number of the current
* line in the never claim
* file.
*/
/******************************************************************************
*
* Function definitions for class NeverClaimAutomaton.
*
*****************************************************************************/
/* ========================================================================= */
void NeverClaimAutomaton::clear()
/* ----------------------------------------------------------------------------
*
* Description: Makes a NeverClaimAutomaton empty.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
for (vector<StateInfo*>::iterator state = state_list.begin();
state != state_list.end();
++state)
delete (*state);
state_list.clear();
label_mapping.clear();
current_state = 0;
}
/* ========================================================================= */
void NeverClaimAutomaton::read(const char* input_filename)
/* ----------------------------------------------------------------------------
*
* Description: Initializes a NeverClaimAutomaton by parsing a "never claim"
* stored in a file.
*
* Arguments: input_filename -- A C-style string containing the name of
* the input file.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
clear();
/*
* Parse the never claim in the given input file.
*/
FILE* input_file = fopen(input_filename, "r");
if (input_file == 0)
throw FileOpenException(string("`") + input_filename + "'");
try
{
parseNeverClaim(input_file, *this);
fclose(input_file);
}
catch (const ParseErrorException&)
{
fclose(input_file);
clear();
throw;
}
if (state_list.size() == 1)
state_list[0]->initial() = true;
}
/* ========================================================================= */
void NeverClaimAutomaton::write(const char* output_filename)
/* ----------------------------------------------------------------------------
*
* Description: Writes a NeverClaimAutomaton to a file in `lbtt' format.
*
* Arguments: output_filename -- A C-style string containing the name of
* the output file.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
ofstream automaton_file;
automaton_file.open(output_filename, ios::out | ios::trunc);
if (!automaton_file.good())
throw FileCreationException(string("`") + output_filename + "'");
try
{
Exceptional_ostream eautomaton_file(&automaton_file,
ios::failbit | ios::badbit);
eautomaton_file << ::StringUtil::toString(state_list.size()) + " 1\n";
/*
* Go through the vector of states. For each state, write the following
* information to the output file:
*
* - The number of the state.
*
* - Information about whether the state is the initial state of
* the automaton.
*
* - Information about whether the state is an accepting state.
*
* - Transitions from the state to other states (in the form
* [state number] [guard formula]; end the transition list with
* `-1'.
*/
for (vector<StateInfo*>::const_iterator state = state_list.begin();
state != state_list.end();
++state)
{
eautomaton_file << ::StringUtil::toString((*state)->number()) + ' '
+ ((*state)->initial() ? "1" : "0") + ' '
+ ((*state)->accepting() ? "0 " : "") + "-1\n";
for (multimap<Cstr, Cstr*>::const_iterator
transition = (*state)->transitions().begin();
transition != (*state)->transitions().end(); ++transition)
{
if (label_mapping.find(transition->first) == label_mapping.end())
{
remove(output_filename);
automaton_file.close();
throw Exception("error in never claim: jump to undefined label `"
+ transition->first + "'");
}
eautomaton_file << ::StringUtil::toString
((*(label_mapping.find(transition->first))).
second->number())
+ ' '
+ ::StringUtil::toString(*(transition->second))
+ '\n';
}
eautomaton_file << "-1\n";
}
automaton_file.close();
}
catch (const IOException&)
{
remove(output_filename);
automaton_file.close();
throw;
}
}
/* ========================================================================= */
void NeverClaimAutomaton::addNewState()
/* ----------------------------------------------------------------------------
*
* Description: Adds a state to a NeverClaimAutomaton and makes it the
* `current' state of the automaton.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
current_state = new StateInfo(state_list.size());
state_list.push_back(current_state);
}
/* ========================================================================= */
void NeverClaimAutomaton::addNewLabel(Cstr& label)
/* ----------------------------------------------------------------------------
*
* Description: Gives a new label for the `current' state of the automaton.
* The following substrings, if present in the label, have the
* following side effects (the side effects are cumulative):
* - If the label contains the substring "init", the current
* state is made an initial state.
* - If the label contains the substring "accept", the
* current state is made an accepting state.
* - If the state is labeled "accept_all", a transition is
* added from the state to itself.
*
* Argument: label -- A string giving the label for the state.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
label_mapping[label] = current_state;
if (label.find("init") != string::npos)
current_state->initial() = true;
if (label.find("accept") != string::npos)
current_state->accepting() = true;
if (label == "accept_all")
{
string* true_str = new string;
*true_str += ::Ltl::LtlTrue::prefix_symbol;
current_state->addTransition(label, true_str);
}
}
/******************************************************************************
*
* Function definitions for class NeverClaimAutomaton::StateInfo.
*
*****************************************************************************/
/* ========================================================================= */
NeverClaimAutomaton::StateInfo::~StateInfo()
/* ----------------------------------------------------------------------------
*
* Description: Destructor for class NeverClaimAutomaton::StateInfo.
* Releases the memory allocated by the state object.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
for (multimap<Cstr, Cstr*>::const_iterator
transition = state_transitions.begin();
transition != state_transitions.end();
++transition)
delete transition->second;
}
/******************************************************************************
*
* Function definitions for class ParseErrorException.
*
*****************************************************************************/
/* ========================================================================= */
ParseErrorException::ParseErrorException
(const string& msg, int line_number, string::size_type error_pos) :
Exception()
/* ----------------------------------------------------------------------------
*
* Description: Constructor for class ParseErrorException. Initializes an
* exception object with an error message.
*
* Arguments: msg -- A string containing the error message.
* line_number -- If nonzero, `msg' is interpreted as the line
* containing the parse error. In this case, the
* error message indicates the position of the
* error on the line.
* error_pos -- Position of the error on the line.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
if (line_number == 0)
changeMessage(msg);
else
{
string space_string(msg.substr(0, error_pos));
for (string::size_type c = 0; c < space_string.length(); c++)
if (space_string[c] != ' ' && space_string[c] != '\t')
space_string[c] = ' ';
changeMessage(string("never claim parse error on line ")
+ StringUtil::toString(line_number) + '\n' + msg + '\n'
+ space_string + "^\n");
}
}

View file

@ -1,455 +0,0 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* 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 NEVERCLAIMAUTOMATON_H
#define NEVERCLAIMAUTOMATON_H
#include <config.h>
#include <map>
#include <string>
#include <utility>
#include <vector>
#include "LbttAlloc.h"
#include "Exception.h"
using namespace std;
/******************************************************************************
*
* A class for representing the Büchi automaton obtained by parsing a "never
* claim" (model checker Spin's representation for Büchi automata). This class
* provides only a very limited set of operations that suffice for parsing a
* never claim and outputting the parsed automaton in the format used by
* `lbtt'.
*
*****************************************************************************/
class NeverClaimAutomaton
{
private:
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
class StateInfo; /* A class for storing the
* states of the automaton.
*/
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
typedef const string Cstr;
public:
NeverClaimAutomaton(); /* Constructor. */
~NeverClaimAutomaton(); /* Destructor. */
void clear(); /* Makes the automaton
* empty.
*/
void read(const char* input_filename); /* Initializes the
* automaton by parsing a
* never claim stored in a
* file.
*/
void write(const char* output_filename); /* Outputs the automaton in
* `lbtt' format.
*/
StateInfo* currentState(); /* Returns a pointer to the
* `current' state of the
* automaton (corresponding
* to the most recently
* introduced state in the
* never claim that is
* currently being parsed).
*/
void addNewState(); /* Adds a new state to the
* automaton.
*/
void addNewLabel(Cstr& label); /* Adds a new label for the
* `current' state of the
* automaton (a single
* state can have several
* different labels).
*/
private:
vector<StateInfo*> state_list; /* States of the automaton.
*/
map<string, StateInfo*> label_mapping; /* Mapping from state
* labels to the states
* itself.
*/
StateInfo* current_state; /* Pointer to the state
* introduced most recently
* in the input file.
*/
NeverClaimAutomaton /* Prevent copying and */
(const NeverClaimAutomaton& automaton); /* assignment of */
NeverClaimAutomaton& operator= /* NeverClaimAutomaton */
(const NeverClaimAutomaton& automaton); /* objects. */
};
/******************************************************************************
*
* A class for storing the states of a Büchi automaton that is being generated
* by parsing a never claim.
*
*****************************************************************************/
class NeverClaimAutomaton::StateInfo
{
public:
explicit StateInfo(unsigned long int num); /* Constructor. */
~StateInfo(); /* Destructor. */
unsigned long int number() const; /* Returns the unique
* identifier of the
* state.
*/
bool initial() const; /* Returns or changes */
bool& initial(); /* the `initialness' */
/* of the state.
*/
bool accepting() const; /* Returns or changes */
bool& accepting(); /* the acceptance status */
/* of the state.
*/
const multimap<Cstr, Cstr*>& transitions() const; /* Returns the labels of
* the state's successor
* states, including the
* conditions controlling
* the enabledness of the
* transition.
*/
void addTransition /* Connects the state to */
(Cstr& target_label, Cstr* guard); /* another state, given
* a state label and a
* propositional formula
* guarding the transition.
*/
private:
StateInfo(const StateInfo&); /* Prevent copying and */
StateInfo& operator=(const StateInfo&); /* assignment of
* StateInfo objects.
*/
unsigned long int state_number; /* Unique state identifier.
*/
bool is_initial; /* Is the state an initial
* state?
*/
bool accept; /* Is the state an
* accepting state?
*/
multimap<Cstr, Cstr*> state_transitions; /* Labels of the state's
* successors, including
* the guard formulae
* controlling the
* enabledness of the
* transitions between
* states.
*/
};
/******************************************************************************
*
* A class for reporting errors when parsing a never claim.
*
*****************************************************************************/
class ParseErrorException : public Exception
{
public:
ParseErrorException /* Constructor. */
(const string& msg
= "error parsing never claim",
int line_number = 0,
string::size_type error_pos = 0);
/* default copy constructor */
~ParseErrorException() throw(); /* Destructor. */
ParseErrorException& operator= /* Assignment operator. */
(const ParseErrorException& e);
};
/******************************************************************************
*
* Inline function definitions for class NeverClaimAutomaton.
*
*****************************************************************************/
/* ========================================================================= */
inline NeverClaimAutomaton::NeverClaimAutomaton() :
current_state(static_cast<StateInfo*>(0))
/* ----------------------------------------------------------------------------
*
* Description: Constructor for class NeverClaimAutomaton. Creates an empty
* automaton.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
inline NeverClaimAutomaton::~NeverClaimAutomaton()
/* ----------------------------------------------------------------------------
*
* Description: Destructor for class NeverClaimAutomaton.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
clear();
}
/* ========================================================================= */
inline NeverClaimAutomaton::StateInfo* NeverClaimAutomaton::currentState()
/* ----------------------------------------------------------------------------
*
* Description: Returns a pointer to the "current" state of the automaton,
* i.e., the state corresponding to the most recently introduced
* state parsed from the never claim.
*
* Arguments: None.
*
* Returns: A pointer to the state.
*
* ------------------------------------------------------------------------- */
{
return current_state;
}
/******************************************************************************
*
* Inline function definitions for class NeverClaimAutomaton::StateInfo.
*
*****************************************************************************/
/* ========================================================================= */
inline NeverClaimAutomaton::StateInfo::StateInfo(unsigned long int num) :
state_number(num), is_initial(false), accept(false)
/* ----------------------------------------------------------------------------
*
* Description: Constructor for class NeverClaimAutomaton::StateInfo.
* Creates a new state with a given identifier. By default, the
* created state will be noninitial and nonaccepting.
*
* Arguments: num -- Numeric identifier for the state.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
inline unsigned long int NeverClaimAutomaton::StateInfo::number() const
/* ----------------------------------------------------------------------------
*
* Description: Tells the identifier of a state.
*
* Arguments: None.
*
* Returns: The identifier of the state.
*
* ------------------------------------------------------------------------- */
{
return state_number;
}
/* ========================================================================= */
inline bool NeverClaimAutomaton::StateInfo::initial() const
/* ----------------------------------------------------------------------------
*
* Description: Tells whether the state is an initial state. This function
* can be used only for querying the value.
*
* Arguments: None.
*
* Returns: Truth value telling whether the state is an initial state.
*
* ------------------------------------------------------------------------- */
{
return is_initial;
}
/* ========================================================================= */
inline bool& NeverClaimAutomaton::StateInfo::initial()
/* ----------------------------------------------------------------------------
*
* Description: Tells whether the state is an initial state. This function
* can be also used to change the `initialness' of the state.
*
* Arguments: None.
*
* Returns: A reference to a truth value telling whether the state is an
* initial state.
*
* ------------------------------------------------------------------------- */
{
return is_initial;
}
/* ========================================================================= */
inline bool NeverClaimAutomaton::StateInfo::accepting() const
/* ----------------------------------------------------------------------------
*
* Description: Tells whether the state is an accepting state. This function
* can be used only for querying the acceptance status.
*
* Arguments: None.
*
* Returns: A truth value telling whether the state is an accepting
* state.
*
* ------------------------------------------------------------------------- */
{
return accept;
}
/* ========================================================================= */
inline bool& NeverClaimAutomaton::StateInfo::accepting()
/* ----------------------------------------------------------------------------
*
* Description: Tells whether the state is an accepting state. This function
* can also be used to change the acceptance status.
*
* Arguments: None.
*
* Returns: A reference to a truth value telling whether the state is an
* accepting state.
*
* ------------------------------------------------------------------------- */
{
return accept;
}
/* ========================================================================= */
inline const multimap<NeverClaimAutomaton::Cstr, NeverClaimAutomaton::Cstr*>&
NeverClaimAutomaton::StateInfo::transitions() const
/* ----------------------------------------------------------------------------
*
* Description: Returns the set of labels of the state's successor states,
* including the propositional formulae containing the
* conditions (propositional formulae) controlling the
* enabledness of the transitions the state and its successors.
*
* Arguments: None.
*
* Returns: A constant reference to a constant multimap object containing
* the successor information.
*
* ------------------------------------------------------------------------- */
{
return state_transitions;
}
/* ========================================================================= */
inline void NeverClaimAutomaton::StateInfo::addTransition
(Cstr& target_label, Cstr* guard)
/* ----------------------------------------------------------------------------
*
* Description: Connects the state to another state.
*
* Arguments: target_label -- Label of the target state.
* guard -- A pointer to a constant string containing
* the guard (a propositional formula) for
* the transition.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
state_transitions.insert(make_pair(target_label, guard));
}
/******************************************************************************
*
* Inline function definitions for class ParseErrorException.
*
*****************************************************************************/
/* ========================================================================= */
inline ParseErrorException::~ParseErrorException() throw()
/* ----------------------------------------------------------------------------
*
* Description: Destructor for class ParseErrorException.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
inline ParseErrorException&
ParseErrorException::operator=(const ParseErrorException& e)
/* ----------------------------------------------------------------------------
*
* Description: Assignment operator for class ParseErrorException.
*
* Argument: e -- A reference to a constant exception object of the
* same type.
*
* Returns: A reference to the exception object assigned to.
*
* ------------------------------------------------------------------------- */
{
Exception::operator=(e);
return *this;
}
#endif /* !NEVERCLAIMAUTOMATON_H */

View file

@ -1,986 +0,0 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* 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.
*/
#include <config.h>
#include <deque>
#include <stack>
#include <string>
#include "PathEvaluator.h"
namespace Ltl
{
/******************************************************************************
*
* Function definitions for class PathEvaluator.
*
*****************************************************************************/
/* ========================================================================= */
void PathEvaluator::reset()
/* ----------------------------------------------------------------------------
*
* Description: Prepares the formula evaluator for a new computation.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
current_formula = static_cast<const LtlFormula*>(0);
current_path = static_cast<const StateSpace*>(0);
current_loop_state = 0;
path_states.clear();
for (map<const LtlFormula*, BitArray*, LtlFormula::ptr_less>::iterator
it = eval_info.begin();
it != eval_info.end();
++it)
delete it->second;
eval_info.clear();
}
/* ========================================================================= */
bool PathEvaluator::evaluate
(const LtlFormula& formula, const StateSpace::Path& prefix,
const StateSpace::Path& cycle, const StateSpace& statespace)
/* ----------------------------------------------------------------------------
*
* Description: Evaluates an LTL formula in a path formed from a prefix and
* an infinitely repeating cycle of states in a state space.
*
* Arguments: formula -- Formula to be evaluated.
* prefix -- A StateSpace::Path object corresponding to
* the prefix of the path. Only the state
* identifiers in the path elements are used;
* the function will not require `prefix' to
* actually represent a path in `statespace'.
* cycle -- A StateSpace::Path object corresponding to
* the infinitely repeating cycle. Only the
* state identifiers in the path elements are
* relevant.
* statespace -- State space to which the state identifiers in
* `path' and `cycle' refer.
*
* Returns: `true' if and only if the LTL formula holds in the path.
*
* ------------------------------------------------------------------------- */
{
reset();
if (cycle.empty())
return false;
current_formula = &formula;
current_path = &statespace;
current_loop_state = prefix.size();
path_states.reserve(prefix.size() + cycle.size());
for (StateSpace::Path::const_iterator state = prefix.begin();
state != prefix.end();
++state)
path_states.push_back(state->node());
for (StateSpace::Path::const_iterator state = cycle.begin();
state != cycle.end();
++state)
path_states.push_back(state->node());
return eval();
}
/* ========================================================================= */
bool PathEvaluator::evaluate
(const LtlFormula& formula, const StateSpace& statespace)
/* ----------------------------------------------------------------------------
*
* Description: Evaluates an LTL formula in a state space in which the states
* are connected into a non-branching sequence that ends in a
* loop.
*
* Arguments: formula -- Formula to be evaluated.
* statespace -- State space in which the formula should be
* evaluated.
*
* Returns: `true' if and only if the LTL formula holds in the path.
*
* ------------------------------------------------------------------------- */
{
reset();
if (statespace.empty())
return false;
current_formula = &formula;
current_path = &statespace;
map<StateSpace::size_type, StateSpace::size_type> ordering;
StateSpace::size_type state = statespace.initialState();
StateSpace::size_type state_count = 0;
/*
* Construct a vector of state identifiers representing the path by
* traversing the state space until some state is encountered twice.
*/
while (1)
{
path_states.push_back(state);
ordering[state] = state_count;
state_count++;
if (statespace[state].edges().empty())
throw Exception
("PathEvaluator::compute: not a total transition relation");
state = (*(statespace[state].edges().begin()))->targetNode();
if (ordering.find(state) != ordering.end())
break;
}
current_loop_state = ordering[state];
return eval();
}
/* ========================================================================= */
bool PathEvaluator::eval()
/* ----------------------------------------------------------------------------
*
* Description: Implements the model checking algorithm for paths.
*
* Arguments: None.
*
* Returns: `true' if and only if `this->current_formula' holds in
* the path described by the contents of `this->path_states'.
*
* ------------------------------------------------------------------------- */
{
stack<const LtlFormula*, deque<const LtlFormula*> > subformula_stack;
const LtlFormula* f;
BitArray* val;
current_formula->collectSubformulae(subformula_stack);
try
{
while (!subformula_stack.empty())
{
if (::user_break)
throw UserBreakException();
/*
* Pop a formula from the subformula stack.
*/
f = subformula_stack.top();
subformula_stack.pop();
/*
* Discard the current formula if its truth value is already known.
*/
if (eval_info.find(f) != eval_info.end())
continue;
/*
* Otherwise allocate space for the evaluation results of the current
* formula and then evaluate it in all states of the path, using the
* truth values of its subformulae which have already been computed.
*/
val = eval_info[f] = new BitArray(path_states.size());
val->clear(path_states.size());
switch (f->what())
{
case LTL_UNTIL :
case LTL_FINALLY :
case LTL_V :
case LTL_GLOBALLY :
case LTL_BEFORE :
{
StateSpace::size_type marker_state;
const LtlFormula* g, *h;
bool lfp, check_value_1, check_value_2, marker_valid = false;
switch (f->what())
{
case LTL_UNTIL :
g = static_cast<const Until*>(f)->subformula1;
h = static_cast<const Until*>(f)->subformula2;
check_value_1 = check_value_2 = true;
lfp = true;
break;
case LTL_FINALLY :
g = 0;
h = static_cast<const Finally*>(f)->subformula;
check_value_1 = check_value_2 = true;
lfp = true;
break;
case LTL_V :
val->set(path_states.size());
g = static_cast<const V*>(f)->subformula1;
h = static_cast<const V*>(f)->subformula2;
check_value_1 = check_value_2 = false;
lfp = false;
break;
case LTL_GLOBALLY :
val->set(path_states.size());
g = 0;
h = static_cast<const Globally*>(f)->subformula;
check_value_1 = check_value_2 = false;
lfp = false;
break;
default : /* LTL_BEFORE */
val->set(path_states.size());
g = static_cast<const Before*>(f)->subformula1;
h = static_cast<const Before*>(f)->subformula2;
check_value_1 = false;
check_value_2 = true;
lfp = false;
break;
}
for (StateSpace::size_type state = 0; state < path_states.size();
state++)
{
if (eval_info[h]->test(state) == check_value_2)
{
val->flipBit(state);
if (marker_valid)
{
while (marker_state < state)
{
val->flipBit(marker_state);
marker_state++;
}
marker_valid = false;
}
}
else if (g == 0 || eval_info[g]->test(state) == check_value_1)
{
if (!marker_valid)
{
marker_valid = true;
marker_state = state;
}
}
else
marker_valid = false;
}
if (marker_valid && eval_info[f]->test(current_loop_state) == lfp)
{
while (marker_state < path_states.size())
{
val->flipBit(marker_state);
marker_state++;
}
}
break;
}
case LTL_WEAK_UNTIL :
case LTL_STRONG_RELEASE :
{
StateSpace::size_type marker_state;
const LtlFormula* g, *h;
bool check_value;
bool marker_valid = false;
if (f->what() == LTL_WEAK_UNTIL)
{
val->set(path_states.size());
h = static_cast<const WeakUntil*>(f)->subformula1;
g = static_cast<const WeakUntil*>(f)->subformula2;
check_value = false;
}
else
{
h = static_cast<const StrongRelease*>(f)->subformula1;
g = static_cast<const StrongRelease*>(f)->subformula2;
check_value = true;
}
for (StateSpace::size_type state = 0; state < path_states.size();
state++)
{
if (eval_info[g]->test(state) == check_value
&& eval_info[h]->test(state) == check_value)
{
val->flipBit(state);
if (marker_valid)
{
while (marker_state < state)
{
val->flipBit(marker_state);
marker_state++;
}
marker_valid = false;
}
}
else if (eval_info[g]->test(state) == check_value)
{
if (!marker_valid)
{
marker_valid = true;
marker_state = state;
}
}
else
marker_valid = false;
}
if (marker_valid
&& eval_info[f]->test(current_loop_state) == check_value)
{
while (marker_state < path_states.size())
{
val->flipBit(marker_state);
marker_state++;
}
}
break;
}
case LTL_TRUE :
val->set(path_states.size());
break;
case LTL_FALSE :
break;
case LTL_ATOM :
{
for (StateSpace::size_type s = 0; s < path_states.size(); s++)
{
/*
* Note: BitArray operations cannot be used directly, since the
* width of the array in `current_path' might be less than the
* atomic proposition identifier.
*/
if (f->evaluate((*current_path)[path_states[s]].positiveAtoms(),
current_path->numberOfPropositions()))
val->setBit(s);
}
break;
}
case LTL_NEGATION :
{
const LtlFormula* g = static_cast<const Not*>(f)->subformula;
for (StateSpace::size_type s = 0; s < path_states.size(); s++)
{
if (!eval_info[g]->test(s))
val->setBit(s);
}
break;
}
case LTL_CONJUNCTION :
{
const LtlFormula* g = static_cast<const And*>(f)->subformula1;
const LtlFormula* h = static_cast<const And*>(f)->subformula2;
for (StateSpace::size_type s = 0; s < path_states.size(); s++)
{
if (eval_info[g]->test(s) && eval_info[h]->test(s))
val->setBit(s);
}
break;
}
case LTL_DISJUNCTION :
{
const LtlFormula* g = static_cast<const Or*>(f)->subformula1;
const LtlFormula* h = static_cast<const Or*>(f)->subformula2;
for (StateSpace::size_type s = 0; s < path_states.size(); s++)
{
if (eval_info[g]->test(s) || eval_info[h]->test(s))
val->setBit(s);
}
break;
}
case LTL_IMPLICATION :
{
const LtlFormula* g = static_cast<const Imply*>(f)->subformula1;
const LtlFormula* h = static_cast<const Imply*>(f)->subformula2;
for (StateSpace::size_type s = 0; s < path_states.size(); s++)
{
if (!eval_info[g]->test(s) || eval_info[h]->test(s))
val->setBit(s);
}
break;
}
case LTL_EQUIVALENCE :
{
const LtlFormula* g = static_cast<const Equiv*>(f)->subformula1;
const LtlFormula* h = static_cast<const Equiv*>(f)->subformula2;
for (StateSpace::size_type s = 0; s < path_states.size(); s++)
{
if (eval_info[g]->test(s) == eval_info[h]->test(s))
val->setBit(s);
}
break;
}
case LTL_XOR :
{
const LtlFormula* g = static_cast<const Xor*>(f)->subformula1;
const LtlFormula* h = static_cast<const Xor*>(f)->subformula2;
for (StateSpace::size_type s = 0; s < path_states.size(); s++)
{
if (eval_info[g]->test(s) != eval_info[h]->test(s))
val->setBit(s);
}
break;
}
default : /* LTL_NEXT */
{
const LtlFormula* g = static_cast<const Next*>(f)->subformula;
StateSpace::size_type s;
for (s = 0; (s + 1) < path_states.size(); s++)
{
if (eval_info[g]->test(s + 1))
val->setBit(s);
}
if (eval_info[g]->test(current_loop_state))
val->setBit(s);
break;
}
}
}
}
catch (...)
{
reset();
throw;
}
return eval_info[current_formula]->test(0);
}
/* ========================================================================= */
bool PathEvaluator::getResult(StateSpace::size_type state) const
/* ----------------------------------------------------------------------------
*
* Description: Returns the model checking result in the path that begins at
* the `state'th state of the path described by the vector
* `this->path_states'.
*
* Arguments: state -- Index of a state in the path.
*
* Returns: `true' if and only if the LTL formula `this->current_formula'
* holds in the path that begins at the given index.
*
* ------------------------------------------------------------------------- */
{
if (eval_info.empty())
return false;
return eval_info.find(current_formula)->second->test(state);
}
/* ========================================================================= */
void PathEvaluator::print(ostream& stream, const int indent) const
/* ----------------------------------------------------------------------------
*
* Description: Displays a proof or a refutation for the formula
* `this->current_formula' in the state space described by the
* contents of `this->path_states'.
*
* Arguments: stream -- A reference to an output stream.
* indent -- Number of spaces to leave on the left of output.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
if (eval_info.empty())
return;
Exceptional_ostream estream(&stream, ios::failbit | ios::badbit);
recPrint(estream, indent, current_formula, 0);
}
/* ========================================================================= */
void PathEvaluator::recPrint
(Exceptional_ostream& estream, const int indent, const LtlFormula* f,
StateSpace::size_type state) const
/* ----------------------------------------------------------------------------
*
* Description: Displays a recursive proof or a refutation for the formula
* `f' in the `state'th state of the state space described by
* the contents of `this->path_states'.
*
* Arguments: estream -- A reference to an exception-aware output
* stream.
* indent -- Number of spaces to leave to the left of output.
* state -- Index of a state in the path.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
static string line_prefix = "";
const bool prove_true = eval_info.find(f)->second->test(state);
estream << string(indent, ' ')
+ (line_prefix.size() == 0
? ""
: line_prefix.substr(0, line_prefix.size() - 4) + "+-> ")
+ "M,<s"
<< path_states[state]
<< string(", ...> |") + (prove_true ? '=' : '/') + "= "
<< *f;
switch (f->what())
{
case LTL_ATOM :
case LTL_TRUE :
case LTL_FALSE :
estream << '\n';
return;
case LTL_NEGATION :
/*
* To display a proof (refutation) for a negated formula, display a
* refutation (proof) for the non-negated formula.
*/
line_prefix += " ";
estream << " :\n";
recPrint(estream, indent, static_cast<const Not*>(f)->subformula, state);
break;
case LTL_NEXT :
{
/*
* To display a proof or refutation for a Next formula, display a
* proof or refutation for the subformula of the Next operator in
* the next state of the path.
*/
estream << " :\n" + string(indent, ' ') + line_prefix + "+-> s"
<< path_states[state]
<< " --> s";
state++;
if (state == path_states.size())
state = current_loop_state;
estream << path_states[state] << '\n';
line_prefix += " ";
recPrint(estream, indent, static_cast<const Next*>(f)->subformula,
state);
break;
}
case LTL_CONJUNCTION : case LTL_DISJUNCTION : case LTL_IMPLICATION :
case LTL_EQUIVALENCE : case LTL_XOR :
{
/*
* Formula: f1 OP f2
*
* proof/refutation OP what will be shown
* ------------------------------------------------------------------
* proof /\ proofs for `f1' and `f2'
*
* refutation /\ refutation for `f1' or `f2'
*
* proof \/ proof for `f1' or `f2'
*
* refutation \/ refutation for `f1 and `f2'
*
* proof -> proof for `f2' or refutation for
* `f1'
*
* refutation -> proof for `f1' and refutation for
* `f2'
*
* proof <-> proofs or refutations for both
* `f1' and `f2'
*
* refutation <-> proof for `f1' and refutation for
* `f2' or vice versa
*
* proof xor proof for `f1' and refutation for
* `f2' or vice versa
*
* refutation xor proofs or refutations for both
* `f1' and `f2'
*/
estream << " :\n";
line_prefix += "| ";
const LtlFormula* f1, *f2;
bool branch, val1, val2;
switch (f->what())
{
case LTL_CONJUNCTION :
f1 = static_cast<const And*>(f)->subformula1;
f2 = static_cast<const And*>(f)->subformula2;
branch = prove_true;
val1 = val2 = false;
break;
case LTL_DISJUNCTION :
f1 = static_cast<const Or*>(f)->subformula1;
f2 = static_cast<const Or*>(f)->subformula2;
branch = !prove_true;
val1 = val2 = true;
break;
case LTL_IMPLICATION :
f1 = static_cast<const Imply*>(f)->subformula1;
f2 = static_cast<const Imply*>(f)->subformula2;
branch = !prove_true;
val1 = false;
val2 = true;
break;
case LTL_EQUIVALENCE :
f1 = static_cast<const Equiv*>(f)->subformula1;
f2 = static_cast<const Equiv*>(f)->subformula2;
branch = true;
break;
default : /* LTL_XOR */
f1 = static_cast<const Xor*>(f)->subformula1;
f2 = static_cast<const Xor*>(f)->subformula2;
branch = true;
break;
}
if (branch)
{
recPrint(estream, indent, f1, state);
line_prefix[line_prefix.size() - 4] = ' ';
recPrint(estream, indent, f2, state);
}
else
{
line_prefix[line_prefix.size() - 4] = ' ';
if (eval_info.find(f2)->second->test(state) != val2)
recPrint(estream, indent, f1, state);
else if (eval_info.find(f1)->second->test(state) != val1)
recPrint(estream, indent, f2, state);
else if ((f1->propositional() && !f2->propositional())
|| (f1->constant() && !f2->constant()))
recPrint(estream, indent, f1, state);
else if ((f2->propositional() && !f1->propositional())
|| (f2->constant() && !f1->constant()))
recPrint(estream, indent, f2, state);
else if (f1->size() <= f2->size())
recPrint(estream, indent, f1, state);
else
recPrint(estream, indent, f2, state);
}
break;
}
default : /* LTL_UNTIL || LTL_FINALLY || LTL_V || LTL_GLOBALLY
|| LTL_BEFORE || LTL_WEAK_UNTIL || LTL_STRONG_RELEASE */
{
/*
* Formula: f1 OP f2
*
* proof/refutation OP what will be shown
* ------------------------------------------------------------------
* proof U proofs for `f1' until finding a
* state in which `f2' holds;
* then show a proof for `f2'
*
* refutation U refutations for `f2' until
* finding a state in which `f1'
* does not hold OR until some
* state is visited twice (in
* which case `f2' never holds in
* the path); if the search ends
* in a state where `f1' does not
* hold, show a refutation for
* `f1' and `f2' in the state
*
* proof <> proof for `f2' in the first state
* in which `f2' holds
*
* refutation <> refutation for `f2' in all states
* of the path
*
* proof V proofs for `f2' until finding a
* state in which `f1' holds OR
* until some state is visited
* twice (in which case `f2'
* always holds in the path); if
* the search ends in a state
* where `f1' holds, show a proof
* for `f1' and `f2' in the state
*
* refutation V refutations for `f1' until
* finding a state in which `f2'
* does not hold; then show a
* refutation for `f2'
*
* proof [] proof for `f2' in all states of
* the path
*
* refutation [] refutation for `f2' in the first
* state in which `f2' does not
* hold
*
* proof W proofs for `f1' until finding a
* state in which `f2' holds or
* until some state is visited
* twice (in which case `f1'
* always holds in the path);
* if the search ends in a state
* in which `f2' holds, show a
* proof for `f2'
*
* refutation W refutations for `f2' until
* finding a state in which
* neither `f1' and `f2' hold;
* then show a refutation for
* `f1' and `f2'
*
* proof M proofs for `f2' until finding a
* state in which both `f1' and
* `f2' hold; then show a proof
* for `f1' and `f2'
*
* refutation M refutations for `f1' until
* finding a state in which `f2'
* does not hold or until some
* state is visited twice (in
* which case `f1' never holds in
* the path); if the search ends
* in a state in which `f2' does
* not hold, show a refutation
* for `f2'
*
* proof B refutations for `f2' until
* finding a state in which `f1'
* holds OR until some state is
* visited twice (in which case
* `f2' never holds in the path);
* if the search ends in a state
* where `f1' holds, show a proof
* for `f1' and a refutation for
* `f2' in the state
*
* refutation B refutations for `f1' until
* finding a state in which `f2'
* holds; then show a proof for
* `f2'
*
*/
estream << " :\n";
line_prefix += "| ";
const LtlFormula* f1;
const LtlFormula* f2;
bool eventuality, check_value_1, check_value_2;
switch (f->what())
{
case LTL_UNTIL :
f1 = static_cast<const Until*>(f)->subformula1;
f2 = static_cast<const Until*>(f)->subformula2;
eventuality = true;
check_value_1 = check_value_2 = true;
break;
case LTL_FINALLY :
f1 = 0;
f2 = static_cast<const Finally*>(f)->subformula;
eventuality = true;
check_value_1 = check_value_2 = true;
break;
case LTL_V :
f1 = static_cast<const V*>(f)->subformula1;
f2 = static_cast<const V*>(f)->subformula2;
eventuality = false;
check_value_1 = check_value_2 = false;
break;
case LTL_GLOBALLY :
f1 = 0;
f2 = static_cast<const Globally*>(f)->subformula;
eventuality = false;
check_value_1 = check_value_2 = false;
break;
case LTL_BEFORE :
f1 = static_cast<const Before*>(f)->subformula1;
f2 = static_cast<const Before*>(f)->subformula2;
eventuality = false;
check_value_1 = false;
check_value_2 = true;
break;
case LTL_WEAK_UNTIL : /* note the order of `f1' and `f2' */
f1 = static_cast<const WeakUntil*>(f)->subformula2;
f2 = static_cast<const WeakUntil*>(f)->subformula1;
eventuality = false;
check_value_1 = check_value_2 = false;
break;
default : /* LTL_STRONG_RELEASE; note the order of `f1' and `f2' */
f1 = static_cast<const StrongRelease*>(f)->subformula2;
f2 = static_cast<const StrongRelease*>(f)->subformula1;
eventuality = true;
check_value_1 = check_value_2 = true;
break;
}
if (prove_true == eventuality)
{
while (eval_info.find(f2)->second->test(state) != check_value_2)
{
if (f1 != 0)
recPrint(estream, indent, f1, state);
estream << string(indent, ' ')
+ line_prefix.substr(0, line_prefix.size() - 4)
+ "+-> s"
<< path_states[state]
<< " --> s";
state++;
if (state == path_states.size())
state = current_loop_state;
estream << path_states[state] << '\n';
}
if (f->what() == LTL_WEAK_UNTIL || f->what() == LTL_STRONG_RELEASE)
{
recPrint(estream, indent, f2, state);
line_prefix[line_prefix.size() - 4] = ' ';
recPrint(estream, indent, f1, state);
}
else
{
line_prefix[line_prefix.size() - 4] = ' ';
recPrint(estream, indent, f2, state);
}
}
else
{
StateSpace::size_type start_state = state;
while (f1 == 0
|| eval_info.find(f1)->second->test(state) == check_value_1)
{
recPrint(estream, indent, f2, state);
estream << string(indent, ' ')
+ line_prefix.substr(0, line_prefix.size() - 4)
+ "+-> s"
<< path_states[state]
<< " --> s";
state++;
if (state == path_states.size())
{
state = current_loop_state;
if (start_state < current_loop_state)
{
estream << path_states[state] << '\n';
break;
}
}
estream << path_states[state] << '\n';
if (state == start_state)
break;
}
if (f1 != 0
&& eval_info.find(f1)->second->test(state) != check_value_1)
{
if (f->what() == LTL_WEAK_UNTIL || f->what() == LTL_STRONG_RELEASE)
{
line_prefix[line_prefix.size() - 4] = ' ';
recPrint(estream, indent, f1, state);
}
else
{
recPrint(estream, indent, f1, state);
line_prefix[line_prefix.size() - 4] = ' ';
recPrint(estream, indent, f2, state);
}
}
}
break;
}
}
line_prefix.resize(line_prefix.size() - 4);
}
}

View file

@ -1,165 +0,0 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* 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 PATHEVALUATOR_H
#define PATHEVALUATOR_H
#include <iostream>
#include <map>
#include "LbttAlloc.h"
#include "BitArray.h"
#include "Exception.h"
#include "LtlFormula.h"
#include "StateSpace.h"
namespace Ltl
{
using namespace Graph;
/******************************************************************************
*
* A class for testing whether an LtlFormula holds in a StateSpace that
* consists of states connected into a non-branching sequence, which ends in a
* loop.
*
*****************************************************************************/
class PathEvaluator
{
public:
PathEvaluator(); /* Constructor. */
~PathEvaluator(); /* Destructor. */
void reset(); /* Prepares the object for
* a new evaluation run.
*/
bool evaluate /* Tests whether an */
(const LtlFormula& formula, /* LtlFormula holds in a */
const StateSpace::Path& prefix, /* path described by a */
const StateSpace::Path& cycle, /* prefix and a cycle of */
const StateSpace& statespace); /* states from a state
* space.
*/
bool evaluate /* Same as above. */
(const LtlFormula& formula,
const StateSpace& statespace);
bool getResult(StateSpace::size_type state) /* Returns the result of */
const; /* the evaluation in a
* given state of the
* current path after a
* call to `evaluate'.
*/
void print /* Displays the results */
(ostream& stream = cout, /* after a call to */
const int indent = 0) const; /* `evaluate'. */
private:
PathEvaluator(const PathEvaluator&); /* Prevent copying and */
PathEvaluator& operator=(const PathEvaluator&); /* assignment of
* PathEvaluator
* objects.
*/
bool eval(); /* Evaluates a formula
* on a path.
*/
void recPrint /* Recursively prints */
(Exceptional_ostream& estream, /* a proof or a */
const int indent, /* refutation for a */
const LtlFormula* f, /* formula. */
StateSpace::size_type state) const;
const LtlFormula* current_formula; /* LTL formula associated
* with the path evaluator.
*/
const StateSpace* current_path; /* State space associated
* with the path evaluator.
*/
StateSpace::size_type current_loop_state; /* Number of the target
* state of the loop on
* the current path.
*/
vector<StateSpace::size_type> path_states; /* Correspondence
* between states of the
* path and the states
* of the current state
* space.
*/
map<const LtlFormula*, BitArray*, /* Information about the */
LtlFormula::ptr_less> /* truth values of the */
eval_info; /* subformulae of the
* formula to be
* evaluated.
*/
};
/******************************************************************************
*
* Inline function definitions for class PathEvaluator.
*
*****************************************************************************/
/* ========================================================================= */
inline PathEvaluator::PathEvaluator() :
current_formula(static_cast<const LtlFormula*>(0)),
current_path(static_cast<const StateSpace*>(0)),
current_loop_state(0)
/* ----------------------------------------------------------------------------
*
* Description: Constructor for class PathEvaluator.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
inline PathEvaluator::~PathEvaluator()
/* ----------------------------------------------------------------------------
*
* Description: Destructor for class PathEvaluator.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
reset();
}
}
#endif /* !PATHEVALUATOR_H */

View file

@ -1,198 +0,0 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* 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.
*/
#include <config.h>
#include "BitArray.h"
#include "PathIterator.h"
namespace Graph
{
/******************************************************************************
*
* Function definitions for class PathIterator.
*
*****************************************************************************/
/* ========================================================================= */
PathIterator::PathIterator
(unsigned long int propositions_per_state,
StateSpace::size_type number_of_states) :
path(propositions_per_state, number_of_states), loop_target_state(0)
/* ----------------------------------------------------------------------------
*
* Description: Constructor for class PathIterator. Creates a new object for
* enumerating all paths with a given number of states and
* atomic propositions.
*
* Arguments: propositions_per_state -- Number of atomic propositions
* per a state in the path.
* number_of_states -- Number of states in the path.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
StateSpace::size_type state;
for (state = 0; (state + 1) < number_of_states; state++)
path.connect(state, state + 1);
path.connect(state, 0);
}
/* ========================================================================= */
bool PathIterator::operator==(const PathIterator& it) const
/* ----------------------------------------------------------------------------
*
* Description: Equivalence operator for class PathIterator. Two
* PathIterators are equivalent if and only if all of the
* following conditions hold:
* (1) Both iterators point to paths of equal size with the
* same number of atomic propositions in each state.
* (2) Starting from the initial states of the paths pointed
* to by the individual iterators, the paths agree on
* the truth values of the atomic propositions in the
* corresponding states of the paths.
* (3) Both paths contain a cycle of an equal length.
*
* Argument: it -- A constant reference to a PathIterator.
*
* Returns: A truth value according to the result of the test.
*
* ------------------------------------------------------------------------- */
{
if (loop_target_state != it.loop_target_state
|| path.size() != it.path.size()
|| path.numberOfPropositions() != it.path.numberOfPropositions())
return false;
StateSpace::size_type state;
for (state = 0;
state < path.size()
&& path[state].positiveAtoms().equal(it.path[state].positiveAtoms(),
path.numberOfPropositions());
state++)
;
return (state == path.size());
}
/* ========================================================================= */
bool PathIterator::operator!=(const PathIterator& it) const
/* ----------------------------------------------------------------------------
*
* Description: Inequivalence operator for class PathIterator. See above for
* the definition of equivalence between two PathIterators; two
* PathIterators are inequal if and only if they are not equal.
*
* Argument: it -- A constant reference to a PathIterator.
*
* Returns: A truth value according to the result of the test.
*
* ------------------------------------------------------------------------- */
{
if (loop_target_state != it.loop_target_state
|| path.size() != it.path.size()
|| path.numberOfPropositions() != it.path.numberOfPropositions())
return true;
StateSpace::size_type state;
for (state = 0;
state < path.size()
&& path[state].positiveAtoms().equal(it.path[state].positiveAtoms(),
path.numberOfPropositions());
state++)
;
return (state != path.size());
}
/* ========================================================================= */
void PathIterator::computeNextPath()
/* ----------------------------------------------------------------------------
*
* Description: Updates the path pointed to by the PathIterator to the
* `next' path in the sequence. The sequence is constructed by
* identifying the sequence as a binary integer (obtained by
* concatenating the truth valuations for the atomic
* propositions in each state) which is then incremented. If
* there is an overflow, the `loop state' is changed until it
* exceeds the length of the path.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
if (atEnd())
return;
StateSpace::size_type state;
const unsigned long int number_of_propositions(path.numberOfPropositions());
/*
* Find the first state in the current path where some proposition has the
* value `false'. Change the truth value of all propositions to `false'
* in all states preceding this state.
*/
for (state = 0;
state < path.size()
&& path[state].positiveAtoms().count(number_of_propositions)
== number_of_propositions;
state++)
path[state].positiveAtoms().clear(number_of_propositions);
if (state == path.size())
{
/*
* If the path did not contain a state in which some proposition had the
* value `false', update the `loop state' in the path.
*/
path.disconnect(path.size() - 1, loop_target_state);
loop_target_state++;
if (loop_target_state < path.size())
path.connect(path.size() - 1, loop_target_state);
}
else
{
/*
* In other case, change the truth value of the proposition to `true' in
* the state and reset the truth values of all propositions with smaller
* identifiers to `false'.
*/
BitArray& truth_assignment = path[state].positiveAtoms();
unsigned long int proposition;
for (proposition = 0; truth_assignment[proposition]; proposition++)
truth_assignment.clearBit(proposition);
truth_assignment.setBit(proposition);
}
}
}

View file

@ -1,204 +0,0 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* 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 PATHITERATOR_H
#define PATHITERATOR_H
#include <config.h>
#include "StateSpace.h"
using namespace std;
namespace Graph
{
/******************************************************************************
*
* An iterator class for systematically enumerating all state spaces consisting
* of a single infinite path (a prefix and a loop) with a given number of
* states and a given number of atomic propositions in each state.
*
*****************************************************************************/
class PathIterator
{
public:
PathIterator /* Constructor. */
(unsigned long int propositions_per_state,
StateSpace::size_type number_of_states);
/* default copy constructor */
~PathIterator(); /* Destructor. */
/* default assignment operator */
bool operator==(const PathIterator& it) /* Equivalence operator. */
const;
bool operator!=(const PathIterator& it) /* Inequivalence operator.
*/
const;
const StateSpace& operator*() const; /* Dereferencing */
const StateSpace* operator->() const; /* operators. */
const StateSpace& operator++(); /* Increment operators. */
const StateSpace operator++(int);
bool atEnd() const; /* Tells whether the
* iterator has enumerated
* all the state spaces in
* the range determined by
* the parameters with
* which the iterator was
* initialized.
*/
private:
void computeNextPath(); /* Updates the state space
* currently pointed to by
* the iterator.
*/
StateSpace path; /* The state space (the
* path) currently pointed
* to by the iterator.
*/
StateSpace::size_type loop_target_state; /* Identifier of the target
* state of the last state
* in the path.
*/
};
/******************************************************************************
*
* Inline function definitions for class PathIterator.
*
*****************************************************************************/
/* ========================================================================= */
inline PathIterator::~PathIterator()
/* ----------------------------------------------------------------------------
*
* Description: Destructor for class PathIterator.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
inline const StateSpace& PathIterator::operator*() const
/* ----------------------------------------------------------------------------
*
* Description: Dereferencing operator for class PathIterator. Gives access
* to the state space currently pointed to by the iterator.
*
* Arguments: None.
*
* Returns: A constant reference to the state space currently pointed to
* by the iterator.
*
* ------------------------------------------------------------------------- */
{
return path;
}
/* ========================================================================= */
inline const StateSpace* PathIterator::operator->() const
/* ----------------------------------------------------------------------------
*
* Description: Dereferencing operator for class PathIterator. Gives access
* to the state space currently pointed to by the iterator.
*
* Arguments: None.
*
* Returns: A pointer to a constant state space currently pointed to by
* the iterator.
*
* ------------------------------------------------------------------------- */
{
return &path;
}
/* ========================================================================= */
inline const StateSpace& PathIterator::operator++()
/* ----------------------------------------------------------------------------
*
* Description: Prefix increment operator for class PathIterator. Computes
* the next path in the graph sequence and returns a constant
* reference to it.
*
* Arguments: None.
*
* Returns: A constant reference to the updated state space pointer to by
* the iterator.
*
* ------------------------------------------------------------------------- */
{
computeNextPath();
return path;
}
/* ========================================================================= */
inline const StateSpace PathIterator::operator++(int)
/* ----------------------------------------------------------------------------
*
* Description: Postfix increment operator for class PathIterator. Computes
* the next path in the graph sequence and returns the graph
* pointed to by the iterator after this operation.
*
* Arguments: None.
*
* Returns: A constant reference to the state space pointed to by the
* iterator before computing the next path in the sequence.
*
* ------------------------------------------------------------------------- */
{
StateSpace old_path(path);
computeNextPath();
return old_path;
}
/* ========================================================================= */
inline bool PathIterator::atEnd() const
/* ----------------------------------------------------------------------------
*
* Description: Tells whether all possible paths have been enumerated by the
* iterator.
*
* Arguments: None.
*
* Returns: A truth value according to the result of the test.
*
* ------------------------------------------------------------------------- */
{
return (loop_target_state == path.size());
}
}
#endif /* !PATHITERATOR_H */

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

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

View file

@ -1,96 +0,0 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* 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 RANDOM_H
#define RANDOM_H
#include <config.h>
#include <cstdlib>
#ifdef HAVE_RAND48
#define rand lrand48
#define srand srand48
static const double MAXRAND = static_cast<double>(1 << 30) * 2.0;
#else
static const double MAXRAND = RAND_MAX + 1.0;
#endif /* HAVE_RAND48 */
/******************************************************************************
*
* Functions for random number generation. If HAVE_RAND48 is defined, the
* functions rely on the lrand48() function for generating a random integer
* between 0 and 2^31 and srand48() for setting the seed for the random
* number generator; otherwise, the rand() and srand() functions are used,
* respectively.
*
*****************************************************************************/
/* ========================================================================= */
inline void SRAND(unsigned int seed)
/* ----------------------------------------------------------------------------
*
* Description: Initializes the random number generator with a seed value.
*
* Argument: seed -- Seed for the random number generator.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
srand (seed);
}
/* ========================================================================= */
inline double DRAND()
/* ----------------------------------------------------------------------------
*
* Description: Generates a random double.
*
* Arguments: None.
*
* Returns: A random double in the half-open interval [0.0,1.0).
*
* ------------------------------------------------------------------------- */
{
return rand () / MAXRAND;
}
/* ========================================================================= */
inline long int LRAND(long int min, long int max)
/* ----------------------------------------------------------------------------
*
* Description: Generates a random long integer in a given interval.
*
* Arguments: min, max -- Bounds for the interval.
*
* Returns: A random long integer in the half-open interval [min,max).
*
* ------------------------------------------------------------------------- */
{
return min + static_cast<long int>(DRAND() * (max - min));
}
#ifdef HAVE_RAND48
#undef rand
#undef srand
#endif /* HAVE_RAND48 */
#endif /* !RANDOM_H */

File diff suppressed because it is too large Load diff

View file

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

View file

@ -1,55 +0,0 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* 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 SHAREDTESTDATA_H
#define SHAREDTESTDATA_H
#include <vector>
#include "LbttAlloc.h"
#include "Exception.h"
#include "TestRoundInfo.h"
#include "TestStatistics.h"
/******************************************************************************
*
* Declarations of variables for storing test results and maintaining test
* state information.
*
*****************************************************************************/
namespace SharedTestData
{
extern TestRoundInfo round_info; /* Data structure for
* storing information
* about the current test
* round.
*/
extern vector<AlgorithmTestResults> test_results; /* Test results for each
* implementation.
*/
extern vector<TestStatistics> final_statistics; /* Overall test
* statistics for each
* implementation.
*/
}
#endif /* !SHAREDTESTDATA_H */

View file

@ -1,119 +0,0 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* 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.
*/
#include <config.h>
#ifdef HAVE_SSTREAM
#include <sstream>
#else
#include <strstream>
#endif /* HAVE_SSTREAM */
#include "Exception.h"
#include "FormulaWriter.h"
#include "NeverClaimAutomaton.h"
#include "SpinWrapper.h"
/******************************************************************************
*
* Definitions for operator symbols specific to Spin.
*
*****************************************************************************/
const char SpinWrapper::SPIN_AND[] = "&&";
const char SpinWrapper::SPIN_OR[] = "||";
/******************************************************************************
*
* Function definitions for class SpinWrapper.
*
*****************************************************************************/
/* ========================================================================= */
void SpinWrapper::translateFormula
(const ::Ltl::LtlFormula& formula, string& translated_formula)
/* ----------------------------------------------------------------------------
*
* Description: Translates an LtlFormula into a string which contains the
* formula in the input syntax of Spin.
*
* Arguments: formula -- The LtlFormula to be translated.
* translated_formula -- A reference to a string for storing
* the results.
*
* Returns: Nothing. The result of the translation can be found in
* the string `translated_formula'.
*
* ------------------------------------------------------------------------- */
{
using namespace Ltl;
#ifdef HAVE_SSTREAM
ostringstream translated_formula_stream;
#else
ostrstream translated_formula_stream;
#endif /* HAVE_SSTREAM */
Exceptional_ostream estream(&translated_formula_stream, ios::goodbit);
FormulaWriter<ConstantWriter<LtlTrue::infix_symbol>,
ConstantWriter<LtlFalse::infix_symbol>,
AtomWriter,
UnaryOperatorWriter<LtlNegation::infix_symbol>,
UnaryOperatorWriter<LtlNext::infix_symbol>,
UnaryOperatorWriter<LtlFinally::infix_symbol>,
UnaryOperatorWriter<LtlGlobally::infix_symbol>,
BinaryOperatorInfixWriter<SPIN_AND>,
BinaryOperatorInfixWriter<SPIN_OR>,
BinaryOperatorInfixWriter<LtlImplication::infix_symbol>,
BinaryOperatorInfixWriter<LtlEquivalence::infix_symbol>,
WriterErrorReporter,
BinaryOperatorInfixWriter<LtlUntil::infix_symbol>,
BinaryOperatorInfixWriter<LtlV::infix_symbol>,
WriterErrorReporter,
WriterErrorReporter,
WriterErrorReporter>
fw(estream);
formula.traverse(fw, LTL_PREORDER | LTL_INORDER | LTL_POSTORDER);
translated_formula = translated_formula_stream.str();
#ifndef HAVE_SSTREAM
translated_formula_stream.freeze(0);
#endif /* HAVE_SSTREAM */
}
/* ========================================================================= */
void SpinWrapper::parseAutomaton
(const string& input_filename, const string& output_filename)
/* ----------------------------------------------------------------------------
*
* Description: Parses the never claim in the output returned by Spin and
* converts it into lbtt format.
*
* Arguments: input_filename -- Name of the input file.
* output_filename -- Name of the output file.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
NeverClaimAutomaton automaton;
automaton.read(input_filename.c_str());
automaton.write(output_filename.c_str());
}

View file

@ -1,122 +0,0 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* 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 SPINWRAPPER_H
#define SPINWRAPPER_H
#include <config.h>
#include <string>
#include "ExternalTranslator.h"
#include "LtlFormula.h"
/******************************************************************************
*
* Interface class for Spin.
*
*****************************************************************************/
class SpinWrapper : public ExternalTranslator
{
public:
SpinWrapper(); /* Constructor. */
~SpinWrapper(); /* Destructor. */
void translateFormula /* Translates a formula */
(const ::Ltl::LtlFormula& formula, /* into a Büchi */
string& translated_formula); /* automaton. */
/* `formatInput' inherited from ExternalTranslator */
string commandLine /* Prepares the command */
(const string& input_filename, /* line for executing */
const string& output_filename); /* Spin. */
/* `execSuccess' inherited from ExternalTranslator */
void parseAutomaton /* Translates the output */
(const string& input_filename, /* of the translation */
const string& output_filename); /* algorithm into lbtt
* format.
*/
private:
SpinWrapper(const SpinWrapper&); /* Prevent copying and */
SpinWrapper& operator=(const SpinWrapper&); /* assignment of
* SpinWrapper objects.
*/
static const char SPIN_AND[]; /* Symbols for */
static const char SPIN_OR[]; /* operators. */
};
/******************************************************************************
*
* Inline function definitions for class SpinWrapper.
*
*****************************************************************************/
/* ========================================================================= */
inline SpinWrapper::SpinWrapper()
/* ----------------------------------------------------------------------------
*
* Description: Constructor for class SpinWrapper.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
inline SpinWrapper::~SpinWrapper()
/* ----------------------------------------------------------------------------
*
* Description: Destructor for class SpinWrapper.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
inline string SpinWrapper::commandLine
(const string& input_filename, const string& output_filename)
/* ----------------------------------------------------------------------------
*
* Description: Prepares the command line for Spin.
*
* Arguments: input_filename -- Name of the input file.
* output_filename -- Name of the output file.
*
* Returns: The command line string.
*
* ------------------------------------------------------------------------- */
{
return string(" -F ") + input_filename + " >" + output_filename;
}
#endif /* !SPINWRAPPER_H */

View file

@ -1,102 +0,0 @@
/*
* Copyright (C) 2003, 2004, 2010
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* Derived from SpinWrapper.cc by Alexandre Duret-Lutz <adl@src.lip6.fr>.
*
* 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.
*/
#include <config.h>
#ifdef HAVE_SSTREAM
#include <sstream>
#else
#include <strstream>
#endif /* HAVE_SSTREAM */
#include "Exception.h"
#include "FormulaWriter.h"
#include "NeverClaimAutomaton.h"
#include "SpotWrapper.h"
/******************************************************************************
*
* Definitions for operator symbols specific to Spot.
*
*****************************************************************************/
const char SpotWrapper::SPOT_AND[] = "&&";
const char SpotWrapper::SPOT_OR[] = "||";
const char SpotWrapper::SPOT_XOR[] = "^";
/******************************************************************************
*
* Function definitions for class SpotWrapper.
*
*****************************************************************************/
/* ========================================================================= */
void SpotWrapper::translateFormula
(const ::Ltl::LtlFormula& formula, string& translated_formula)
/* ----------------------------------------------------------------------------
*
* Description: Translates an LtlFormula into a string which contains the
* formula in the input syntax of Spot.
*
* Arguments: formula -- The LtlFormula to be translated.
* translated_formula -- A reference to a string for storing
* the results.
*
* Returns: Nothing. The result of the translation can be found in
* the string `translated_formula'.
*
* ------------------------------------------------------------------------- */
{
using namespace Ltl;
#ifdef HAVE_SSTREAM
ostringstream translated_formula_stream;
#else
ostrstream translated_formula_stream;
#endif /* HAVE_SSTREAM */
Exceptional_ostream estream(&translated_formula_stream, ios::goodbit);
FormulaWriter<ConstantWriter<LtlTrue::infix_symbol>,
ConstantWriter<LtlFalse::infix_symbol>,
AtomWriter,
UnaryOperatorWriter<LtlNegation::infix_symbol>,
UnaryOperatorWriter<LtlNext::infix_symbol>,
UnaryOperatorWriter<LtlFinally::infix_symbol>,
UnaryOperatorWriter<LtlGlobally::infix_symbol>,
BinaryOperatorInfixWriter<SPOT_AND>,
BinaryOperatorInfixWriter<SPOT_OR>,
BinaryOperatorInfixWriter<LtlImplication::infix_symbol>,
BinaryOperatorInfixWriter<LtlEquivalence::infix_symbol>,
BinaryOperatorInfixWriter<SPOT_XOR>,
BinaryOperatorInfixWriter<LtlUntil::infix_symbol>,
BinaryOperatorInfixWriter<LtlV::infix_symbol>,
BinaryOperatorInfixWriter<LtlWeakUntil::infix_symbol>,
BinaryOperatorInfixWriter<LtlStrongRelease::infix_symbol>,
WriterErrorReporter>
fw(estream);
formula.traverse(fw, LTL_PREORDER | LTL_INORDER | LTL_POSTORDER);
translated_formula = translated_formula_stream.str();
#ifndef HAVE_SSTREAM
translated_formula_stream.freeze(0);
#endif /* HAVE_SSTREAM */
}

View file

@ -1,143 +0,0 @@
/*
* Copyright (C) 2003, 2004
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* Derived from SpinWrapper.h by Alexandre Duret-Lutz <adl@src.lip6.fr>.
*
* 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 SPOTWRAPPER_H
#define SPOTWRAPPER_H
#include <config.h>
#include <string>
#include "ExternalTranslator.h"
#include "LtlFormula.h"
/******************************************************************************
*
* Interface class for Spot.
*
*****************************************************************************/
class SpotWrapper : public ExternalTranslator
{
public:
SpotWrapper(); /* Constructor. */
~SpotWrapper(); /* Destructor. */
void translateFormula /* Translates a formula */
(const ::Ltl::LtlFormula& formula, /* into a Büchi */
string& translated_formula); /* automaton. */
/* `formatInput' inherited from ExternalTranslator */
string commandLine /* Prepares the command */
(const string& input_filename, /* line for executing */
const string& output_filename); /* Spot. */
/* `execSuccess' inherited from ExternalTranslator */
void parseAutomaton /* Translates the output */
(const string& input_filename, /* of the translation */
const string& output_filename); /* algorithm into lbtt
* format.
*/
private:
SpotWrapper(const SpotWrapper&); /* Prevent copying and */
SpotWrapper& operator=(const SpotWrapper&); /* assignment of
* SpotWrapper objects.
*/
static const char SPOT_AND[]; /* Symbols for */
static const char SPOT_OR[]; /* operators. */
static const char SPOT_XOR[];
};
/******************************************************************************
*
* Inline function definitions for class SpotWrapper.
*
*****************************************************************************/
/* ========================================================================= */
inline SpotWrapper::SpotWrapper()
/* ----------------------------------------------------------------------------
*
* Description: Constructor for class SpotWrapper.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
inline SpotWrapper::~SpotWrapper()
/* ----------------------------------------------------------------------------
*
* Description: Destructor for class SpotWrapper.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
inline string SpotWrapper::commandLine
(const string& input_filename, const string&)
/* ----------------------------------------------------------------------------
*
* Description: Prepares the command line for Spot.
*
* Arguments: input_filename -- Name of the input file.
* The other argument is only needed for supporting the
* ExternalTranslator interface; the output will be written to
* the filename stored in `command_line_arguments[4]'.
*
* Returns: The command line string.
*
* ------------------------------------------------------------------------- */
{
return (string(" ") + input_filename
+ " >" + string(command_line_arguments[4]));
}
/* ========================================================================= */
inline void SpotWrapper::parseAutomaton(const string&, const string&)
/* ----------------------------------------------------------------------------
*
* Description: Dummy function which is needed to support the
* ExternalTranslator interface.
*
* Arguments: References to two constant strings.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
#endif /* !SPOTWRAPPER_H */

File diff suppressed because it is too large Load diff

View file

@ -1,108 +0,0 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* 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 STATDISPLAY_H
#define STATDISPLAY_H
#include <config.h>
#include <iostream>
#include <vector>
#include "LbttAlloc.h"
#include "Configuration.h"
#include "TestStatistics.h"
using namespace std;
extern Configuration configuration;
/******************************************************************************
*
* Functions for displaying test statistics.
*
*****************************************************************************/
namespace StatDisplay
{
void printStatTableHeader /* Displays a table */
(ostream& stream, int indent); /* header for test
* statistics.
*/
void printBuchiAutomatonStats /* Displays information */
(ostream& stream, /* about a Büchi */
int indent, /* automaton. */
vector<AlgorithmTestResults>::size_type
algorithm,
int result_id);
void printProductAutomatonStats /* Displays information */
(ostream& stream, /* about a product */
int indent, /* automaton. */
vector<AlgorithmTestResults>::size_type
algorithm,
int result_id);
void printAcceptanceCycleStats /* Displays information */
(ostream& stream, /* about the acceptance */
int indent, /* cycles of a product */
vector<AlgorithmTestResults>::size_type /* automaton. */
algorithm,
int result_id);
void printConsistencyCheckStats /* Displays the result */
(ostream& stream, /* of the consistency */
int indent, /* check for a given */
vector<AlgorithmTestResults>::size_type /* algorithm. */
algorithm);
void printCrossComparisonStats /* Displays information */
(ostream& stream, int indent, /* about the model */
const IntervalList& algorithms); /* checking result */
/* cross-comparison */
/* check. */
void printBuchiIntersectionCheckStats /* Displays the results */
(ostream& stream, int indent, /* of the Büchi automata */
const IntervalList& algorithms); /* intersection */
/* emptiness checks. */
void printAllStats /* A shorthand for */
(ostream& stream, /* showing all the */
int indent, /* information displayed */
vector<TestStatistics>::size_type algorithm); /* by the previous five
* functions.
*/
void printCollectiveCrossComparisonStats /* Displays a single */
(ostream& stream, /* `cell' of the final */
vector<TestStatistics>::size_type algorithm_y, /* result cross- */
vector<TestStatistics>::size_type algorithm_x, /* comparison table. */
int data_type);
void printCollectiveStats /* Displays average test */
(ostream& stream, int indent); /* data over all the
* test rounds
* performed so far.
*/
}
#endif /* !STATDISPLAY_H */

View file

@ -1,454 +0,0 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* 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.
*/
#include <config.h>
#include <map>
#include "DispUtil.h"
#include "Exception.h"
#include "StateSpace.h"
#include "StringUtil.h"
namespace Graph
{
/******************************************************************************
*
* Function definitions for class StateSpace.
*
*****************************************************************************/
/* ========================================================================= */
StateSpace::StateSpace
(const unsigned long int propositions_per_state,
const size_type initial_number_of_states) :
atoms_per_state(propositions_per_state), initial_state(0)
#ifdef HAVE_OBSTACK_H
, store()
#endif /* HAVE_OBSTACK_H */
/* ----------------------------------------------------------------------------
*
* Description: Constructor for class StateSpace. Initializes a state space
* with a given number of states and with a given number of
* atomic propositions per state.
*
* Arguments: propositions_per_state -- Atomic propositions per state.
* initial_number_of_states -- Initial size of the state space
* (can be grown later).
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
expand(initial_number_of_states);
}
/* ========================================================================= */
StateSpace::StateSpace(const StateSpace& statespace) :
Graph<GraphEdgeContainer>(), atoms_per_state(statespace.atoms_per_state),
initial_state(statespace.initial_state)
#ifdef HAVE_OBSTACK_H
, store()
#endif /* HAVE_OBSTACK_H */
/* ----------------------------------------------------------------------------
*
* Description: Copy constructor for class StateSpace. Creates a copy of a
* StateSpace object.
*
* Argument: statespace -- StateSpace to be copied.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
expand(statespace.size());
for (size_type state = 0; state < size(); ++state)
{
for (GraphEdgeContainer::const_iterator transition
= statespace[state].edges().begin();
transition != statespace[state].edges().end();
++transition)
connect(state, (*transition)->targetNode());
operator[](state).positiveAtoms().copy(statespace[state].positiveAtoms(),
atoms_per_state);
}
}
/* ========================================================================= */
StateSpace& StateSpace::operator=(const StateSpace& statespace)
/* ----------------------------------------------------------------------------
*
* Description: Assignment operator for class StateSpace. Assigns the
* contents of a state space to another one.
*
* Argument: statespace -- A reference to the constant StateSpace whose
* contents are to be copied.
*
* Returns: A reference to the StateSpace assigned to.
*
* ------------------------------------------------------------------------- */
{
if (&statespace != this)
{
clear();
expand(statespace.size());
atoms_per_state = statespace.atoms_per_state;
initial_state = statespace.initial_state;
for (size_type state = 0; state < size(); ++state)
{
for (GraphEdgeContainer::const_iterator transition
= statespace[state].edges().begin();
transition != statespace[state].edges().end();
++transition)
connect(state, (*transition)->targetNode());
operator[](state).positiveAtoms().copy(statespace[state].positiveAtoms(),
atoms_per_state);
}
}
return *this;
}
/* ========================================================================= */
void StateSpace::clear()
/* ----------------------------------------------------------------------------
*
* Description: Makes the automaton empty.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
atoms_per_state = 0;
initial_state = 0;
#ifdef HAVE_OBSTACK_H
for (vector<Node*>::iterator state = nodes.begin(); state != nodes.end();
++state)
static_cast<State*>(*state)->~State();
if (!nodes.empty())
{
store.free(*nodes.begin());
nodes.clear();
nodes.reserve(0);
}
#endif /* HAVE_OBSTACK_H */
Graph<GraphEdgeContainer>::clear();
}
/* ========================================================================= */
StateSpace::size_type StateSpace::expand(size_type node_count)
/* ----------------------------------------------------------------------------
*
* Description: Inserts a given number of states to a StateSpace.
*
* Argument: node_count -- Number of states to be inserted.
*
* Returns: The index of the last inserted state.
*
* ------------------------------------------------------------------------- */
{
nodes.reserve(nodes.size() + node_count);
while (node_count > 0)
{
#ifdef HAVE_OBSTACK_H
void* state_storage = store.alloc(sizeof(State));
State* new_state = new(state_storage) State(atoms_per_state);
#else
State* new_state = new State(atoms_per_state);
#endif /* HAVE_OBSTACK_H */
try
{
nodes.push_back(new_state);
}
catch (...)
{
#ifdef HAVE_OBSTACK_H
new_state->~State();
store.free(state_storage);
#else
delete new_state;
#endif /* HAVE_OBSTACK_H */
throw;
}
node_count--;
}
return size() - 1;
}
/* ========================================================================= */
void StateSpace::connect(const size_type father, const size_type child)
/* ----------------------------------------------------------------------------
*
* Description: Connects two states of the state space.
*
* Arguments: father, child -- Identifiers of two states.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
Edge* edge = operator[](child).incoming_edge;
if (edge != 0)
{
nodes[father]->outgoing_edges.insert(edge);
return;
}
#ifdef HAVE_OBSTACK_H
void* edge_storage = store.alloc(sizeof(Edge));
edge = new(edge_storage) Edge(child);
#else
edge = new Edge(child);
#endif /* HAVE_OBSTACK_H */
try
{
nodes[father]->outgoing_edges.insert(edge);
}
catch (...)
{
#ifdef HAVE_OBSTACK_H
edge->~Edge();
store.free(edge_storage);
#else
delete edge;
#endif /* HAVE_OBSTACK_H */
throw;
}
operator[](child).incoming_edge = edge;
}
/* ========================================================================= */
void StateSpace::disconnect(const size_type father, const size_type child)
/* ----------------------------------------------------------------------------
*
* Description: Disconnects two states of the state space.
*
* Arguments: father, child -- Identifiers for two states.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
Edge e(child);
/*
* Scan the set of `father''s outgoing transitions for a transition to the
* given target state and remove it if such a transition exists.
*/
GraphEdgeContainer::iterator search_edge
= nodes[father]->outgoing_edges.find(&e);
if (search_edge != nodes[father]->outgoing_edges.end())
nodes[father]->outgoing_edges.erase(search_edge);
}
/* ========================================================================= */
void StateSpace::print
(ostream& stream, const int indent, const GraphOutputFormat fmt) const
/* ----------------------------------------------------------------------------
*
* Description: Writes information about a StateSpace 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.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
Exceptional_ostream estream(&stream, ios::failbit | ios::badbit);
if (fmt == DOT)
estream << string(indent, ' ') + "digraph G {\n";
if (nodes.empty())
{
if (fmt == NORMAL)
estream << string(indent, ' ') + "The state space is empty.\n";
}
else
{
if (fmt == NORMAL)
{
pair<size_type, unsigned long int> statistics = stats();
pair<size_type, unsigned long int> reachable_part_statistics =
subgraphStats(initial_state);
estream << string(indent, ' ') + "The state space consists of\n"
+ string(indent + 4, ' ')
<< statistics.first
<< " states and\n" + string(indent + 4, ' ')
<< statistics.second
<< " transitions.\n" + string(indent, ' ')
+ "The reachable part of the state space contains\n"
+ string(indent + 4, ' ')
<< reachable_part_statistics.first
<< " states and\n" + string(indent + 4, ' ')
<< reachable_part_statistics.second
<< " transitions.\n" + string(indent, ' ') + "Initial state: "
<< initial_state << '\n';
}
size_type s = nodes.size();
for (size_type state = 0; state < s; ++state)
{
estream << string(indent, ' ');
if (fmt == NORMAL)
{
estream << "State " << state << ":\n";
operator[](state).print(stream, indent + 4, NORMAL, atoms_per_state);
}
else if (fmt == DOT)
{
GraphEdgeContainer::const_iterator transition;
estream << " n" << state << " [";
if (state == 0)
estream << "style=filled,";
estream << "shape=ellipse,label=\"" << state << ": ";
operator[](state).print(stream, 0, DOT, atoms_per_state);
estream << "\",fontsize=12];\n";
for (transition = nodes[state]->edges().begin();
transition != nodes[state]->edges().end();
++transition)
{
estream << string(indent + 2, ' ') + 'n' << state;
(*transition)->print(stream, indent, fmt);
estream << ";\n";
}
}
}
}
if (fmt == DOT)
estream << string(indent, ' ') + "}\n";
estream.flush();
}
/******************************************************************************
*
* Function definitions for class StateSpace::State.
*
*****************************************************************************/
/* ========================================================================= */
void StateSpace::State::print
(ostream& stream, const int indent, const GraphOutputFormat fmt,
const unsigned long int number_of_atoms) const
/* ----------------------------------------------------------------------------
*
* Description: Writes information about a state of a state space.
*
* Arguments: stream -- A reference to an output stream.
* indent -- Number of spaces to leave to the left of
* output.
* fmt -- Determines the format of output.
* number_of_atoms -- Number of atoms associated with the
* state.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
Exceptional_ostream estream(&stream, ios::failbit | ios::badbit);
if (positive_atoms.count(number_of_atoms) == 0)
{
if (fmt == NORMAL)
estream << string(indent, ' ') + "No true propositions in this state.\n";
else if (fmt == DOT)
estream << "{}";
}
else
{
bool first_printed = false;
if (fmt == NORMAL)
estream << string(indent, ' ') + "True propositions:\n";
string text = "{";
for (unsigned long int atom = 0; atom < number_of_atoms; ++atom)
{
if (positive_atoms[atom])
{
if (first_printed)
text += ", ";
else
first_printed = true;
text += 'p' + ::StringUtil::toString(atom);
}
}
text += '}';
if (fmt == NORMAL)
::DispUtil::printTextBlock(stream, indent + 2, text, 78);
else
estream << text;
}
if (fmt == NORMAL)
{
if (edges().empty())
estream << string(indent, ' ') + "No transitions to other states.\n";
else
{
bool first_printed = false;
estream << string(indent, ' ') + "Transitions to states\n";
string text = "{";
for (GraphEdgeContainer::const_iterator edge = edges().begin();
edge != edges().end();
++edge)
{
if (first_printed)
text += ", ";
else
first_printed = true;
text += ::StringUtil::toString((*edge)->targetNode());
}
text += '}';
::DispUtil::printTextBlock(stream, indent + 2, text, 78);
}
}
estream.flush();
}
}

View file

@ -1,450 +0,0 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* 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 STATESPACE_H
#define STATESPACE_H
#include <config.h>
#include "LbttAlloc.h"
#include "BitArray.h"
#include "EdgeContainer.h"
#include "Graph.h"
using namespace std;
extern bool user_break;
namespace Graph
{
/******************************************************************************
*
* A class for representing state spaces.
*
*****************************************************************************/
class StateSpace : public Graph<GraphEdgeContainer>
{
private:
unsigned long int atoms_per_state; /* Number of propositional
* variables per state in
* the state space.
*/
size_type initial_state; /* Index of the initial
* state of the state
* space.
*/
#ifdef HAVE_OBSTACK_H /* Storage for states */
ObstackAllocator store; /* and transitions. */
#endif /* HAVE_OBSTACK_H */
public:
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
class State : /* A class for */
public Graph<GraphEdgeContainer>::Node /* representing the */
{ /* states of the state
* space.
*/
public:
explicit State /* Constructs a state */
(const unsigned long int /* with a false truth */
number_of_atoms = 0); /* assignment for the
* atomic propositions.
*/
State /* Constructs a state */
(const BitArray& atoms, /* from a given truth */
const unsigned long int number_of_atoms); /* assignment. */
~State(); /* Destructor. */
/* `edges' inherited from Graph<GraphEdgeContainer>::Node */
bool holds /* Test whether a given */
(const unsigned long int atom, /* atomic proposition */
const unsigned long int number_of_atoms) /* holds in the state. */
const;
const BitArray& positiveAtoms() const; /* Get or set the truth */
BitArray& positiveAtoms(); /* assignment for the
* propositional atoms in
* a state.
*/
void print /* Writes information */
(ostream& stream, /* about the state to a */
const int indent, /* stream. */
const GraphOutputFormat fmt) const;
void print /* Writes information */
(ostream& stream, /* about the state to a */
const int indent, /* stream. */
const GraphOutputFormat fmt,
const unsigned long int number_of_atoms)
const;
private:
friend class StateSpace;
State(const State&); /* Prevent copying and */
State& operator=(const State&); /* assignment of State
* objects.
*/
BitArray positive_atoms; /* The set of propositions
* holding in the state.
*/
Edge* incoming_edge; /* The unique edge pointing
* to `this' state.
*/
};
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
explicit StateSpace /* Constructor. */
(const unsigned long int
propositions_per_state = 0,
const size_type initial_number_of_states = 0);
StateSpace(const StateSpace& statespace); /* Copy constructor. */
~StateSpace(); /* Destructor. */
StateSpace& operator= /* Assignment operator. */
(const StateSpace& statespace);
State& operator[](const size_type index) const; /* Indexing operator. No
* range checks are
* performed on the
* argument.
*/
State& node(const size_type index) const; /* Synonym for the indexing
* operator. This function
* will also check the
* range of its argument.
*/
/* `size' inherited from Graph<GraphEdgeContainer> */
/* `empty' inherited from Graph<GraphEdgeContainer> */
void clear(); /* Makes the state space
* empty.
*/
size_type expand(size_type node_count = 1); /* Inserts states to the
* state space.
*/
void connect /* Connects two states */
(const size_type father, /* of the state space. */
const size_type child);
void disconnect /* Disconnects two */
(const size_type father, /* states of the state */
const size_type child); /* space. */
/* `connected' inherited from Graph<GraphEdgeContainer> */
/* `stats' inherited from Graph<GraphEdgeContainer> */
/* `subgraphStats' inherited from Graph<GraphEdgeContainer> */
unsigned long int numberOfPropositions() const; /* Get the number of atomic
* propositions associated
* with each state of the
* state space.
*/
size_type initialState() const; /* Get or set the */
size_type& initialState(); /* initial state of the
* state space.
*/
void print /* Writes information */
(ostream& stream = cout, /* about the state space */
const int indent = 0, /* to a stream. */
const GraphOutputFormat fmt = NORMAL) const;
};
/******************************************************************************
*
* Inline function definitions for class StateSpace.
*
*************************************************************************** */
/* ========================================================================= */
inline StateSpace::~StateSpace()
/* ----------------------------------------------------------------------------
*
* Description: Destructor for class StateSpace.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
clear();
}
/* ========================================================================= */
inline StateSpace::State& StateSpace::operator[](const size_type index) const
/* ----------------------------------------------------------------------------
*
* Description: Indexing operator for class StateSpace. This function can
* be used to refer to the individual states of the state space
* This function does not perform any range checks on its
* argument.
*
* Argument: index -- Index of a state.
*
* Returns: A reference to a state of the state space.
*
* ------------------------------------------------------------------------- */
{
return static_cast<State&>(*nodes[index]);
}
/* ========================================================================= */
inline StateSpace::State& StateSpace::node(const size_type index) const
/* ----------------------------------------------------------------------------
*
* Description: Function for referring to a single state of a StateSpace.
* This function also performs a range check on its argument.
*
* Argument: index -- Index of a state.
*
* Returns: A reference to a state of the state space.
*
* ------------------------------------------------------------------------- */
{
return static_cast<State&>(Graph<GraphEdgeContainer>::node(index));
}
/* ========================================================================= */
inline unsigned long int StateSpace::numberOfPropositions() const
/* ----------------------------------------------------------------------------
*
* Description: Tells the number of atomic propositions associated with each
* state of the state space.
*
* Arguments: None.
*
* Returns: Number of propositions associated with each state of the
* state space.
*
* ------------------------------------------------------------------------- */
{
return atoms_per_state;
}
/* ========================================================================= */
inline StateSpace::size_type StateSpace::initialState() const
/* ----------------------------------------------------------------------------
*
* Description: Returns the number of the initial state of the StateSpace by
* value.
*
* Arguments: None.
*
* Returns: Index of the initial state of the state space.
*
* ------------------------------------------------------------------------- */
{
return initial_state;
}
/* ========================================================================= */
inline StateSpace::size_type& StateSpace::initialState()
/* ----------------------------------------------------------------------------
*
* Description: Returns the number of the initial state of the StateSpace by
* reference. This function can therefore be used to change the
* initial state.
*
* Arguments: None.
*
* Returns: A reference to the index of the initial state.
*
* ------------------------------------------------------------------------- */
{
return initial_state;
}
/******************************************************************************
*
* Inline function definitions for class StateSpace::State.
*
*****************************************************************************/
/* ========================================================================= */
inline StateSpace::State::State(const unsigned long int number_of_atoms) :
Graph<GraphEdgeContainer>::Node(), positive_atoms(number_of_atoms),
incoming_edge(0)
/* ----------------------------------------------------------------------------
*
* Description: Constructor for class StateSpace::State. Creates a new state
* with a given number of atomic propositions, all of which are
* initially false.
*
* Argument: number_of_atoms -- Number of atomic propositions in the
* state.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
positive_atoms.clear(number_of_atoms);
}
/* ========================================================================= */
inline StateSpace::State::State
(const BitArray& atoms, const unsigned long int number_of_atoms) :
Graph<GraphEdgeContainer>::Node()
/* ----------------------------------------------------------------------------
*
* Description: Constructor for class StateSpace::State. Creates a new state,
* using a given truth assignment for propositional variables
* for initialization.
*
* Argument: atoms -- A truth assignment for atomic
* propositions.
* number_of_atoms -- Number of atomic propositions in the
* truth assignment.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
positive_atoms.copy(atoms, number_of_atoms);
incoming_edge = 0;
}
/* ========================================================================= */
inline StateSpace::State::~State()
/* ----------------------------------------------------------------------------
*
* Description: Destructor for class StateSpace::State.
*
* 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 bool StateSpace::State::holds
(const unsigned long int atom, const unsigned long int number_of_atoms) const
/* ----------------------------------------------------------------------------
*
* Description: Tests whether a given proposition holds in a state.
*
* Arguments: atom -- Identifier of the proposition.
* number_of_atoms -- Number of atomic propositions associated
* with the state.
*
* Returns: Truth value of the proposition in the state.
*
* ------------------------------------------------------------------------- */
{
if (atom >= number_of_atoms)
return false;
return positive_atoms[atom];
}
/* ========================================================================= */
inline const BitArray& StateSpace::State::positiveAtoms() const
/* ----------------------------------------------------------------------------
*
* Description: Returns the truth assignment for the propositions in a state.
*
* Arguments: None.
*
* Returns: A reference to the truth assignment, represented as a
* constant BitArray.
*
* ------------------------------------------------------------------------- */
{
return positive_atoms;
}
/* ========================================================================= */
inline BitArray& StateSpace::State::positiveAtoms()
/* ----------------------------------------------------------------------------
*
* Description: Returns the truth assignment for the propositions in a state.
* This function can be also used to change the truth
* assignment.
*
* Arguments: None.
*
* Returns: A reference to the truth assignment, represented as a
* BitArray.
*
* ------------------------------------------------------------------------- */
{
return positive_atoms;
}
/* ========================================================================= */
inline void StateSpace::State::print
(ostream& stream, const int indent, const GraphOutputFormat fmt) const
/* ----------------------------------------------------------------------------
*
* Description: Writes information about a state of a state space, assuming
* that there are no propositions associated with the state.
* [Note: This function is used to override the `print' function
* defined in the base class `Graph::node'.]
*
* Arguments: stream -- A reference to an output stream.
* indent -- Number of spaces to leave to the left of output.
* fmt -- Determines the format of output.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
this->print(stream, indent, fmt, 0);
}
}
#endif /* !STATESPACE_H */

View file

@ -1,430 +0,0 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* 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 STATESPACEPRODUCT_H
#define STATESPACEPRODUCT_H
#include <config.h>
#include "BitArray.h"
#include "BuchiAutomaton.h"
#include "EdgeContainer.h"
#include "Graph.h"
#include "StateSpace.h"
using namespace std;
namespace Graph
{
/******************************************************************************
*
* A class with operations for checking the product of a Büchi automaton and
* a state space for emptiness.
*
*****************************************************************************/
class StateSpaceProduct
{
public:
StateSpaceProduct /* Constructor. */
(const Graph<GraphEdgeContainer>& a,
const Graph<GraphEdgeContainer>& s);
/* default copy constructor */
~StateSpaceProduct(); /* Destructor. */
/* default assignment operator */
bool empty() const; /* Tells whether the
* product of a Büchi
* automaton and a state
* space is (trivially)
* empty.
*/
unsigned long int numberOfAcceptanceSets() const; /* Tells the number of
* acceptance sets in a
* Büchi automaton in its
* product with a state
* space.
*/
const BuchiAutomaton::BuchiState& firstComponent /* Mappings between a */
(const Graph<GraphEdgeContainer>::size_type /* product state */
state_id) const; /* identifier and */
const StateSpace::State& secondComponent /* states of the Büchi */
(const Graph<GraphEdgeContainer>::size_type /* automaton and the */
state_id) const; /* state space forming
* the product.
*/
void mergeAcceptanceInformation /* Merges the acceptance */
(const Graph<GraphEdgeContainer>::Node& state, /* sets associated with */
const Graph<GraphEdgeContainer>::Node&, /* a state in the Büchi */
BitArray& acceptance_sets) const; /* automaton into a
* collection of sets.
*/
void mergeAcceptanceInformation /* Merges the acceptance */
(const Graph<GraphEdgeContainer>::Edge& /* sets associated with */
buchi_transition, /* a transition in the */
const Graph<GraphEdgeContainer>::Edge&, /* Büchi automaton into */
BitArray& acceptance_sets) const; /* a collection of sets. */
void validateEdgeIterators /* Ensures that a pair */
(const Graph<GraphEdgeContainer>::Node& /* of transition */
buchi_state, /* iterators points to a */
const Graph<GraphEdgeContainer>::Node& /* transition beginning */
system_state, /* from a given state in */
GraphEdgeContainer::const_iterator& /* the product of a */
buchi_transition, /* Büchi automaton and */
GraphEdgeContainer::const_iterator& /* a state space. */
system_transition) const;
void incrementEdgeIterators /* Updates a pair of */
(const Graph<GraphEdgeContainer>::Node& /* transition iterators */
buchi_state, /* to make them point to */
const Graph<GraphEdgeContainer>::Node& /* the "next" transition */
system_state, /* starting from a given */
GraphEdgeContainer::const_iterator& /* state in the product */
buchi_transition, /* of a Büchi automaton */
GraphEdgeContainer::const_iterator& /* and a state space. */
system_transition) const;
private:
const BuchiAutomaton& buchi_automaton; /* Büchi automaton
* associated with the
* product.
*/
const StateSpace& statespace; /* State space associated
* with the product.
*/
};
/******************************************************************************
*
* Inline function definitions for class StateSpaceProduct.
*
*****************************************************************************/
/* ========================================================================= */
inline StateSpaceProduct::StateSpaceProduct
(const Graph<GraphEdgeContainer>& a, const Graph<GraphEdgeContainer>& s) :
buchi_automaton(static_cast<const BuchiAutomaton&>(a)),
statespace(static_cast<const StateSpace&>(s))
/* ----------------------------------------------------------------------------
*
* Description: Constructor for class StateSpaceProduct. Initializes a new
* object with operations for checking the emptiness of the
* product of a Büchi automaton and a state space.
*
* Arguments: a -- A constant reference to a Graph<GraphEdgeContainer>
* object, assumed to be a BuchiAutomaton.
* s -- A constant reference to a Graph<GraphEdgeContainer>
* object, assumed to be a StateSpace.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
inline StateSpaceProduct::~StateSpaceProduct()
/* ----------------------------------------------------------------------------
*
* Description: Destructor for class StateSpaceProduct.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
inline bool StateSpaceProduct::empty() const
/* ----------------------------------------------------------------------------
*
* Description: Tells whether the product of `this->buchi_automaton' and
* `this->statespace' is (trivially) empty.
*
* Arguments: None.
*
* Returns: true iff either the Büchi automaton or the state space has
* no states.
*
* ------------------------------------------------------------------------- */
{
return (buchi_automaton.empty() || statespace.empty());
}
/* ========================================================================= */
inline unsigned long int StateSpaceProduct::numberOfAcceptanceSets() const
/* ----------------------------------------------------------------------------
*
* Description: Tells the number of acceptance sets in the Büchi automaton
* associated with a StateSpaceProduct object.
*
* Arguments: None.
*
* Returns: The number of acceptance sets in the automaton.
*
* ------------------------------------------------------------------------- */
{
return buchi_automaton.numberOfAcceptanceSets();
}
/* ========================================================================= */
inline const BuchiAutomaton::BuchiState& StateSpaceProduct::firstComponent
(const Graph<GraphEdgeContainer>::size_type state_id) const
/* ----------------------------------------------------------------------------
*
* Description: Function for accessing states in the Büchi automaton
* associated with a StateSpaceProduct object.
*
* Argument: state_id -- Identifier of a state in the automaton.
*
* Returns: A constant reference to a state in the automaton.
*
* ------------------------------------------------------------------------- */
{
return buchi_automaton[state_id];
}
/* ========================================================================= */
inline const StateSpace::State& StateSpaceProduct::secondComponent
(const Graph<GraphEdgeContainer>::size_type state_id) const
/* ----------------------------------------------------------------------------
*
* Description: Function for accessing states in the state space associated
* with a StateSpaceProduct object.
*
* Argument: state_id -- Identifier of a state in the state space.
*
* Returns: A constant reference to a state in the state space.
*
* ------------------------------------------------------------------------- */
{
return statespace[state_id];
}
/* ========================================================================= */
inline void StateSpaceProduct::mergeAcceptanceInformation
(const Graph<GraphEdgeContainer>::Node& state,
const Graph<GraphEdgeContainer>::Node&, BitArray& acceptance_sets) const
/* ----------------------------------------------------------------------------
*
* Description: Merges the acceptance sets associated with a state of a Büchi
* automaton into a collection of sets.
*
* Arguments: state -- A constant reference to a state in the
* automaton.
* acceptance_sets -- A reference to a BitArray for storing
* the result. The BitArray should have
* capacity for (at least)
* `this->buchi_automaton
* .numberOfAcceptanceSets()' bits.
* (The second argument is needed to allow the class
* StateSpaceProduct to be used for instantiating the Product
* template; see file Product.h.)
*
* Returns: Nothing. After the operation, `acceptance_sets[i] == true'
* holds if `state.acceptanceSets().test(i) == true' for all
* 0 <= i < `this->buchi_automaton.numberOfAcceptanceSets()'.
*
* ------------------------------------------------------------------------- */
{
acceptance_sets.bitwiseOr
(static_cast<const BuchiAutomaton::BuchiState&>(state).acceptanceSets(),
numberOfAcceptanceSets());
}
/* ========================================================================= */
inline void StateSpaceProduct::mergeAcceptanceInformation
(const Graph<GraphEdgeContainer>::Edge& buchi_transition,
const Graph<GraphEdgeContainer>::Edge&, BitArray& acceptance_sets) const
/* ----------------------------------------------------------------------------
*
* Description: Merges the acceptance sets associated with a transition of a
* Büchi automaton into a collection of sets.
*
* Arguments: transition -- A constant reference to a transition in
* the automaton.
* acceptance_sets -- A reference to a BitArray for storing
* the result. The BitArray should have
* capacity for (at least)
* `this->buchi_automaton
* .numberOfAcceptanceSets()' bits.
* (The second argument is needed to allow the class
* StateSpaceProduct to be used for instantiating the Product
* template; see file Product.h.)
*
* Returns: Nothing. After the operation, `acceptance_sets[i] == true'
* holds if `transition.acceptanceSets().test(i) == true' for
* all
* 0 <= i < `this->buchi_automaton.numberOfAcceptanceSets()'.
*
* ------------------------------------------------------------------------- */
{
acceptance_sets.bitwiseOr
(static_cast<const BuchiAutomaton::BuchiTransition&>(buchi_transition)
.acceptanceSets(),
numberOfAcceptanceSets());
}
/* ========================================================================= */
inline void StateSpaceProduct::validateEdgeIterators
(const Graph<GraphEdgeContainer>::Node& buchi_state,
const Graph<GraphEdgeContainer>::Node& system_state,
GraphEdgeContainer::const_iterator& buchi_transition,
GraphEdgeContainer::const_iterator& system_transition) const
/* ----------------------------------------------------------------------------
*
* Description: Checks whether a pair of transition iterators corresponds to
* a transition beginning from a state in the product of a Büchi
* automaton and a state space; if this is not the case, makes
* the iterators point to a valid transition beginning from the
* product state (or to the "end" of the collection of
* transitions beginning from the product state if no valid
* transition can be found by incrementing the iterators).
*
* Arguments: buchi_state, -- These variables determine the state
* system_state, in the product; `buchi_state' and
* `system_state' should be references to
* states in `this->buchi_automaton' and
* `this->statespace', respectively.
* buchi_transition, -- References to the transition
* system_transition iterators. It is assumed that
* `buchi_transition' and
* `system_transition' initially point to
* two transitions starting from
* `buchi_state' and `system_state',
* respectively.
*
* Returns: Nothing. Upon return, `buchi_transition' and
* `system_transition' will either equal
* `buchi_state.edges().end()' and `system_state.edges().end()',
* respectively, or they will point to a pair of transitions
* beginning from `buchi_state' and `system_state' such that
* this pair of transitions corresponds to a transition starting
* from the product state determined by `buchi_state' and
* `system_state'.
*
* ------------------------------------------------------------------------- */
{
const GraphEdgeContainer& buchi_transitions = buchi_state.edges();
const GraphEdgeContainer& system_transitions = system_state.edges();
if (buchi_transition == buchi_transitions.end())
{
system_transition = system_transitions.end();
return;
}
if (system_transition == system_transitions.end())
{
buchi_transition = buchi_transitions.end();
return;
}
while (!static_cast<const BuchiAutomaton::BuchiTransition*>
(*buchi_transition)->enabled
(static_cast<const StateSpace::State&>(system_state)
.positiveAtoms(),
statespace.numberOfPropositions()))
{
++buchi_transition;
if (buchi_transition == buchi_transitions.end())
{
system_transition = system_transitions.end();
return;
}
}
system_transition = system_transitions.begin();
}
/* ========================================================================= */
inline void StateSpaceProduct::incrementEdgeIterators
(const Graph<GraphEdgeContainer>::Node& buchi_state,
const Graph<GraphEdgeContainer>::Node& system_state,
GraphEdgeContainer::const_iterator& buchi_transition,
GraphEdgeContainer::const_iterator& system_transition) const
/* ----------------------------------------------------------------------------
*
* Description: Increments a pair of transition iterators to point to the
* "next" transition beginning from a state in the product of a
* Büchi automaton and a state space. If no "next" transition
* exists, makes the iterators point to the "end" of the
* collection of transitions beginning from the product state.
*
* Arguments: buchi_state, -- These variables determine the state
* system_state, in the product; `buchi_state' and
* `system_state' should be references to
* states in `this->buchi_automaton' and
* `this->statespace', respectively.
* buchi_transition, -- References to the transition
* system_transition iterators. It is assumed that
* `buchi_transition' and
* `system_transition' initially point to
* two transitions starting from
* `buchi_state' and `system_state',
* respectively.
*
* Returns: Nothing. Upon return, `buchi_transition' and
* `system_transition' will either equal
* `buchi_state.edges().end()' and `system_state.edges().end()',
* respectively, or they will point to a pair of transitions
* beginning from `buchi_state' and `system_state' such that
* this pair of transitions corresponds to a transition starting
* from the product state determined by `buchi_state' and
* `system_state'.
*
* ------------------------------------------------------------------------- */
{
const GraphEdgeContainer& buchi_transitions = buchi_state.edges();
const GraphEdgeContainer& system_transitions = system_state.edges();
++system_transition;
if (system_transition == system_transitions.end())
{
do
{
++buchi_transition;
if (buchi_transition == buchi_transitions.end())
return;
}
while (!static_cast<const BuchiAutomaton::BuchiTransition*>
(*buchi_transition)->enabled
(static_cast<const StateSpace::State&>(system_state)
.positiveAtoms(),
statespace.numberOfPropositions()));
system_transition = system_transitions.begin();
}
}
}
#endif /* !STATESPACEPRODUCT_H */

View file

@ -1,285 +0,0 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* 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.
*/
#include <climits>
#include <config.h>
#include <map>
#include "LbttAlloc.h"
#include "BitArray.h"
#include "Exception.h"
#include "StateSpaceRandomizer.h"
namespace Graph
{
/******************************************************************************
*
* Function definitions for class StateSpaceRandomizer.
*
*****************************************************************************/
/* ========================================================================= */
void StateSpaceRandomizer::reset()
/* ----------------------------------------------------------------------------
*
* Description: (Re)initializes the StateSpaceRandomizer object with default
* state space generation parameters.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
min_size = max_size = 20;
atoms_per_state = 5;
edge_probability = 0.2;
truth_probability = 0.5;
}
/* ========================================================================= */
StateSpace* StateSpaceRandomizer::generateGraph() const
/* ----------------------------------------------------------------------------
*
* Description: Generates a random state space with the current graph
* generation parameters.
*
* Arguments: None.
*
* Returns: A pointer to a newly allocated StateSpace object.
*
* ------------------------------------------------------------------------- */
{
StateSpace::size_type size = chooseSize();
StateSpace* statespace = new StateSpace(atoms_per_state, size);
statespace->initialState() = 0;
if (size > 0)
{
try
{
bool has_successor;
for (StateSpace::size_type i = 0; i < size; i++)
{
if (::user_break)
throw UserBreakException();
has_successor = false;
for (StateSpace::size_type j = 0; j < size; j++)
{
if (DRAND() < edge_probability)
{
statespace->connect(i, j);
has_successor = true;
}
}
if (!has_successor)
statespace->connect(i, LRAND(0, size));
for (unsigned long int j = 0; j < atoms_per_state; j++)
{
if (DRAND() < truth_probability)
(*statespace)[i].positiveAtoms().setBit(j);
}
}
}
catch (...)
{
delete statespace;
throw;
}
}
return statespace;
}
/* ========================================================================= */
StateSpace* StateSpaceRandomizer::generateConnectedGraph() const
/* ----------------------------------------------------------------------------
*
* Description: Initializes a random connected state space whose each state
* is reachable from its initial state 0.
*
* Arguments: None.
*
* Returns: A pointer to a newly allocated StateSpace object.
*
* ------------------------------------------------------------------------- */
{
StateSpace::size_type size = chooseSize();
StateSpace* statespace = new StateSpace(atoms_per_state, size);
statespace->initialState() = 0;
if (size > 0)
{
try
{
/* Random graph generation algorithm:
----------------------------------
allocate number_of_states nodes;
insert node 0 to the set of `reachable but unprocessed' nodes (nodes
that are reachable from the root node but whose children have not yet
been selected)
while the set of `reachable but unprocessed' nodes in nonempty
{
select a (random) node X from the set;
if there exists a node Y that is not yet reachable from root node
{
connect X to Y by making X the parent node of Y;
insert Y to the set of `reachable but unprocessed' nodes;
}
for each node Z (excluding node Y) in the graph
{
randomly connect X to Z (making X the parent of Z);
if Z was not previously reachable from the root node
insert Z to the set of `reachable but unprocessed' nodes;
}
remove X from the set of `reachable but unprocessed' nodes;
}
In the following implementation, the random truth value allocation
for propositions that hold in a state is interleaved with the
previous algorithm.
*/
StateSpace::size_type first_unreachable_state = 1, random_node;
multimap<long int, StateSpace::size_type> reachable_but_unprocessed;
reachable_but_unprocessed.insert(make_pair(0, 0));
while (!reachable_but_unprocessed.empty())
{
if (::user_break)
throw UserBreakException();
random_node = (*(reachable_but_unprocessed.begin())).second;
reachable_but_unprocessed.erase(reachable_but_unprocessed.begin());
for (StateSpace::size_type n = 0; n < first_unreachable_state; ++n)
{
if (DRAND() < edge_probability)
statespace->connect(random_node, n);
}
if (first_unreachable_state < size)
{
statespace->connect(random_node, first_unreachable_state);
reachable_but_unprocessed.insert(make_pair(LRAND(0, LONG_MAX),
first_unreachable_state));
++first_unreachable_state;
for (StateSpace::size_type i = first_unreachable_state; i < size;
++i)
{
if (DRAND() < edge_probability)
{
statespace->connect(random_node, first_unreachable_state);
reachable_but_unprocessed.insert
(make_pair(LRAND(0, LONG_MAX), first_unreachable_state));
++first_unreachable_state;
}
}
}
if ((*statespace)[random_node].edges().empty())
statespace->connect(random_node, random_node);
BitArray& atoms = (*statespace)[random_node].positiveAtoms();
for (unsigned long int i = 0; i < atoms_per_state; ++i)
{
if (DRAND() < truth_probability)
atoms.setBit(i);
}
}
}
catch (...)
{
delete statespace;
throw;
}
}
return statespace;
}
/* ========================================================================= */
StateSpace* StateSpaceRandomizer::generatePath() const
/* ----------------------------------------------------------------------------
*
* Description: Generates a random Kripke structure that consists of a finite
* prefix of states that ends in a loop. The initial state of
* the generated structure will be at index 0.
*
* Arguments: None.
*
* Returns: A pointer to a newly allocated StateSpace object.
*
* ------------------------------------------------------------------------- */
{
StateSpace::size_type size = chooseSize();
StateSpace* statespace = new StateSpace(atoms_per_state, size);
statespace->initialState() = 0;
if (size > 0)
{
try
{
for (StateSpace::size_type i = 0; i + 1 < size; i++)
{
if (::user_break)
throw UserBreakException();
statespace->connect(i, i + 1);
for (unsigned long int j = 0; j < atoms_per_state; j++)
{
if (DRAND() < truth_probability)
(*statespace)[i].positiveAtoms().setBit(j);
}
}
statespace->connect(size - 1, LRAND(0, size));
}
catch (...)
{
delete statespace;
throw;
}
}
return statespace;
}
}

View file

@ -1,154 +0,0 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* 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 STATESPACERANDOMIZER_H
#define STATESPACERANDOMIZER_H
#include <config.h>
#include "Random.h"
#include "StateSpace.h"
namespace Graph
{
/******************************************************************************
*
* A class for generating random state spaces.
*
*****************************************************************************/
class StateSpaceRandomizer
{
public:
StateSpaceRandomizer(); /* Constructor. */
~StateSpaceRandomizer(); /* Destructor. */
StateSpace* generateGraph() const; /* Generates a random
* state space.
*/
StateSpace* generateConnectedGraph() const; /* Generates a random
* state space whose all
* states are reachable
* from its initial state.
*/
StateSpace* generatePath() const; /* Generates a random path.
*/
void reset(); /* (Re)initializes the
* object with default
* state space generation
* parameters.
*/
StateSpace::size_type min_size; /* Minimum size for the
* generated state spaces.
*/
StateSpace::size_type max_size; /* Maximum size for the
* generated state spaces.
*/
unsigned long int atoms_per_state; /* Number of atomic
* propositions associated
* with each state of the
* generated state spaces.
*/
double edge_probability; /* Probability for adding
* random edges between
* state space states.
*/
double truth_probability; /* Probability of assigning
* the value `true' for a
* proposition in a state.
*/
private:
StateSpace::size_type chooseSize() const; /* Chooses a size for a
* state space to be
* generated.
*/
StateSpaceRandomizer /* Prevent copying and */
(const StateSpaceRandomizer&); /* assignment of */
StateSpaceRandomizer& operator= /* StateSpaceRandomizer */
(const StateSpaceRandomizer&); /* objects. */
};
/******************************************************************************
*
* Inline function definitions for class StateSpaceRandomizer.
*
*****************************************************************************/
/* ========================================================================= */
inline StateSpaceRandomizer::StateSpaceRandomizer()
/* ----------------------------------------------------------------------------
*
* Description: Constructor for class StateSpaceRandomizer. Initializes a new
* StateSpaceRandomizer object with default parameters.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
reset();
}
/* ========================================================================= */
inline StateSpaceRandomizer::~StateSpaceRandomizer()
/* ----------------------------------------------------------------------------
*
* Description: Destructor for class StateSpaceRandomizer.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
inline StateSpace::size_type StateSpaceRandomizer::chooseSize() const
/* ----------------------------------------------------------------------------
*
* Description: Chooses a random size for a state space to be generated.
*
* Arguments: None.
*
* Returns: A random integer in the interval
* [this->min_size, this->max_size].
*
* ------------------------------------------------------------------------- */
{
return (min_size + LRAND(0, max_size - min_size + 1));
}
}
#endif /* STATESPACERANDOMIZER_H */

View file

@ -1,586 +0,0 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* 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.
*/
#include <config.h>
#include <cctype>
#include <climits>
#include <cstdlib>
#include "StringUtil.h"
namespace StringUtil
{
/* ========================================================================= */
string toString(const double d, const int precision, const ios::fmtflags flags)
/* ----------------------------------------------------------------------------
*
* Description: Converts a double to a string with a given precision and
* format. The function defaults to fixed-point format with a
* precision of two decimals.
*
* Arguments: d -- The double to be converted.
* precision -- Precision.
* flags -- Formatting flags.
*
* Returns: The double as a string.
*
* ------------------------------------------------------------------------- */
{
#ifdef HAVE_SSTREAM
ostringstream stream;
stream.precision(precision);
stream.flags(flags);
stream << d;
return stream.str();
#else
ostrstream stream;
stream.precision(precision);
stream.flags(flags);
stream << d << ends;
string result(stream.str());
stream.freeze(0);
return result;
#endif /* HAVE_SSTREAM */
}
/* ========================================================================= */
void sliceString
(const string& s, const char* slice_chars, vector<string>& slices)
/* ----------------------------------------------------------------------------
*
* Description: Slices a string into a vector of strings, using a given set
* of characters as separators.
*
* Arguments: s -- A reference to the constant original string.
* slice_chars -- A C-style string containing the characters
* to be used as separators.
* slices -- A reference to a vector for storing the
* string components.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
string::size_type last_non_slicechar_pos = 0;
string::size_type last_slicechar_pos = 0;
slices.clear();
do
{
last_non_slicechar_pos =
s.find_first_not_of(slice_chars, last_slicechar_pos);
if (last_non_slicechar_pos != s.npos)
{
last_slicechar_pos = s.find_first_of(slice_chars,
last_non_slicechar_pos);
if (last_slicechar_pos == s.npos)
slices.push_back(s.substr(last_non_slicechar_pos));
else
slices.push_back(s.substr(last_non_slicechar_pos,
last_slicechar_pos
- last_non_slicechar_pos));
}
}
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)
/* ----------------------------------------------------------------------------
*
* Description: Converts a string to an unsigned long integer.
*
* Argument: number_string -- A reference to a constant string.
*
* Returns: The number contained in the string, unless the string could
* not be converted to a number, in which case an exception is
* thrown.
*
* ------------------------------------------------------------------------- */
{
char* endptr;
unsigned long int number = strtoul(number_string.c_str(), &endptr, 10);
if (*endptr != '\0' || number_string.empty()
|| number_string.find_first_of("-") != string::npos)
throw NotANumberException("expected a nonnegative integer, got `"
+ number_string + "'");
return number;
}
/* ========================================================================= */
int parseInterval
(const string& token, unsigned long int& min, unsigned long int& max)
/* ----------------------------------------------------------------------------
*
* Description: Reads the lower and upper bound from an "interval string"
* into two unsigned long integer variables.
*
* Arguments: token -- A reference to a constant "interval string" of
* the format
* <interval string>
* ::= "*" // 0
* | <ulong> // 1
* | <sep><ulong> // 2
* | <ulong><sep> // 3
* | <ulong><sep><ulong> // 4
* where <ulong> is an unsigned long integer (not
* containing a minus sign), and <sep> is either
* "-" or "...". The meaning of the various cases
* is as follows:
* 0 All integers between 0 and ULONG_MAX.
* 1 A point interval consisting of a single
* value.
* 2 An interval from 0 to a given upper
* bound.
* 3 An interval from a given lower bound to
* ULONG_MAX.
* 4 A bounded interval.
* min, max -- References to two unsigned long integers for
* storing the lower and upper bound of the
* interval.
*
* Returns: A value telling the type of the specified interval, which is
* a bitwise or of the values LEFT_BOUNDED and RIGHT_BOUNDED
* depending on which bounds were given explicitly for the
* interval. (The lower and upper bounds of the interval itself
* are stored in the variables `min' and `max', respectively.)
* The function will throw a NotANumberException if the
* interval string is of an invalid format.
*
* ------------------------------------------------------------------------- */
{
unsigned long int tmp_min = 0;
unsigned long int tmp_max = ULONG_MAX;
int interval_type = UNBOUNDED;
if (token != "*")
{
string::size_type pos(token.find_first_of("-"));
if (pos == string::npos)
pos = token.find("...");
string value(token.substr(0, pos));
if (!value.empty())
{
tmp_min = parseNumber(value);
if (pos == string::npos)
tmp_max = tmp_min;
interval_type |= LEFT_BOUNDED;
}
if (pos != string::npos)
value = token.substr(pos + (token[pos] == '-' ? 1 : 3));
if (!value.empty())
{
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)
{
extra_tokens->push_back(*i);
continue;
}
else
throw;
}
if (interval_type & LEFT_BOUNDED)
{
if (i_start < min || i_start > max)
throw IntervalRangeException(i_start);
}
else if (i_start < min)
i_start = min;
if (interval_type & RIGHT_BOUNDED)
{
if (i_end < min || i_end > max)
throw IntervalRangeException(i_end);
}
else if (i_end > max)
i_end = max;
intervals.merge(i_start, i_end);
}
}
/* ========================================================================= */
void parseTime
(const string& time_string, unsigned long int& hours,
unsigned long int& minutes, unsigned long int& seconds)
/* ----------------------------------------------------------------------------
*
* Description: Parses a "time string", i.e., a string of the form
* ([0-9]+"h")([0-9]+"min")?([0-9]+"s")?
* | ([0-9]+"min")([0-9]+"s")?
* | ([0-9]+"s")
* (where 'h', 'min' and 's' correspond to hours, minutes and
* seconds, respectively) and stores the numbers into three
* unsigned long integers. The case of the unit symbols is not
* relevant.
*
* Arguments: time_string -- String to process.
* hours -- A reference to an unsigned long integer for
* storing the number of hours.
* minutes -- A reference to an unsigned long integer for
* storing the number of minutes.
* seconds -- A reference to an unsigned long integer for
* storing the number of seconds.
*
* Time components left unspecified in `time_string' will get
* the value 0.
*
* Returns: Nothing. Throws an Exception if the given string is not of
* the correct format.
*
* ------------------------------------------------------------------------- */
{
bool hours_present = false, minutes_present = false, seconds_present = false;
hours = minutes = seconds = 0;
if (time_string.empty())
throw Exception("invalid time format");
string::size_type pos1 = 0;
string s;
while (pos1 < time_string.length())
{
string::size_type pos2 = time_string.find_first_not_of("0123456789", pos1);
if (pos2 >= time_string.length())
throw Exception("invalid time format");
unsigned long int val;
try
{
val = parseNumber(time_string.substr(pos1, pos2 - pos1));
}
catch (const NotANumberException&)
{
throw Exception("invalid time format");
}
switch (tolower(time_string[pos2]))
{
case 'h' :
if (hours_present || minutes_present || seconds_present)
throw Exception("invalid time format");
hours_present = true;
hours = val;
break;
case 'm' :
if (minutes_present
|| seconds_present
|| pos2 + 2 >= time_string.length()
|| tolower(time_string[pos2 + 1]) != 'i'
|| tolower(time_string[pos2 + 2]) != 'n')
throw Exception("invalid time format");
minutes_present = true;
minutes = val;
pos2 += 2;
break;
case 's' :
if (seconds_present)
throw Exception("invalid time format");
seconds_present = true;
seconds = val;
break;
default : /* 's' */
throw Exception("invalid time format");
break;
}
pos1 = pos2 + 1;
}
}
}

View file

@ -1,352 +0,0 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* 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 STRINGUTIL_H
#define STRINGUTIL_H
#include <config.h>
#include <set>
#include <string>
#ifdef HAVE_SSTREAM
#include <sstream>
#else
#include <strstream>
#endif /* HAVE_SSTREAM */
#include <vector>
#include "LbttAlloc.h"
#include "Exception.h"
#include "IntervalList.h"
using namespace std;
/******************************************************************************
*
* Miscellaneous routines extracting data from strings or converting data types
* to strings.
*
*****************************************************************************/
namespace StringUtil
{
string toString /* Function for */
(const double d, /* converting a double */
const int precision = 2, /* to a string. */
const ios::fmtflags flags = ios::fixed);
template<typename T> string toString(const T& t); /* Template function for
* converting data types
* supporting stream output
* operations into strings.
*/
void sliceString /* Breaks a string into */
(const string& s, const char* slice_chars, /* `slices', using a */
vector<string>& slices); /* given set of
* characters as
* separators.
*/
string toLowerCase(const string& s); /* Converts a string to
* lower case.
*/
string unquoteString(const string& s); /* Removes unescaped quotes
* from a string and
* interprets escaped
* characters.
*/
enum QuoteMode {GLOBAL, INSIDE_QUOTES, /* Enumeration type used */
OUTSIDE_QUOTES}; /* for controlling the
* behavior of the
* substitute function.
*/
string::size_type findInQuotedString /* Finds a character in */
(const string& s, const string& chars, /* a string (respecting */
QuoteMode type = GLOBAL); /* quotes). */
string substituteInQuotedString /* Replaces characters */
(const string& s, const string& chars, /* in a string with */
const string& substitutions, /* other characters. */
QuoteMode type = GLOBAL);
unsigned long int parseNumber /* Converts a string to */
(const string& number_string); /* an unsigned long
* integer.
*/
enum IntervalStringType {UNBOUNDED = 0, /* Type for an interval */
LEFT_BOUNDED = 1, /* string (see the */
RIGHT_BOUNDED = 2}; /* documentation of
* the parseInterval
* function in
* StringUtil.cc).
*/
int parseInterval /* Reads the lower and */
(const string& token, /* upper bounds from a */
unsigned long int& min, /* "number interval */
unsigned long int& max); /* string" into two
* unsigned long integer
* variables.
*/
void parseIntervalList /* Converts a list of */
(const string& token, /* number intervals to */
IntervalList& intervals, /* the set of unsigned */
unsigned long int min, /* long integers */
unsigned long int max, /* corresponding to the */
vector<string>* extra_tokens = 0); /* union of the
* intervals.
*/
void parseTime /* Parses a time string. */
(const string& time_string,
unsigned long int& hours,
unsigned long int& minutes,
unsigned long int& seconds);
/******************************************************************************
*
* Template function definitions in namespace StringUtil.
*
*****************************************************************************/
/* ========================================================================= */
template<typename T>
string toString(const T& t)
/* ----------------------------------------------------------------------------
*
* Description: Converts any data type supporting stream output (the <<
* operator) into a string.
*
* Arguments: t -- The object to be converted into a string.
*
* Returns: The object as a string.
*
* ------------------------------------------------------------------------- */
{
#ifdef HAVE_SSTREAM
ostringstream stream;
stream << t;
return stream.str();
#else
ostrstream stream;
stream << t << ends;
string result(stream.str());
stream.freeze(0);
return result;
#endif /* HAVE_SSTREAM */
}
/******************************************************************************
*
* A class for reporting number conversion errors.
*
*****************************************************************************/
class NotANumberException : public Exception
{
public:
NotANumberException /* Constructor. */
(const string& message = "not a number");
/* default copy constructor */
~NotANumberException() throw(); /* Destructor. */
NotANumberException& operator= /* Assignment operator. */
(const NotANumberException& e);
};
/******************************************************************************
*
* 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 NotANumberException::NotANumberException
(const string& message) :
Exception(message)
/* ----------------------------------------------------------------------------
*
* Description: Constructor for class NotANumberException. Creates an
* exception object and initializes it with an error message.
*
* Arguments: message -- A reference to a constant string containing the
* error message.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
inline NotANumberException::~NotANumberException() throw()
/* ----------------------------------------------------------------------------
*
* Description: Destructor for class NotANumberException.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
inline NotANumberException& NotANumberException::operator=
(const NotANumberException& e)
/* ----------------------------------------------------------------------------
*
* Description: Assignment operator for class NotANumberException. Copies
* the contents of an exception object to another.
*
* Arguments: e -- A reference to a constant NotANumberException.
*
* Returns: A reference to the object assigned to.
*
* ------------------------------------------------------------------------- */
{
Exception::operator=(e);
return *this;
}
/******************************************************************************
*
* Inline function definitions for class IntervalRangeException.
*
*****************************************************************************/
/* ========================================================================= */
inline IntervalRangeException::IntervalRangeException
(const unsigned long int number, const string& message) :
Exception(message), invalid_number(number)
/* ----------------------------------------------------------------------------
*
* Description: Constructor for class IntervalRangeException. Creates an
* exception object.
*
* Arguments: number -- A constant unsigned long integer specifying a
* number that does not fit in an interval.
* message -- A reference to a constant string containing an
* error message.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
inline IntervalRangeException::~IntervalRangeException() throw()
/* ----------------------------------------------------------------------------
*
* Description: Destructor for class IntervalRangeException.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
inline unsigned long int IntervalRangeException::getNumber() const
/* ----------------------------------------------------------------------------
*
* Description: Returns the number associated with the IntervalRangeException
* object.
*
* Arguments: None.
*
* Returns: The number associated with the object.
*
* ------------------------------------------------------------------------- */
{
return invalid_number;
}
/* ========================================================================= */
inline IntervalRangeException& IntervalRangeException::operator=
(const IntervalRangeException& e)
/* ----------------------------------------------------------------------------
*
* Description: Assignment operator for class IntervalRangeException.
* Copies the contents of an exception object to another.
*
* Arguments: e -- A reference to a constant IntervalRangeException.
*
* Returns: A reference to the object assigned to.
*
* ------------------------------------------------------------------------- */
{
Exception::operator=(e);
return *this;
}
}
#endif /* !STRINGUTIL_H */

View file

@ -1,125 +0,0 @@
/*
* Copyright (C) 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* 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.
*/
#include <config.h>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <sys/stat.h>
#include <sys/types.h>
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif /* HAVE_FCNTL_H */
#include <string>
#include "Exception.h"
#include "StringUtil.h"
#include "TempFsysName.h"
/******************************************************************************
*
* Number of generated temporary names.
*
*****************************************************************************/
unsigned long int TempFsysName::number_of_allocated_names = 0;
/******************************************************************************
*
* Function definitions for class TempFsysName.
*
*****************************************************************************/
/* ========================================================================= */
const char* TempFsysName::allocate
(const char* prefix, const NameType t, const bool literal)
/* ----------------------------------------------------------------------------
*
* Description: Associates a TempFsysName object with a temporary name. (As
* a side effect, the function actually creates an empty
* temporary file or a directory to reserve the name in the file
* system. The file or directory should never be removed
* explicitly; it is removed automatically when the TempFsysName
* object is destroyed or another call is made to
* `this->allocate'.)
*
* Arguments: prefix -- Pointer to a C-style string containing a prefix
* for the temporary name (empty by default). If
* `literal == true', `prefix' (if nonempty) is
* assumed to contain the full path for the
* temporary file or directory; otherwise the
* function will reserve a temporary name in the
* `P_tmpdir' directory. This name will consist
* of the value of `prefix' (if nonempty), followed
* by the current value of
* `TempFsysName::number_of_allocated_names' and
* the current process id, separated by dots.
* t -- Determines the type of the name (file or a
* directory).
* literal -- See above.
*
* Returns: A pointer to a constant C-style string containing the
* temporary name. The function throws an IOException if the
* name allocation or the file or directory creation fails.
*
* ------------------------------------------------------------------------- */
{
releaseName();
using ::StringUtil::toString;
string tempname;
try
{
if (!literal || strlen(prefix) == 0)
{
tempname = toString(P_tmpdir) + "/";
if (strlen(prefix))
tempname += string(prefix) + ".";
tempname += toString(number_of_allocated_names) + "."
+ toString(getpid());
++number_of_allocated_names;
}
else
tempname = prefix;
name = new char[tempname.length() + 1];
strcpy(name, tempname.c_str());
}
catch (const bad_alloc&)
{
name = 0;
throw IOException
("unable to allocate a temporary name in the file system");
}
type = t;
if (t == FILE)
{
int fd = open(name, O_RDWR | O_CREAT | O_EXCL, S_IREAD | S_IWRITE);
if (fd == -1)
throw IOException("unable to create a temporary file");
close(fd);
}
else if (mkdir(name, S_IRWXU) == -1)
throw IOException("unable to create a temporary directory");
return name;
}

View file

@ -1,157 +0,0 @@
/*
* Copyright (C) 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* 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 TEMPFSYSNAME_H
#define TEMPFSYSNAME_H
#include <config.h>
#include <cstdio>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif /* HAVE_UNISTD_H */
/******************************************************************************
*
* A class for temporary file system names.
*
*****************************************************************************/
class TempFsysName
{
public:
TempFsysName(); /* Constructor. */
~TempFsysName(); /* Destructor. */
enum NameType { FILE, DIRECTORY }; /* Types of temporary
* file system names.
*/
const char* allocate /* Allocates a name */
(const char* prefix = "", /* in the file system. */
const NameType t = FILE,
const bool literal = false);
const char* get() const; /* Tells the name. */
private:
TempFsysName(const TempFsysName&); /* Prevent copying and */
TempFsysName& operator=(const TempFsysName&); /* assignment of
* TempFsysName objects.
*/
void releaseName(); /* Frees a name in the file
* system.
*/
char* name; /* Temporary name. */
NameType type; /* Tells whether the name
* refers to a file or a
* directory.
*/
static unsigned long int /* Counter for the */
number_of_allocated_names; /* number of generated
* temporary names.
*/
};
/******************************************************************************
*
* Inline function definitions for class TempFsysName.
*
*****************************************************************************/
/* ========================================================================= */
inline TempFsysName::TempFsysName() : name(static_cast<char*>(0))
/* ----------------------------------------------------------------------------
*
* Description: Constructor for class TempFsysName.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
inline TempFsysName::~TempFsysName()
/* ----------------------------------------------------------------------------
*
* Description: Destructor for class TempFsysName.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
releaseName();
}
/* ========================================================================= */
inline const char* TempFsysName::get() const
/* ----------------------------------------------------------------------------
*
* Description: Tells the name associated with the TempFsysName object.
*
* Arguments: None.
*
* Returns: A pointer to a constant C-style string containing the name
* associated with the TempFsysName object. If the TempFsysName
* object has not yet been (successfully) associated with a file
* using TempFsysName::allocate, this pointer has the value 0.
*
* ------------------------------------------------------------------------- */
{
return name;
}
/* ========================================================================= */
inline void TempFsysName::releaseName()
/* ----------------------------------------------------------------------------
*
* Description: Deallocates the memory reserved for `this->name' and frees
* the name also in the file system by removing the file or
* directory associated with the object. If the name
* is associated with a directory, the directory is assumed to
* be empty.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
if (name == static_cast<char*>(0))
return;
if (type == FILE)
remove(name);
else
rmdir(name);
delete[] name;
name = 0;
}
#endif /* !TEMPFSYSNAME_H */

File diff suppressed because it is too large Load diff

View file

@ -1,534 +0,0 @@
/* -*- coding: utf-8 -*-
*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* 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 TESTOPERATIONS_H
#define TESTOPERATIONS_H
#include <config.h>
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
#include "LbttAlloc.h"
#include "Configuration.h"
#include "Exception.h"
#include "StateSpace.h"
#include "TestStatistics.h"
using namespace std;
extern Configuration configuration;
/******************************************************************************
*
* Functions for various test operations.
*
*****************************************************************************/
namespace TestOperations
{
void openFile
(const char* filename, ifstream& stream, /* Opens a file for */
ios::openmode mode, int indent = 0); /* reading. */
void openFile /* Opens a file for */
(const char* filename, ofstream& stream, /* writing. */
ios::openmode mode, int indent = 0);
void openFile /* Opens a file for */
(const char* filename, int& fd, int flags, /* input/output using */
int indent = 0); /* file descriptors. */
void truncateFile /* Truncates a file. */
(const char* filename, int indent = 0);
void printFileContents /* Displays the contents */
(ostream& stream, const char* message, /* of a file. */
const char* filename, int indent,
const char* line_prefix = "");
void writeToTranscript /* Writes a message */
(const string& message, /* into the transcript */
bool show_formula_in_header = true); /* file. */
void generateStateSpace(); /* Generates a state space.
*/
void generateFormulae /* Generates a random */
(istream* formula_input_stream = 0); /* LTL formula and
* stores the formula,
* its negation and the
* NNFs of the two
* formulae into a
* given array.
*/
void verifyFormulaOnPath(); /* Evaluates the LTL
* formula (accessed
* through `round_info')
* on a path directly
* (if using paths as
* state spaces).
*/
void writeFormulaeToFiles(); /* Writes LTL formulas */
/* into a file. */
void generateBuchiAutomaton /* Generates a Büchi */
(int f, /* automaton from a LTL */
vector<Configuration::AlgorithmInformation> /* formula stored in a */
::size_type /* given file, using a */
algorithm_id); /* given LTL-to-Büchi
* translation algorithm
* for the conversion.
*/
void performEmptinessCheck /* Performs an emptiness */
(int f, /* check on a product */
vector<Configuration::AlgorithmInformation> /* automaton. */
::size_type
algorithm_id);
void performConsistencyCheck /* Performs a */
(vector<Configuration::AlgorithmInformation> /* consistency check on */
::size_type /* the test results */
algorithm_id); /* for a formula and its
* negation.
*/
void compareResults(); /* Compares the model
* checking results
* obtained using some
* LTL-to-Büchi conversion
* algorithm with the
* results given by the
* other algorithms.
*/
void performBuchiIntersectionCheck(); /* Performs pairwise
* emptiness checks on the
* Büchi automata
* constructed by the
* different algorithms
* from a formula and its
* negation.
*/
/******************************************************************************
*
* A class for reporting state space generation errors.
*
*****************************************************************************/
class StateSpaceGenerationException : public Exception
{
public:
StateSpaceGenerationException(); /* Constructor. */
/* default copy constructor */
~StateSpaceGenerationException() throw(); /* Destructor. */
StateSpaceGenerationException& operator= /* Assignment operator. */
(const StateSpaceGenerationException& e);
};
/******************************************************************************
*
* A class for reporting LTL formula generation errors.
*
*****************************************************************************/
class FormulaGenerationException : public Exception
{
public:
FormulaGenerationException(); /* Constructor. */
/* default copy constructor */
~FormulaGenerationException() throw(); /* Destructor. */
FormulaGenerationException& operator= /* Assignment operator. */
(const FormulaGenerationException& e);
};
/******************************************************************************
*
* A class for reporting Büchi automaton generation errors.
*
*****************************************************************************/
class BuchiAutomatonGenerationException : public Exception
{
public:
BuchiAutomatonGenerationException(); /* Constructor. */
/* default copy constructor */
~BuchiAutomatonGenerationException() throw(); /* Destructor. */
BuchiAutomatonGenerationException& operator= /* Assignment operator. */
(const BuchiAutomatonGenerationException& e);
};
/******************************************************************************
*
* A class for reporting product automaton generation errors.
*
*****************************************************************************/
class ProductAutomatonGenerationException : public Exception
{
public:
ProductAutomatonGenerationException(); /* Constructor. */
/* default copy constructor */
~ProductAutomatonGenerationException() throw(); /* Destructor. */
ProductAutomatonGenerationException& operator= /* Assignment operator. */
(const ProductAutomatonGenerationException& e);
};
/******************************************************************************
*
* A class for reporting errors during the emptiness check.
*
*****************************************************************************/
class EmptinessCheckFailedException : public Exception
{
public:
EmptinessCheckFailedException(); /* Constructor. */
/* default copy constructor */
~EmptinessCheckFailedException() throw(); /* Destructor. */
EmptinessCheckFailedException& operator= /* Assignment operator. */
(const EmptinessCheckFailedException& e);
};
/******************************************************************************
*
* Inline function definitions for class StateSpaceGenerationException.
*
*****************************************************************************/
/* ========================================================================= */
inline StateSpaceGenerationException::StateSpaceGenerationException() :
Exception("state space generation failed")
/* ----------------------------------------------------------------------------
*
* Description: Constructor for class StateSpaceGenerationException.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
inline StateSpaceGenerationException::~StateSpaceGenerationException() throw()
/* ----------------------------------------------------------------------------
*
* Description: Destructor for class StateSpaceGenerationException.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
inline StateSpaceGenerationException&
StateSpaceGenerationException::operator=
(const StateSpaceGenerationException& e)
/* ----------------------------------------------------------------------------
*
* Description: Assignment operator for class StateSpaceGenerationException.
* Assigns the value of another StateSpaceGenerationException to
* `this' one.
*
* Arguments: e -- A reference to a constant StateSpaceException.
*
* Returns: A reference to the object whose values was changed.
*
* ------------------------------------------------------------------------- */
{
Exception::operator=(e);
return *this;
}
/******************************************************************************
*
* Inline function definitions for class FormulaGenerationException.
*
*****************************************************************************/
/* ========================================================================= */
inline FormulaGenerationException::FormulaGenerationException() :
Exception("LTL formula generation failed")
/* ----------------------------------------------------------------------------
*
* Description: Constructor for class FormulaGenerationException.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
inline FormulaGenerationException::~FormulaGenerationException() throw()
/* ----------------------------------------------------------------------------
*
* Description: Destructor for class FormulaGenerationException.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
inline FormulaGenerationException&
FormulaGenerationException::operator=(const FormulaGenerationException& e)
/* ----------------------------------------------------------------------------
*
* Description: Assignment operator for class FormulaGenerationException.
* Assigns the value of another FormulaGenerationException to
* `this' one.
*
* Arguments: e -- A reference to a constant FormulaException.
*
* Returns: A reference to the object whose values was changed.
*
* ------------------------------------------------------------------------- */
{
Exception::operator=(e);
return *this;
}
/******************************************************************************
*
* Inline function definitions for class BuchiAutomatonGenerationException.
*
*****************************************************************************/
/* ========================================================================= */
inline BuchiAutomatonGenerationException::BuchiAutomatonGenerationException() :
Exception("Büchi automaton generation failed")
/* ----------------------------------------------------------------------------
*
* Description: Constructor for class BuchiAutomatonGenerationException.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
inline BuchiAutomatonGenerationException::~BuchiAutomatonGenerationException()
throw()
/* ----------------------------------------------------------------------------
*
* Description: Destructor for class BuchiAutomatonGenerationException.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
inline BuchiAutomatonGenerationException&
BuchiAutomatonGenerationException::operator=
(const BuchiAutomatonGenerationException& e)
/* ----------------------------------------------------------------------------
*
* Description: Assignment operator for class
* BuchiAutomatonGenerationException. Assigns the value of
* another BuchiAutomatonGenerationException to `this' one.
*
* Arguments: e -- A reference to a constant
* BuchiAutomatonGenerationException.
*
* Returns: A reference to the object whose value was changed.
*
* ------------------------------------------------------------------------- */
{
Exception::operator=(e);
return *this;
}
/******************************************************************************
*
* Inline function definitions for class ProductAutomatonGenerationException.
*
*****************************************************************************/
/* ========================================================================= */
inline
ProductAutomatonGenerationException::ProductAutomatonGenerationException() :
Exception("product automaton generation failed")
/* ----------------------------------------------------------------------------
*
* Description: Constructor for class ProductAutomatonGenerationException.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
inline
ProductAutomatonGenerationException::~ProductAutomatonGenerationException()
throw()
/* ----------------------------------------------------------------------------
*
* Description: Destructor for class ProductAutomatonGenerationException.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
inline ProductAutomatonGenerationException&
ProductAutomatonGenerationException::operator=
(const ProductAutomatonGenerationException& e)
/* ----------------------------------------------------------------------------
*
* Description: Assignment operator for class
* ProductAutomatonGenerationException.
*
* Arguments: e -- A reference to a constant
* ProductAutomatonGenerationException.
*
* Returns: A reference to the object whose value was changed.
*
* ------------------------------------------------------------------------- */
{
Exception::operator=(e);
return *this;
}
/******************************************************************************
*
* Inline function definitions for class EmptinessCheckFailedException.
*
*****************************************************************************/
/* ========================================================================= */
inline
EmptinessCheckFailedException::EmptinessCheckFailedException() :
Exception("emptiness check failed")
/* ----------------------------------------------------------------------------
*
* Description: Constructor for class EmptinessCheckFailedException.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
inline EmptinessCheckFailedException::~EmptinessCheckFailedException() throw()
/* ----------------------------------------------------------------------------
*
* Description: Destructor for class EmptinessCheckFailedException.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
inline EmptinessCheckFailedException& EmptinessCheckFailedException::operator=
(const EmptinessCheckFailedException& e)
/* ----------------------------------------------------------------------------
*
* Description: Assignment operator for class EmptinessCheckFailedException.
* Assigns the value of another EmptinessCheckFailedException to
* `this' one.
*
* Arguments: e -- A reference to a constant
* EmptinessCheckFailedException.
*
* Returns: A reference to the object whose value was changed.
*
* ------------------------------------------------------------------------- */
{
Exception::operator=(e);
return *this;
}
}
#endif /* !TESTOPERATIONS_H */

View file

@ -1,251 +0,0 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* 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 TESTROUNDINFO_H
#define TESTROUNDINFO_H
#include <config.h>
#include <cstdio>
#include <fstream>
#include <iostream>
#include <vector>
#include "LbttAlloc.h"
#include "Exception.h"
#include "LtlFormula.h"
#include "PathIterator.h"
#include "StateSpace.h"
#include "TempFsysName.h"
using namespace std;
namespace SharedTestData
{
/******************************************************************************
*
* A data structure for storing test round control information and some test-
* related data.
*
*****************************************************************************/
class TestRoundInfo
{
public:
TestRoundInfo(); /* Constructor. */
~TestRoundInfo(); /* Destructor. */
Exceptional_ostream cout; /* Exception-guarded output
* stream for messages.
*/
istream* formula_input_stream; /* Stream for reading input
* formulae.
*/
ifstream formula_input_file; /* File for reading input
* formulae.
*/
ofstream transcript_file; /* Output stream for
* logging operations.
*/
unsigned long int number_of_translators; /* Number of translators.
*/
unsigned long int current_round; /* Number of current round.
*/
unsigned long int next_round_to_run; /* Indicates the next
* round to run.
*/
unsigned long int next_round_to_stop; /* Indicates the next
* test round after which
* to pause and wait for
* user commands.
*/
unsigned long int error_report_round; /* Number of the last round
* in which something was
* written to the error
* transcript file.
*/
bool error; /* True if an error
* occurred during the
* current round.
*/
bool all_tests_successful; /* True if no errors have
* occurred during testing.
*/
bool skip; /* True if the current
* round is to be skipped.
*/
bool abort; /* True if the testing is
* to be aborted.
*/
unsigned long int num_generated_statespaces; /* State space */
unsigned long int total_statespace_states; /* statistics. */
unsigned long int total_statespace_transitions;
unsigned long int num_processed_formulae; /* Number of processed LTL
* formulae.
*/
bool fresh_statespace; /* True if a new state
* space was generated in
* the current test round.
*/
const Graph::StateSpace* statespace; /* Pointer to the state
* space used in the
* current test round.
*/
Graph::PathIterator* path_iterator; /* Pointer to a "path
* iterator" needed
* when using enumerated
* paths as state spaces.
*/
unsigned long int real_emptiness_check_size; /* Number of states in the
* state space where the
* emptiness check should
* be performed.
*/
unsigned long int /* Number of the round */
next_round_to_change_statespace; /* in which to generate
* a new state space.
*/
unsigned long int /* Number of the round */
next_round_to_change_formula; /* in which to generate
* (or read) a new LTL
* formula.
*/
bool fresh_formula; /* True is a new formula
* was generated (or read
* from a file) in the
* current round.
*/
vector<class ::Ltl::LtlFormula*> formulae; /* Formulae used in the
* current round:
* formulae[0]:
* positive formula in
* negation normal
* form
* formulae[1]:
* negated formula in
* negation normal
* form
* formulae[2]:
* positive formula as
* generated
* formulae[3]:
* negative formula as
* generated
*/
vector<bool> formula_in_file; /* The values in this
* vector will be set to
* true when the
* corresponding
* formulae have been
* written to files
* successfully. Index
* 0 corresponds to the
* positive formula and
* 1 to the negative
* formula.
*/
TempFsysName* formula_file_name[2]; /* Names for temporary */
TempFsysName* automaton_file_name; /* files. */
TempFsysName* cout_capture_file;
TempFsysName* cerr_capture_file;
private:
TestRoundInfo(const TestRoundInfo& info); /* Prevent copying and */
TestRoundInfo& operator= /* assignment of */
(const TestRoundInfo& info); /* TestRoundInfo
* objects.
*/
};
/******************************************************************************
*
* Inline function definitions for class TestRoundInfo.
*
*****************************************************************************/
/* ========================================================================= */
inline TestRoundInfo::TestRoundInfo() :
cout(&std::cout, ios::failbit | ios::badbit), number_of_translators(0),
current_round(1), next_round_to_run(1), next_round_to_stop(1),
error_report_round(0), error(false), all_tests_successful(true),
skip(false), abort(false), num_generated_statespaces(0),
total_statespace_states(0), total_statespace_transitions(0),
num_processed_formulae(0), fresh_statespace(false), statespace(0),
path_iterator(0), real_emptiness_check_size(0),
next_round_to_change_statespace(1), next_round_to_change_formula(1),
fresh_formula(false), formulae(4, static_cast<class ::Ltl::LtlFormula*>(0)),
formula_in_file(2, false), automaton_file_name(0), cout_capture_file(0),
cerr_capture_file(0)
/* ----------------------------------------------------------------------------
*
* Description: Constructor for class TestRoundInfo. Creates a new
* TestRoundInfo object.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
formula_file_name[0] = formula_file_name[1] = 0;
}
/* ========================================================================= */
inline TestRoundInfo::~TestRoundInfo()
/* ----------------------------------------------------------------------------
*
* Description: Destructor for class TestRoundInfo.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
}
#endif /* !TESTROUNDINFO_H */

View file

@ -1,96 +0,0 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* 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.
*/
#include <config.h>
#include "TestStatistics.h"
/******************************************************************************
*
* Function definitions for struct AlgorithmTestResults.
*
*****************************************************************************/
/* ========================================================================= */
void AlgorithmTestResults::emptinessReset()
/* ----------------------------------------------------------------------------
*
* Description: Resets the emptiness checking information in an
* AlgorithmTestResults structure.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
consistency_check_result = -1;
consistency_check_comparisons = 0;
failed_consistency_check_comparisons = 0;
for (int i = 0; i < 2; i++)
{
automaton_stats[i].number_of_product_states = 0;
automaton_stats[i].number_of_product_transitions = 1;
automaton_stats[i].emptiness_check_result.clear();
automaton_stats[i].emptiness_check_performed = false;
for (vector<AutomatonStats::CrossComparisonStats>::iterator it
= automaton_stats[i].cross_comparison_stats.begin();
it != automaton_stats[i].cross_comparison_stats.end();
++it)
{
it->first = false;
it->second = 0;
}
}
}
/* ========================================================================= */
void AlgorithmTestResults::fullReset()
/* ----------------------------------------------------------------------------
*
* Description: Resets the contents of an AlgorithmTestResults structure.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
emptinessReset();
for (int i = 0; i < 2; i++)
{
if (automaton_stats[i].buchi_automaton != 0)
delete automaton_stats[i].buchi_automaton;
automaton_stats[i].buchi_automaton = 0;
automaton_stats[i].number_of_buchi_states = 0;
automaton_stats[i].number_of_buchi_transitions = 0;
automaton_stats[i].number_of_acceptance_sets = 0;
automaton_stats[i].number_of_msccs = 0;
automaton_stats[i].nondeterminism_index = 0;
automaton_stats[i].buchi_generation_time = 0.0;
for (vector<int>::iterator it
= automaton_stats[i].buchi_intersection_check_stats.begin();
it != automaton_stats[i].buchi_intersection_check_stats.end();
++it)
*it = -1;
}
}

View file

@ -1,581 +0,0 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* 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 TESTSTATISTICS_H
#define TESTSTATISTICS_H
#include <config.h>
#include <utility>
#include <vector>
#include "EdgeContainer.h"
#include "Graph.h"
#include "LbttAlloc.h"
#include "BuchiAutomaton.h"
#include "Configuration.h"
#include "StateSpace.h"
using namespace std;
using Graph::BuchiAutomaton;
using Graph::StateSpace;
/******************************************************************************
*
* A data structure for storing test data for a single formula.
*
*****************************************************************************/
struct AutomatonStats
{
explicit AutomatonStats /* Constructor. */
(vector<Configuration::AlgorithmInformation>
::size_type number_of_algorithms,
StateSpace::size_type max_statespace_size);
/* default copy constructor */
~AutomatonStats(); /* Destructor. */
/* default assignment operator */
bool buchiAutomatonComputed() const; /* Tests whether a Büchi
* automaton has been
* computed.
*/
bool productAutomatonComputed() const; /* Tests whether a product
* automaton has been
* computed.
*/
bool crossComparisonPerformed /* Tests whether the */
(unsigned long int algorithm) const; /* result of the
* emptiness check has
* been compared against
* the result computed
* using some other
* implementation.
*/
bool buchiIntersectionCheckPerformed /* Tests whether the */
(unsigned long int algorithm) const; /* Büchi automata
* intersection check
* has been performed
* against a given
* implementation.
*/
BuchiAutomaton* buchi_automaton; /* A pointer to a Büchi
* automaton.
*/
BuchiAutomaton::size_type number_of_buchi_states; /* Number of states in the
* automaton.
*/
unsigned long int number_of_buchi_transitions; /* Number of transitions in
* the automaton.
*/
unsigned long int number_of_acceptance_sets; /* Number of acceptance
* sets in the automaton.
*/
unsigned long int number_of_msccs; /* Number of maximal
* strongly connected
* components in the
* automaton.
*/
unsigned long int nondeterminism_index; /* Nondeterminism index
*/
bool is_deterministic; /* True if the automaton
* is deterministic
*/
double buchi_generation_time; /* Time used to generate a
* Büchi automaton.
*/
::Graph::Graph<GraphEdgeContainer>::size_type /* Number of stats in a */
number_of_product_states; /* product automaton. */
unsigned long int number_of_product_transitions; /* Number of transitions in
* a product automaton.
*/
Bitset emptiness_check_result; /* Result of the emptiness
* check for the product
* automaton.
*/
bool emptiness_check_performed; /* Tells whether the
* contents of the previous
* Bitset are valid.
*/
typedef pair<bool, unsigned long int>
CrossComparisonStats;
vector<CrossComparisonStats> /* Emptiness check */
cross_comparison_stats; /* cross-comparison
* results. The `first'
* element of the pair
* tells whether a cross-
* comparison with a given
* algorithm has been
* performed, and the
* `second' element of the
* pair gives the number
* of system states in
* which the results
* differ.
*/
vector<int> buchi_intersection_check_stats; /* Büchi automaton
* intersection
* emptiness check
* results. The elements
* of the vector tell
* whether the check has
* been performed
* against the automata
* constructed from the
* negated formula using
* the other algorithms,
* and if yes, the result
* of the check
* (-1 = check not
* performed, 0 = check
* failed, 1 = check
* was successful).
*/
};
/******************************************************************************
*
* A data structure for storing test data for a single algorithm.
*
*****************************************************************************/
struct AlgorithmTestResults
{
explicit AlgorithmTestResults /* Constructor. */
(vector<Configuration::AlgorithmInformation>
::size_type
number_of_algorithms,
StateSpace::size_type max_statespace_size);
/* default copy constructor */
~AlgorithmTestResults(); /* Destructor. */
/* default assignment operator */
void emptinessReset(); /* Resets the emptiness
* checking information.
*/
void fullReset(); /* Resets the test results
* completely.
*/
int consistency_check_result; /* Tells the consistency
* check status for an
* algorithm. The value
* -1 means the check has
* not been performed, a 0
* stands for a failed
* check, and the value 1
* denotes that the check
* was successful.
*/
StateSpace::size_type /* Number of test cases */
consistency_check_comparisons; /* in the consistency
* check.
*/
StateSpace::size_type /* Number of failed test */
failed_consistency_check_comparisons; /* cases in the consistency
* check.
*/
vector<AutomatonStats> automaton_stats; /* A two-element vector
* storing test results
* for an algorithm.
*/
};
/******************************************************************************
*
* A data structure for storing test statistics for a single algorithm over the
* whole test session.
*
*****************************************************************************/
struct TestStatistics
{
explicit TestStatistics /* Constructor. */
(vector<TestStatistics>::size_type
number_of_algorithms);
/* default copy constructor */
~TestStatistics();
/* default assignment operator */
unsigned long int /* Number of failed */
failures_to_compute_buchi_automaton[2]; /* attempts to generate
* a Büchi automaton.
*/
unsigned long int buchi_automaton_count[2]; /* Number of attempts to
* generate a Büchi
* automaton.
*/
unsigned long int /* Number of failed */
failures_to_compute_product_automaton[2]; /* attempts to generate
* a product automaton.
*/
unsigned long int product_automaton_count[2]; /* Number of attempts to
* generate a product
* automaton.
*/
unsigned long int consistency_check_failures; /* Number of failed
* consistency checks.
*/
unsigned long int consistency_checks_performed; /* Number of consistency
* checks performed.
*/
BIGUINT total_number_of_buchi_states[2]; /* Total number of states
* in all the generated
* Büchi automata.
*/
BIGUINT total_number_of_buchi_transitions[2]; /* Total number of
* transitions in all
* the generated Büchi
* automata.
*/
BIGUINT total_number_of_acceptance_sets[2]; /* Total number of sets of
* accepting states in all
* the generated Büchi
* automata.
*/
BIGUINT total_nondeterminism_index[2]; /* Total nondetereminism
* index for all the
* generated Büchi automata.
*/
int total_deterministic_count[2]; /* Total number of
* deterministic automata
*/
double total_buchi_generation_time[2]; /* Total time used when
* generating Büchi
* automata.
*/
BIGUINT total_number_of_product_states[2]; /* Total number of states
* in all the generated
* product automata.
*/
BIGUINT total_number_of_product_transitions[2]; /* Total number of
* transitions in all the
* generated product
* automata.
*/
vector<unsigned long int> /* Number of failed */
cross_comparison_mismatches; /* result cross-
* comparisons.
*/
vector<unsigned long int> /* Number of failed */
initial_cross_comparison_mismatches; /* result cross-
* comparisons in the
* initial state of the
* state space.
*/
vector<unsigned long int> /* Number of result */
cross_comparisons_performed; /* cross-comparisons
* performed.
*/
vector<unsigned long int> /* Number of failed */
buchi_intersection_check_failures; /* Büchi automaton
* emptiness checks
* against the automata
* constructed from the
* negated formula
* using the other
* algorithms.
*/
vector<unsigned long int> /* Number of Büchi */
buchi_intersection_checks_performed; /* automaton emptiness
* checks performed
* against the automata
* constructed from the
* negated formula using
* the other algorithms.
*/
};
/******************************************************************************
*
* Inline function definitions for struct AutomatonStats.
*
*****************************************************************************/
/* ========================================================================= */
inline AutomatonStats::AutomatonStats
(vector<Configuration::AlgorithmInformation>::size_type number_of_algorithms,
StateSpace::size_type max_statespace_size) :
buchi_automaton(0), number_of_buchi_states(0), nondeterminism_index(0),
number_of_buchi_transitions(0), number_of_acceptance_sets(0),
number_of_msccs(0), buchi_generation_time(0.0), number_of_product_states(0),
number_of_product_transitions(1), is_deterministic(false),
emptiness_check_result(max_statespace_size),
emptiness_check_performed(false),
cross_comparison_stats(number_of_algorithms, make_pair(false, 0)),
buchi_intersection_check_stats(number_of_algorithms, -1)
/* ----------------------------------------------------------------------------
*
* Description: Constructor for struct AutomatonStats.
*
* Arguments: number_of_algorithms -- Number of implementations taking
* part in the tests.
* max_statespace_size -- Maximum size of the state spaces
* used in testing.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
emptiness_check_result.clear();
}
/* ========================================================================= */
inline AutomatonStats::~AutomatonStats()
/* ----------------------------------------------------------------------------
*
* Description: Destructor for struct AutomatonStats.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
inline bool AutomatonStats::buchiAutomatonComputed() const
/* ----------------------------------------------------------------------------
*
* Description: Test whether a Büchi automaton has been computed (i.e.,
* whether information about the automaton has been stored in
* the AutomatonStats structure).
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
return (buchi_automaton != 0);
}
/* ========================================================================= */
inline bool AutomatonStats::productAutomatonComputed() const
/* ----------------------------------------------------------------------------
*
* Description: Test whether a product automaton has been computed (i.e.,
* whether information about the automaton has been stored in
* the AutomatonStats structure).
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
return (number_of_product_states != 0
|| number_of_product_transitions <= number_of_product_states);
}
/* ========================================================================= */
inline bool
AutomatonStats::crossComparisonPerformed(unsigned long int algorithm) const
/* ----------------------------------------------------------------------------
*
* Description: Test whether the emptiness check result for a product
* automaton has been compared with another result computed
* using a different implementation.
*
* Arguments: algorithm -- Implementation identifier.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
return cross_comparison_stats[algorithm].first;
}
/* ========================================================================= */
inline bool
AutomatonStats::buchiIntersectionCheckPerformed(unsigned long int algorithm)
const
/* ----------------------------------------------------------------------------
*
* Description: Test whether the Büchi automata intersection check result
* (against some other implementation) is available in the data
* structure.
*
* Arguments: algorithm -- Implementation identifier.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
return (buchi_intersection_check_stats[algorithm] != -1);
}
/******************************************************************************
*
* Inline function definitions for struct AlgorithmTestResults.
*
*****************************************************************************/
/* ========================================================================= */
inline AlgorithmTestResults::AlgorithmTestResults
(vector<Configuration::AlgorithmInformation>::size_type number_of_algorithms,
StateSpace::size_type max_statespace_size) :
consistency_check_result(-1), consistency_check_comparisons(0),
failed_consistency_check_comparisons(0),
automaton_stats(2, AutomatonStats(number_of_algorithms,
max_statespace_size))
/* ----------------------------------------------------------------------------
*
* Description: Constructor for struct AlgorithmTestResults.
*
* Arguments: number_of_algorithms -- Number of implementations taking
* part in the tests.
* max_statespace_size -- Maximum size of the state spaces
* used in testing.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
inline AlgorithmTestResults::~AlgorithmTestResults()
/* ----------------------------------------------------------------------------
*
* Description: Destructor for struct AlgorithmTestResults.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/******************************************************************************
*
* Inline function definitions for struct TestStatistics.
*
*****************************************************************************/
/* ========================================================================= */
inline TestStatistics::TestStatistics
(vector<TestStatistics>::size_type number_of_algorithms) :
consistency_check_failures(0), consistency_checks_performed(0),
cross_comparison_mismatches(number_of_algorithms, 0),
initial_cross_comparison_mismatches(number_of_algorithms, 0),
cross_comparisons_performed(number_of_algorithms, 0),
buchi_intersection_check_failures(number_of_algorithms, 0),
buchi_intersection_checks_performed(number_of_algorithms, 0)
/* ----------------------------------------------------------------------------
*
* Description: Constructor for struct TestStatistics.
*
* Arguments: number_of_algorithms -- Number of implementations taking
* part in the tests.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
for (int i = 0; i < 2; i++)
{
failures_to_compute_buchi_automaton[i] = 0;
buchi_automaton_count[i] = 0;
failures_to_compute_product_automaton[i] = 0;
product_automaton_count[i] = 0;
total_number_of_buchi_states[i] = 0;
total_number_of_buchi_transitions[i] = 0;
total_number_of_acceptance_sets[i] = 0;
total_nondeterminism_index[i] = 0;
total_deterministic_count[i] = 0;
total_number_of_product_states[i] = 0;
total_number_of_product_transitions[i] = 0;
total_buchi_generation_time[i] = 0.0;
}
}
/* ========================================================================= */
inline TestStatistics::~TestStatistics()
/* ----------------------------------------------------------------------------
*
* Description: Destructor for struct TestStatistics.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
#endif /* !TESTSTATISTICS_H */

View file

@ -1,91 +0,0 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* 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 TRANSLATORINTERFACE_H
#define TRANSLATORINTERFACE_H
#include <config.h>
#include "LtlFormula.h"
/******************************************************************************
*
* General interface class for an LTL-to-Büchi translator. The interface
* provides an abstract member function `translate' taking an LtlFormula
* and an output file name as arguments. The purpose of an actual
* implementation of the function is to translate the given LtlFormula into
* an automaton and store the results in the given file.
*
*****************************************************************************/
class TranslatorInterface
{
public:
TranslatorInterface(); /* Constructor. */
virtual ~TranslatorInterface() = 0; /* Destructor. */
virtual void translate /* Interface for a */
(const ::Ltl::LtlFormula& formula, /* translation */
const char* filename) = 0; /* algorithm. */
private:
TranslatorInterface(const TranslatorInterface&); /* Prevent copying and */
TranslatorInterface& operator= /* assignment of */
(const TranslatorInterface&); /* TranslatorInterface
* objects.
*/
};
/******************************************************************************
*
* Inline function definitions for class TranslatorInterface.
*
*****************************************************************************/
/* ========================================================================= */
inline TranslatorInterface::TranslatorInterface()
/* ----------------------------------------------------------------------------
*
* Description: Constructor for class TranslatorInterface.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
inline TranslatorInterface::~TranslatorInterface()
/* ----------------------------------------------------------------------------
*
* Description: Destructor for class TranslatorInterface.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
#endif /* !TRANSLATORINTERFACE_H */

View file

@ -1,940 +0,0 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* 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.
*/
#include <config.h>
#include <csignal>
#include <cstdio>
#include <iostream>
#include <fstream>
#ifdef HAVE_SSTREAM
#include <sstream>
#else
#include <strstream>
#endif /* HAVE_SSTREAM */
#include "DispUtil.h"
#include "SharedTestData.h"
#include "StatDisplay.h"
#include "StringUtil.h"
#include "TestRoundInfo.h"
#include "TestStatistics.h"
#include "TestOperations.h"
#include "UserCommandReader.h"
#include "UserCommands.h"
#ifdef HAVE_READLINE
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <readline/readline.h>
#include <readline/history.h>
#endif /* HAVE_READLINE */
#ifdef HAVE_ISATTY
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif /* HAVE_UNISTD_H */
#endif /* HAVE_ISATTY */
/******************************************************************************
*
* Functions for reading and parsing user commands.
*
*****************************************************************************/
namespace UserCommandInterface
{
using namespace ::SharedTestData;
using namespace ::StatDisplay;
using namespace ::StringUtil;
using namespace ::UserCommands;
/* ========================================================================= */
void executeUserCommands()
/* ----------------------------------------------------------------------------
*
* Description: Loop for reading user commands and executing them after a
* test round.
*
* Arguments: None.
*
* Returns: Nothing. However, changes `round_info.current_round',
* `round_info.next_round_to_stop',
* `round_info.next_round_to_run' and `round_info.abort' as a
* side effect, depending on the user's wish to abort testing,
* skip some number of test rounds or continue testing for a
* number of rounds.
*
* ------------------------------------------------------------------------ */
{
string input_line;
vector<string> input_tokens;
TokenType token;
bool formula_type = true;
pair<string, bool> redirection_info;
string external_command;
ofstream* output_file = 0;
#ifdef HAVE_SSTREAM
ostringstream* output_string = 0;
#else
ostrstream* output_string = 0;
#endif /* HAVE_SSTREAM */
ostream* output_stream = 0;
const string prompt = " ** [Round " + toString(round_info.current_round)
+ " of " + toString(configuration.global_options.
number_of_rounds)
+ "] >> ";
int indent;
#ifdef HAVE_READLINE
char* prompt_c_str = new char[prompt.length() + 1];
strcpy(prompt_c_str, prompt.c_str());
char* line;
try
{
#endif /* HAVE_READLINE */
signal(SIGPIPE, SIG_IGN);
while (1)
{
try
{
input_line = "";
#ifdef HAVE_READLINE
line = readline(prompt_c_str);
if (line != static_cast<char*>(0))
input_line = line;
else
{
#else
round_info.cout << prompt;
round_info.cout.flush();
getline(cin, input_line, '\n');
if (cin.eof())
{
cin.clear();
#endif /* HAVE_READLINE */
#ifdef HAVE_ISATTY
/*
* If standard input is not bound to a terminal, act on EOF as if the
* `continue' command had been issued. Otherwise act as if an empty
* line was given as input.
*/
if (!isatty(STDIN_FILENO))
input_line = "continue";
else
{
round_info.cout << '\n';
round_info.cout.flush();
}
#else
input_line = "continue";
round_info.cout << input_line << '\n';
round_info.cout.flush();
#endif /* HAVE_ISATTY */
}
#ifdef HAVE_ISATTY
if (!isatty(STDIN_FILENO))
{
round_info.cout << input_line << '\n';
round_info.cout.flush();
}
#endif /* HAVE_ISATTY */
#ifdef HAVE_READLINE
if (line != static_cast<char*>(0) /* line may be 0 on EOF */
&& input_line.find_first_not_of(" \t") != string::npos)
{
add_history(line);
free(line);
}
#endif /* HAVE_READLINE */
/*
* If the input line contains an unescaped pipe symbol ('|') outside
* quotes, extract an external command from the line.
*/
external_command = "";
string::size_type pos
= findInQuotedString(input_line, "|", OUTSIDE_QUOTES);
if (pos != string::npos)
{
string::size_type nonspace_pos
= input_line.find_first_not_of(" \t", pos + 1);
if (nonspace_pos != string::npos)
{
external_command = input_line.substr(nonspace_pos);
input_line = input_line.substr(0, pos);
}
}
sliceString(substituteInQuotedString(input_line, " \t", "\n\n",
OUTSIDE_QUOTES),
"\n",
input_tokens);
user_break = false;
if (!input_tokens.empty() || !external_command.empty())
{
round_info.cout << '\n';
round_info.cout.flush();
}
if (!input_tokens.empty())
{
token = parseCommand(input_tokens[0]);
if (token == CONTINUE || token == SKIP)
{
verifyArgumentCount(input_tokens, 0, 1);
unsigned long int rounds_to_continue;
rounds_to_continue = (input_tokens.size() > 1
? parseNumber(input_tokens[1])
: 1);
if (rounds_to_continue == 0)
throw CommandErrorException("Argument of the command must be "
"positive.");
if (token == CONTINUE)
{
bool all_algorithms_disabled = true;
for (vector<Configuration::AlgorithmInformation>::const_iterator
algorithm = configuration.algorithms.begin();
algorithm != configuration.algorithms.end();
++algorithm)
{
if (algorithm->enabled)
{
all_algorithms_disabled = false;
break;
}
}
/*
* Show a warning if the `continue' command would result in no
* further tests in the case that none of the implementations is
* enabled for testing.
*/
if (configuration.global_options.interactive
!= Configuration::ALWAYS
&& all_algorithms_disabled)
{
round_info.cout << " Warning! All algorithms are currently "
"disabled.\n Are you sure you wish to "
"continue? [y/n] ";
round_info.cout.flush();
input_line = "";
getline(cin, input_line, '\n');
sliceString(input_line, " \t", input_tokens);
if (!input_tokens.empty()
&& (input_tokens[0][0] == 'y' || input_tokens[0][0] == 'Y'))
round_info.next_round_to_stop
= configuration.global_options.number_of_rounds + 1;
else
{
round_info.cout << '\n';
round_info.cout.flush();
continue;
}
}
if (round_info.next_round_to_run == round_info.current_round)
round_info.next_round_to_run++;
if (configuration.global_options.interactive
== Configuration::ALWAYS
|| input_tokens.size() > 1)
round_info.next_round_to_stop
= round_info.current_round + rounds_to_continue;
}
else /* token == SKIP */
{
round_info.next_round_to_stop
= round_info.current_round + rounds_to_continue;
round_info.next_round_to_run = round_info.next_round_to_stop + 1;
}
break;
}
else if (token == ENABLE || token == DISABLE)
{
verifyArgumentCount(input_tokens, 0, 1);
changeAlgorithmState(input_tokens, token == ENABLE);
continue;
}
else if (token == QUIT)
{
verifyArgumentCount(input_tokens, 0, 0);
round_info.abort = true;
break;
}
else if (token == VERBOSITY)
{
verifyArgumentCount(input_tokens, 0, 1);
changeVerbosity(input_tokens);
continue;
}
if (round_info.skip
&& (token == BUCHI || token == BUCHIANALYZE
|| token == CONSISTENCYANALYSIS || token == EVALUATE
|| token == FORMULA || token == INCONSISTENCIES
|| token == RESULTANALYZE || token == STATESPACE))
throw CommandErrorException("This command is not available because "
"the current test round was skipped.");
/*
* If the command expects a formula identifier as a parameter,
* determine the type of the formula to which the command refers.
*/
if (token == BUCHI || token == EVALUATE
|| token == FORMULA || token == RESULTANALYZE)
formula_type = parseFormulaType(input_tokens);
if (!external_command.empty())
{
/*
* If the command output should be piped to an external program,
* prepare to collect the output into a string. In this case no
* output redirection (> or >>) is allowed.
*/
#ifdef HAVE_SSTREAM
output_string = new ostringstream();
#else
output_string = new ostrstream();
#endif /* HAVE_SSTREAM */
output_stream = output_string;
indent = 0;
}
else
{
/*
* Determine whether the output of the command should be saved or
* appended to a file, instead of displaying it on the console. If
* output redirection is required, open a file for output.
*/
redirection_info = parseRedirection(input_tokens);
if (redirection_info.first.empty())
{
output_stream = &cout;
indent = 2;
}
else
{
output_file = new ofstream();
try
{
TestOperations::openFile(redirection_info.first.c_str(),
*output_file,
ios::out | (redirection_info.second
? ios::app
: ios::trunc),
2);
}
catch (const IOException& e)
{
delete output_file;
output_file = 0;
throw CommandErrorException(e.what());
}
output_stream = output_file;
indent = 0;
}
}
switch (token)
{
case ALGORITHMS :
verifyArgumentCount(input_tokens, 0, 0);
printAlgorithmList(*output_stream, indent);
if (output_file != 0)
round_info.cout << " List of algorithms";
break;
case BUCHI :
{
bool use_dot = (input_tokens.size() == 3
&& input_tokens[2] == "dot");
verifyArgumentCount(input_tokens, 1, 2);
printBuchiAutomaton(*output_stream, indent,
formula_type,
input_tokens,
(use_dot ? Graph::DOT : Graph::NORMAL));
if (output_file != 0)
{
round_info.cout << " Büchi automaton information";
if (use_dot)
round_info.cout << " (in dot format)";
}
}
break;
case BUCHIANALYZE :
verifyArgumentCount(input_tokens, 2, 2);
printAutomatonAnalysisResults(*output_stream, indent,
input_tokens);
if (output_file != 0)
round_info.cout << " Büchi automaton intersection emptiness "
"check analysis";
break;
case CONSISTENCYANALYSIS :
verifyArgumentCount(input_tokens, 1, 2);
printConsistencyAnalysisResults(*output_stream, indent,
input_tokens);
if (output_file != 0)
round_info.cout << " Consistency check result analysis";
break;
case EVALUATE :
verifyArgumentCount(input_tokens, 0, 2);
evaluateFormula(*output_stream, indent, formula_type,
input_tokens);
if (output_file != 0)
round_info.cout << " Formula acceptance information";
break;
case FORMULA :
verifyArgumentCount(input_tokens, 0, 1);
printFormula(*output_stream, indent, formula_type, input_tokens);
if (output_file != 0)
round_info.cout << string(" ") + (formula_type
? "Formula"
: "Negated formula");
break;
case HELP :
verifyArgumentCount(input_tokens, 0, 1);
printCommandHelp(*output_stream, indent, input_tokens);
if (output_file != 0)
round_info.cout << " Command help";
break;
case INCONSISTENCIES :
verifyArgumentCount(input_tokens, 0, 1);
printInconsistencies(*output_stream, indent, input_tokens);
if (output_file != 0)
round_info.cout << " Model checking result consistency check "
"results for round "
+ toString(round_info.current_round)
+ "\n ";
break;
case RESULTANALYZE :
verifyArgumentCount(input_tokens, 2, 3);
printCrossComparisonAnalysisResults
(*output_stream, indent, formula_type, input_tokens);
if (output_file != 0)
round_info.cout << " Model checking result cross-comparison "
"analysis";
break;
case RESULTS :
verifyArgumentCount(input_tokens, 0, 1);
printTestResults(*output_stream, indent, input_tokens);
if (output_file != 0)
round_info.cout << " Test results for round "
+ toString(round_info.current_round);
break;
case STATESPACE :
{
bool use_dot = (input_tokens.size() == 2
&& input_tokens[1] == "dot");
verifyArgumentCount(input_tokens, 0, 1);
printStateSpace(*output_stream, indent, input_tokens,
(use_dot ? Graph::DOT : Graph::NORMAL));
if (output_file != 0)
{
round_info.cout << " State space information";
if (use_dot)
round_info.cout << " (in dot format)";
}
}
break;
case STATISTICS :
verifyArgumentCount(input_tokens, 0, 0);
printCollectiveStats(*output_stream, indent);
if (output_file != 0)
round_info.cout << " Test statistics after round "
+ toString(round_info.current_round);
break;
default :
throw CommandErrorException("Unknown command (`" + input_tokens[0]
+ "').");
}
if (output_string != 0)
{
*output_stream << ends;
string outstring(output_string->str());
FILE* output_pipe = popen(external_command.c_str(), "w");
if (output_pipe == NULL)
throw ExecFailedException(external_command);
fputs(outstring.c_str(), output_pipe);
pclose(output_pipe);
}
else
{
if (output_file != 0)
round_info.cout << string(redirection_info.second
? " appended"
: " written")
+ " to `" + redirection_info.first + "'.\n";
round_info.cout << '\n';
round_info.cout.flush();
}
}
else if (!external_command.empty())
{
(void) system(external_command.c_str());
round_info.cout << '\n';
round_info.cout.flush();
}
}
catch (const Exception& e)
{
::DispUtil::printTextBlock(cout, 2, string("Error: ") + e.what() + '\n',
78);
}
if (output_string != 0)
{
#ifndef HAVE_SSTREAM
output_string->freeze(0);
#endif /* HAVE_SSTREAM */
delete output_string;
output_string = 0;
}
else if (output_file != 0)
{
output_file->close();
delete output_file;
output_file = 0;
}
}
#ifdef HAVE_READLINE
}
catch (...)
{
delete[] prompt_c_str;
throw;
}
delete[] prompt_c_str;
#endif /* HAVE_READLINE */
signal(SIGPIPE, SIG_DFL);
}
/* ========================================================================= */
TokenType parseCommand(const string& token)
/* ----------------------------------------------------------------------------
*
* Description: Parses a user command by translating a command name into
* its corresponding TokenType identifier.
*
* Argument: token -- A reference to a string containing the command.
*
* Returns: A command identifier of the enumerated type TokenType.
*
* ------------------------------------------------------------------------- */
{
TokenType token_type = UNKNOWN;
string::size_type len = token.length();
bool ambiguous = false;
if (token.empty())
return token_type;
switch (token[0])
{
case 'a' :
if (token.compare(1, len - 1, "lgorithms", len - 1) == 0)
token_type = ALGORITHMS;
break;
case 'b' :
if (len < 2)
ambiguous = true;
else if (token[1] == 'u')
{
if (len < 3)
ambiguous = true;
else if (token[2] == 'c')
{
if (len < 4)
ambiguous = true;
else if (token[3] == 'h')
{
if (len < 5)
ambiguous = true;
else if (token[4] == 'i')
{
if (len < 6)
token_type = BUCHI;
else if (token[5] == 'a'
&& token.compare(6, len - 6, "nalysis", len - 6) == 0)
token_type = BUCHIANALYZE;
}
}
}
}
break;
case 'c' :
if (len < 2)
ambiguous = true;
else if (token[1] == 'o')
{
if (len < 3)
ambiguous = true;
else if (token[2] == 'n')
{
if (len < 4)
ambiguous = true;
else if (token[3] == 's'
&& token.compare(4, len - 4, "istencyanalysis", len - 4)
== 0)
token_type = CONSISTENCYANALYSIS;
else if (token[3] == 't'
&& token.compare(4, len - 4, "inue", len - 4) == 0)
token_type = CONTINUE;
}
}
break;
case 'd' :
if (token.compare(1, len - 1, "isable", len - 1) == 0)
token_type = DISABLE;
break;
case 'e' :
if (len < 2)
ambiguous = true;
else if (token[1] == 'n')
{
if (token.compare(2, len - 2, "able", len - 2) == 0)
token_type = ENABLE;
}
else if (token[1] == 'v')
{
if (token.compare(2, len - 2, "aluate", len - 2) == 0)
token_type = EVALUATE;
}
break;
case 'f' :
if (token.compare(1, len - 1, "ormula", len - 1) == 0)
token_type = FORMULA;
break;
case 'h' :
if (token.compare(1, len - 1, "elp", len - 1) == 0)
token_type = HELP;
break;
case 'i' :
if (len < 2)
ambiguous = true;
else if (token[1] == 'm')
{
if (token.compare(2, len - 2, "plementations", len - 2) == 0)
token_type = ALGORITHMS;
}
else if (token[1] == 'n')
{
if (token.compare(2, len - 2, "consistencies", len - 2) == 0)
token_type = INCONSISTENCIES;
}
break;
case 'q' :
if (token.compare(1, len - 1, "uit", len - 1) == 0)
token_type = QUIT;
break;
case 'r' :
if (len < 2)
ambiguous = true;
else if (token[1] == 'e')
{
if (len < 3)
ambiguous = true;
else if (token[2] == 's')
{
if (len < 4)
ambiguous = true;
else if (token[3] == 'u')
{
if (len < 5)
ambiguous = true;
else if (token[4] == 'l')
{
if (len < 6)
ambiguous = true;
else if (token[5] == 't')
{
if (len < 7)
ambiguous = true;
else if (token[6] == 's' && len == 7)
token_type = RESULTS;
else if (token[6] == 'a')
{
if (token.compare(7, len - 7, "nalysis", len - 7) == 0)
token_type = RESULTANALYZE;
}
}
}
}
}
}
break;
case 's' :
if (len < 2)
ambiguous = true;
else if (token[1] == 'k')
{
if (token.compare(2, len - 2, "ip", len - 2) == 0)
token_type = SKIP;
}
else if (token[1] == 't')
{
if (len < 3)
ambiguous = true;
else if (token[2] == 'a')
{
if (len < 4)
ambiguous = true;
else if (token[3] == 't')
{
if (len < 5)
ambiguous = true;
else if (token[4] == 'e')
{
if (token.compare(5, len - 5, "space", len - 5) == 0)
token_type = STATESPACE;
}
else if (token[4] == 'i')
{
if (token.compare(5, len - 5, "stics", len - 5) == 0)
token_type = STATISTICS;
}
}
}
}
break;
case 't' :
if (token.compare(1, len - 1, "ranslators", len - 1) == 0)
token_type = ALGORITHMS;
break;
case 'v' :
if (token.compare(1, len - 1, "erbosity", len - 1) == 0)
token_type = VERBOSITY;
break;
}
if (ambiguous)
throw CommandErrorException("Ambiguous command.");
return token_type;
}
/* ========================================================================= */
void verifyArgumentCount
(const vector<string>& command, vector<string>::size_type min_arg_count,
vector<string>::size_type max_arg_count)
/* ----------------------------------------------------------------------------
*
* Description: Verifies that the number of arguments given for a user
* command is between a given interval.
*
* Arguments: command -- A reference to a constant vector of
* strings (the user command and its
* arguments).
* min_arg_count -- Smallest allowed number of arguments.
* max_arg_count -- Largest allowed number of arguments.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
if (command.size() < min_arg_count + 1)
throw CommandErrorException("Too few arguments for command.");
else if (command.size() > max_arg_count + 1)
throw CommandErrorException("Too many arguments for command.");
}
/* ========================================================================= */
pair<string, bool> parseRedirection(vector<string>& input_tokens)
/* ----------------------------------------------------------------------------
*
* Description: Tests whether the last argument to a user command specifies
* output redirection. If redirection is requested, the
* "argument" specifying the redirection is removed from the
* vector of strings forming the command.
*
* Argument: input_tokens -- A reference to a vector of strings giving
* the user command and its arguments.
*
* Returns: A pair whose first component is the name of the output file
* (or the empty string if no redirection was specified) and
* whose second component determines whether the output should
* be appended to the file instead of creating a new file.
*
* ------------------------------------------------------------------------- */
{
string filename;
bool append = false;
if (!input_tokens.empty())
{
string& token = input_tokens.back();
if (token[0] == '>')
{
if (token.length() > 1)
{
if (token[1] == '>')
{
if (token.length() > 2)
{
append = true;
filename = unquoteString(token.substr(2));
input_tokens.pop_back();
}
}
else
{
filename = unquoteString(token.substr(1));
input_tokens.pop_back();
}
}
}
else if (input_tokens.size() >= 2)
{
string& token = *(input_tokens.rbegin() + 1);
if (token == ">" || token == ">>")
{
filename = unquoteString(input_tokens.back());
append = (token.length() == 2);
input_tokens.pop_back();
input_tokens.pop_back();
}
}
}
return make_pair(filename, append);
}
/* ========================================================================= */
bool parseFormulaType(vector<string>& input_tokens)
/* ----------------------------------------------------------------------------
*
* Description: Tests whether the first argument of a command specifies a
* formula (i.e., whether the first argument of the command is
* either a `+' or a `-'). If it is, the argument is removed
* from the vector of strings forming the command.
*
* Argument: input_tokens -- A reference to a vector of strings giving
* the user command.
*
* Returns: A truth value according to whether a formula or its negation
* was specified; the effect of specifying no formula type is
* the same as giving a `+' as an argument (i.e. the formula
* type defaults to the positive formula).
*
* ------------------------------------------------------------------------- */
{
bool formula_type = true;
if (input_tokens.size() >= 2)
{
formula_type = (input_tokens[1] != "-");
if (input_tokens[1] == "+" || input_tokens[1] == "-")
input_tokens.erase(input_tokens.begin());
}
return formula_type;
}
/* ========================================================================= */
void verifyNumber
(unsigned long int number, unsigned long int max, const char* error_message)
/* ----------------------------------------------------------------------------
*
* Description: Checks that a given unsigned long integer is less than a
* given maximum value. Throws an exception with an error
* message if this is not the case.
*
* Argument: number -- Number to be tested.
* max -- Value the number is to be tested against.
* error_message -- Error message.
*
* Returns: Nothing. Throws an exception if the check fails.
*
* ------------------------------------------------------------------------- */
{
if (number >= max)
throw CommandErrorException(string(error_message) + " ("
+ toString(number) + ").");
}
}

View file

@ -1,174 +0,0 @@
/*
* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
* Heikki Tauriainen <Heikki.Tauriainen@tkk.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* 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 USERCOMMANDREADER_H
#define USERCOMMANDREADER_H
#include <config.h>
#include <string>
#include <utility>
#include <vector>
#include "LbttAlloc.h"
#include "Configuration.h"
#include "Exception.h"
using namespace std;
extern Configuration configuration;
extern bool user_break;
/******************************************************************************
*
* Interactive user command interface.
*
*****************************************************************************/
namespace UserCommandInterface
{
void executeUserCommands(); /* Function for reading and
* executing user commands
* at the end of a test
* round.
*/
enum TokenType /* User commands. */
{ALGORITHMS, BUCHI, BUCHIANALYZE,
CONSISTENCYANALYSIS, CONTINUE, DISABLE, ENABLE,
EVALUATE, FORMULA, HELP, INCONSISTENCIES, QUIT,
RESULTANALYZE, RESULTS, SKIP, STATESPACE,
STATISTICS, VERBOSITY, UNKNOWN, _NO_INPUT};
TokenType parseCommand(const string& token); /* Translates a command
* name into its
* corresponding
* TokenType identifier.
*/
void verifyArgumentCount /* Checks that the */
(const vector<string>& arguments, /* number of arguments */
vector<string>::size_type min_arg_count, /* for a command is */
vector<string>::size_type max_arg_count); /* within given limits. */
pair<string, bool> parseRedirection /* Checks whether an */
(vector<string>& input_tokens); /* user command given
* will require
* redirecting its
* output to a file.
*/
bool parseFormulaType /* Checks whether an */
(vector<string>& input_tokens); /* user command
* specified a positive
* or a negative
* formula.
*/
void verifyNumber /* Checks that a given */
(unsigned long int number, /* number is less than a */
unsigned long int max, /* given maximum value. */
const char* error_message);
/******************************************************************************
*
* An exception class for reporting errors in user commands.
*
*****************************************************************************/
class CommandErrorException : public Exception
{
public:
CommandErrorException /* Constructor. */
(const string& message
= "Syntax error in command.");
/* default copy constructor */
~CommandErrorException() throw(); /* Destructor. */
CommandErrorException& operator= /* Assignment operator. */
(const CommandErrorException& e);
};
/******************************************************************************
*
* Inline function definitions for class CommandErrorException.
*
*****************************************************************************/
/* ========================================================================= */
inline CommandErrorException::CommandErrorException
(const string& message) :
Exception(message)
/* ----------------------------------------------------------------------------
*
* Description: Constructor for class CommandErrorException. Creates an
* exception object and initializes it with an error message.
*
* Arguments: message -- A reference to a constant string containing the
* error message.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
inline CommandErrorException::~CommandErrorException() throw()
/* ----------------------------------------------------------------------------
*
* Description: Destructor for class CommandErrorException.
*
* Arguments: None.
*
* Returns: Nothing.
*
* ------------------------------------------------------------------------- */
{
}
/* ========================================================================= */
inline CommandErrorException&
CommandErrorException::operator=(const CommandErrorException& e)
/* ----------------------------------------------------------------------------
*
* Description: Assignment operator for class CommandErrorException. Copies
* the contents of an exception object to another.
*
* Arguments: e -- A reference to a constant CommandErrorException.
*
* Returns: A reference to the object assigned to.
*
* ------------------------------------------------------------------------- */
{
Exception::operator=(e);
return *this;
}
}
#endif /* !USERCOMMANDREADER_H */

File diff suppressed because it is too large Load diff

View file

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

File diff suppressed because it is too large Load diff

View file

@ -1,188 +0,0 @@
/* getopt_long and getopt_long_only entry points for GNU getopt.
Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98
Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "gnu-getopt.h"
#if !defined __STDC__ || !__STDC__
/* This is a separate conditional since some stdc systems
reject `defined (const)'. */
#ifndef const
#define const
#endif
#endif
#include <stdio.h>
/* Comment out all this code if we are using the GNU C Library, and are not
actually compiling the library itself. This code is part of the GNU C
Library, but also included in many other GNU distributions. Compiling
and linking in this code is a waste when using the GNU C library
(especially if it is a shared library). Rather than having every GNU
program understand `configure --with-gnu-libc' and omit the object files,
it is simpler to just do this in the source for each such file. */
#define GETOPT_INTERFACE_VERSION 2
#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
#include <gnu-versions.h>
#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
#define ELIDE_CODE
#endif
#endif
#ifndef ELIDE_CODE
/* This needs to come after some library #include
to get __GNU_LIBRARY__ defined. */
#ifdef __GNU_LIBRARY__
#include <stdlib.h>
#endif
#ifndef NULL
#define NULL 0
#endif
int
gnu_getopt_long (argc, argv, options, long_options, opt_index)
int argc;
char *const *argv;
const char *options;
const struct gnu_option *long_options;
int *opt_index;
{
return _gnu_getopt_internal (argc, argv, options, long_options, opt_index, 0);
}
/* Like getopt_long, but '-' as well as '--' can indicate a long option.
If an option that starts with '-' (not '--') doesn't match a long option,
but does match a short option, it is parsed as a short option
instead. */
int
gnu_getopt_long_only (argc, argv, options, long_options, opt_index)
int argc;
char *const *argv;
const char *options;
const struct gnu_option *long_options;
int *opt_index;
{
return _gnu_getopt_internal (argc, argv, options, long_options, opt_index, 1);
}
#endif /* Not ELIDE_CODE. */
#ifdef TEST
#include <stdio.h>
int
main (argc, argv)
int argc;
char **argv;
{
int c;
int digit_optind = 0;
while (1)
{
int this_option_optind = gnu_optind ? gnu_optind : 1;
int option_index = 0;
static struct gnu_option long_options[] =
{
{"add", 1, 0, 0},
{"append", 0, 0, 0},
{"delete", 1, 0, 0},
{"verbose", 0, 0, 0},
{"create", 0, 0, 0},
{"file", 1, 0, 0},
{0, 0, 0, 0}
};
c = gnu_getopt_long (argc, argv, "abc:d:0123456789",
long_options, &option_index);
if (c == -1)
break;
switch (c)
{
case 0:
printf ("option %s", long_options[option_index].name);
if (gnu_optarg)
printf (" with arg %s", gnu_optarg);
printf ("\n");
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
if (digit_optind != 0 && digit_optind != this_option_optind)
printf ("digits occur in two different argv-elements.\n");
digit_optind = this_option_optind;
printf ("option %c\n", c);
break;
case 'a':
printf ("option a\n");
break;
case 'b':
printf ("option b\n");
break;
case 'c':
printf ("option c with value `%s'\n", gnu_optarg);
break;
case 'd':
printf ("option d with value `%s'\n", gnu_optarg);
break;
case '?':
break;
default:
printf ("?? getopt returned character code 0%o ??\n", c);
}
}
if (gnu_optind < argc)
{
printf ("non-option ARGV-elements: ");
while (gnu_optind < argc)
printf ("%s ", argv[gnu_optind++]);
printf ("\n");
}
exit (0);
}
#endif /* TEST */

Some files were not shown because too many files have changed in this diff Show more