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:
parent
a577850eb3
commit
e2f17f65b8
105 changed files with 29 additions and 52054 deletions
|
|
@ -23,9 +23,6 @@
|
||||||
if WITH_INCLUDED_BUDDY
|
if WITH_INCLUDED_BUDDY
|
||||||
MAYBE_BUDDY = buddy
|
MAYBE_BUDDY = buddy
|
||||||
endif WITH_INCLUDED_BUDDY
|
endif WITH_INCLUDED_BUDDY
|
||||||
if WITH_INCLUDED_LBTT
|
|
||||||
MAYBE_LBTT = lbtt
|
|
||||||
endif WITH_INCLUDED_LBTT
|
|
||||||
if NEVER
|
if NEVER
|
||||||
# For Automake a conditional directory
|
# For Automake a conditional directory
|
||||||
# is conditionally built, but unconditionally distributed.
|
# is conditionally built, but unconditionally distributed.
|
||||||
|
|
@ -34,8 +31,7 @@ if NEVER
|
||||||
NEVER_BENCH = bench
|
NEVER_BENCH = bench
|
||||||
endif
|
endif
|
||||||
|
|
||||||
SUBDIRS = $(MAYBE_BUDDY) $(MAYBE_LBTT) \
|
SUBDIRS = $(MAYBE_BUDDY) $(NEVER_BENCH) doc lib src wrap ltdl iface
|
||||||
$(NEVER_BENCH) doc lib src wrap ltdl iface
|
|
||||||
|
|
||||||
UTF8 = utf8/doc/ReleaseNotes utf8/doc/utf8cpp.html utf8/utf8.h \
|
UTF8 = utf8/doc/ReleaseNotes utf8/doc/utf8cpp.html utf8/utf8.h \
|
||||||
utf8/utf8/checked.h utf8/utf8/core.h utf8/utf8/unchecked.h
|
utf8/utf8/checked.h utf8/utf8/core.h utf8/utf8/unchecked.h
|
||||||
|
|
|
||||||
46
README
46
README
|
|
@ -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
|
you don't have Python installed, you should run configure with
|
||||||
the --disable-python option (see below).
|
the --disable-python option (see below).
|
||||||
|
|
||||||
Spot also uses modified versions of BuDDy (a binary decision diagram),
|
The Boost libraries should also be installed.
|
||||||
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.
|
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
|
Building and installing
|
||||||
|
|
@ -60,20 +74,13 @@ flags specific to Spot:
|
||||||
CVS repository hosted by the Università di Torino.
|
CVS repository hosted by the Università di Torino.
|
||||||
|
|
||||||
--with-included-buddy
|
--with-included-buddy
|
||||||
--with-included-lbtt
|
After you have installed Spot the first time, a modified version
|
||||||
After you have installed Spot the first time, LBTT and a modified
|
of BuDDy will be installed. The next time you reconfigure Spot,
|
||||||
version of BuDDy will be installed. The next time you reconfigure
|
configure will detect that this version is already installed, and
|
||||||
Spot, configure will detect that these versions are already
|
will attempt to use it directly (this is in case you had to modify
|
||||||
installed, and will attempt to use these installed versions
|
one of these yourself for another purpose). This option will
|
||||||
directly (this is in case you had to modify one of these yourself
|
*force* the use, build, and installation of the included version
|
||||||
for another purpose). These two options will *force* the use,
|
of BuDDy, even when a compatible version is already installed.
|
||||||
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.
|
|
||||||
|
|
||||||
--disable-python
|
--disable-python
|
||||||
Turn off the compilation of Python bindings. These bindings are
|
Turn off the compilation of Python bindings. These bindings are
|
||||||
|
|
@ -101,7 +108,7 @@ flags specific to Spot:
|
||||||
--enable-optimizations
|
--enable-optimizations
|
||||||
|
|
||||||
Here are the meaning of the fine-tuning options, in case
|
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
|
--disable-assert
|
||||||
--enable-assert
|
--enable-assert
|
||||||
|
|
@ -198,7 +205,6 @@ Third party software
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
buddy/ A patched version of BuDDy 2.3 (a BDD library).
|
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.
|
ltdl/ Libtool's portable dlopen() wrapper library.
|
||||||
lib/ Gnulib's portability modules.
|
lib/ Gnulib's portability modules.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,6 @@ AC_HEADER_TR1_UNORDERED_MAP
|
||||||
AC_HEADER_EXT_HASH_MAP
|
AC_HEADER_EXT_HASH_MAP
|
||||||
|
|
||||||
AX_CHECK_BUDDY
|
AX_CHECK_BUDDY
|
||||||
AX_CHECK_LBTT
|
|
||||||
AX_CHECK_GSPNLIB
|
AX_CHECK_GSPNLIB
|
||||||
AX_CHECK_BOOST([1.34], [103400])
|
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([LTL2NBA], [script4lbtt.py], [script4lbtt.py])
|
||||||
AC_CHECK_PROG([PERL], [perl], [perl])
|
AC_CHECK_PROG([PERL], [perl], [perl])
|
||||||
AC_CHECK_PROG([SPIN], [spin], [spin])
|
AC_CHECK_PROG([SPIN], [spin], [spin])
|
||||||
|
AC_CHECK_PROG([LBTT], [lbtt], [lbtt])
|
||||||
|
AC_CHECK_PROG([LBTT_TRANSLATE], [lbtt-translate], [lbtt-translate])
|
||||||
AX_CHECK_VALGRIND
|
AX_CHECK_VALGRIND
|
||||||
AC_CHECK_PROG([WRING2LBTT], [wring2lbtt], [wring2lbtt])
|
AC_CHECK_PROG([WRING2LBTT], [wring2lbtt], [wring2lbtt])
|
||||||
# Debian has a binary for SWIG 2.0 named swig2.0 and they kept swig as
|
# Debian has a binary for SWIG 2.0 named swig2.0 and they kept swig as
|
||||||
|
|
|
||||||
|
|
@ -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
22
lbtt/.gitignore
vendored
|
|
@ -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
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
Heikki Tauriainen <heikki.tauriainen@tkk.fi>
|
|
||||||
340
lbtt/COPYING
340
lbtt/COPYING
|
|
@ -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.
|
|
||||||
1332
lbtt/ChangeLog
1332
lbtt/ChangeLog
File diff suppressed because it is too large
Load diff
|
|
@ -1,2 +0,0 @@
|
||||||
SUBDIRS = doc src
|
|
||||||
ACLOCAL_AMFLAGS = -I m4
|
|
||||||
392
lbtt/NEWS
392
lbtt/NEWS
|
|
@ -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/>.
|
|
||||||
94
lbtt/README
94
lbtt/README
|
|
@ -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/>.
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
Makefile.in
|
|
||||||
Makefile
|
|
||||||
*.info*
|
|
||||||
texinfo.tex
|
|
||||||
14
lbtt/doc/.gitignore
vendored
14
lbtt/doc/.gitignore
vendored
|
|
@ -1,14 +0,0 @@
|
||||||
Makefile.in
|
|
||||||
Makefile
|
|
||||||
*.info*
|
|
||||||
texinfo.tex
|
|
||||||
*.cp
|
|
||||||
*.cps
|
|
||||||
*.fn
|
|
||||||
*.fns
|
|
||||||
*.ky
|
|
||||||
*.kys
|
|
||||||
*.pg
|
|
||||||
*.vr
|
|
||||||
*.vrs
|
|
||||||
*.tp
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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.
|
|
||||||
|
|
@ -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 |
|
|
@ -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 #
|
|
||||||
#################
|
|
||||||
5166
lbtt/doc/lbtt.texi
5166
lbtt/doc/lbtt.texi
File diff suppressed because it is too large
Load diff
|
|
@ -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 |
|
|
@ -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 #
|
|
||||||
######################### #########################
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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
20
lbtt/src/.gitignore
vendored
|
|
@ -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
|
|
||||||
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -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 */
|
|
||||||
|
|
@ -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 */
|
|
||||||
|
|
@ -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();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -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 */
|
|
||||||
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -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 */
|
|
||||||
|
|
@ -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; }
|
|
||||||
|
|
||||||
%%
|
|
||||||
|
|
@ -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();
|
|
||||||
}
|
|
||||||
|
|
@ -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
|
|
@ -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 */
|
|
||||||
|
|
@ -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();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -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 */
|
|
||||||
|
|
@ -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 */
|
|
||||||
1222
lbtt/src/Exception.h
1222
lbtt/src/Exception.h
File diff suppressed because it is too large
Load diff
|
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
@ -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 */
|
|
||||||
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -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 */
|
|
||||||
|
|
@ -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 */
|
|
||||||
2028
lbtt/src/Graph.h.in
2028
lbtt/src/Graph.h.in
File diff suppressed because it is too large
Load diff
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
@ -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 */
|
|
||||||
|
|
@ -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 */
|
|
||||||
|
|
@ -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 */
|
|
||||||
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -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
|
|
@ -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@
|
|
||||||
|
|
@ -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();
|
|
||||||
}
|
|
||||||
|
|
@ -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();
|
|
||||||
}
|
|
||||||
|
|
@ -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"
|
|
||||||
|
|
@ -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");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -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 */
|
|
||||||
|
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -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 */
|
|
||||||
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -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 */
|
|
||||||
2933
lbtt/src/Product.h
2933
lbtt/src/Product.h
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -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 */
|
|
||||||
|
|
@ -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
|
|
@ -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 ¤t_scc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ========================================================================= */
|
|
||||||
template<class EdgeContainer, class SccContainer, class Filter>
|
|
||||||
inline const SccContainer&
|
|
||||||
SccIterator<EdgeContainer, SccContainer, Filter>::operator++()
|
|
||||||
/* ----------------------------------------------------------------------------
|
|
||||||
*
|
|
||||||
* Description: Prefix increment operator for a SccIterator. Computes the
|
|
||||||
* next maximal strongly connected component of the graph and
|
|
||||||
* then returns it.
|
|
||||||
*
|
|
||||||
* Arguments: None.
|
|
||||||
*
|
|
||||||
* Returns: A collection of nodes representing some maximal strongly
|
|
||||||
* connected component.
|
|
||||||
*
|
|
||||||
* ------------------------------------------------------------------------- */
|
|
||||||
{
|
|
||||||
computeNextScc();
|
|
||||||
return current_scc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ========================================================================= */
|
|
||||||
template<class EdgeContainer, class SccContainer, class Filter>
|
|
||||||
inline const SccContainer
|
|
||||||
SccIterator<EdgeContainer, SccContainer, Filter>::operator++(int)
|
|
||||||
/* ----------------------------------------------------------------------------
|
|
||||||
*
|
|
||||||
* Description: Postfix increment operator for a SccIterator. Effectively
|
|
||||||
* returns the maximal strongly connected component of the graph
|
|
||||||
* currently pointed to by the iterator and then updates the
|
|
||||||
* iterator to point to the next strongly connected component.
|
|
||||||
*
|
|
||||||
* Arguments: None (the `int' is only required to distinguish this operator
|
|
||||||
* from the prefix increment operator).
|
|
||||||
*
|
|
||||||
* Returns: A collection of nodes representing some maximal strongly
|
|
||||||
* connected component.
|
|
||||||
*
|
|
||||||
* ------------------------------------------------------------------------- */
|
|
||||||
{
|
|
||||||
SccContainer old_scc = current_scc;
|
|
||||||
computeNextScc();
|
|
||||||
return old_scc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ========================================================================= */
|
|
||||||
template<class EdgeContainer, class SccContainer, class Filter>
|
|
||||||
inline bool SccIterator<EdgeContainer, SccContainer, Filter>::atEnd() const
|
|
||||||
/* ----------------------------------------------------------------------------
|
|
||||||
*
|
|
||||||
* Description: Tells whether there are still more strongly connected
|
|
||||||
* components in the graph for the iterator to process.
|
|
||||||
*
|
|
||||||
* Arguments: None.
|
|
||||||
*
|
|
||||||
* Returns: A truth value.
|
|
||||||
*
|
|
||||||
* ------------------------------------------------------------------------- */
|
|
||||||
{
|
|
||||||
return (current_node == graph.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
*
|
|
||||||
* Function definitions for template class
|
|
||||||
* SccIterator<EdgeContainer, SccContainer, Filter>.
|
|
||||||
*
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
/* ========================================================================= */
|
|
||||||
template<class EdgeContainer, class SccContainer, class Filter>
|
|
||||||
void SccIterator<EdgeContainer, SccContainer, Filter>::reset()
|
|
||||||
/* ----------------------------------------------------------------------------
|
|
||||||
*
|
|
||||||
* Description: Initializes the iterator to point to the first maximal
|
|
||||||
* strongly connected component of the graph with which the
|
|
||||||
* iterator it associated.
|
|
||||||
*
|
|
||||||
* Arguments: None.
|
|
||||||
*
|
|
||||||
* Returns: Nothing.
|
|
||||||
*
|
|
||||||
* ------------------------------------------------------------------------- */
|
|
||||||
{
|
|
||||||
dfs_number = 0;
|
|
||||||
|
|
||||||
for (typename vector<typename Graph<EdgeContainer>::size_type,
|
|
||||||
ALLOC(typename Graph<EdgeContainer>::size_type) >
|
|
||||||
::iterator node = dfs_ordering.begin();
|
|
||||||
node != dfs_ordering.end();
|
|
||||||
++node)
|
|
||||||
*node = 0;
|
|
||||||
|
|
||||||
while (!node_stack.empty())
|
|
||||||
node_stack.pop();
|
|
||||||
|
|
||||||
while (!scc_stack.empty())
|
|
||||||
scc_stack.pop();
|
|
||||||
|
|
||||||
current_scc.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ========================================================================= */
|
|
||||||
template<class EdgeContainer, class SccContainer, class Filter>
|
|
||||||
void SccIterator<EdgeContainer, SccContainer, Filter>::computeNextScc()
|
|
||||||
/* ----------------------------------------------------------------------------
|
|
||||||
*
|
|
||||||
* Description: Updates the state of the iterator to `point to' the next
|
|
||||||
* maximal strongly connected component of the graph, using the
|
|
||||||
* algorithm due to Tarjan [R. Tarjan. Depth-first search and
|
|
||||||
* linear graph algorithms. SIAM Journal on Computing,
|
|
||||||
* 1(2):146--160, June 1972] for computing the next maximal
|
|
||||||
* strongly connected component of the graph.
|
|
||||||
*
|
|
||||||
* Arguments: None.
|
|
||||||
*
|
|
||||||
* Returns: Nothing.
|
|
||||||
*
|
|
||||||
* ------------------------------------------------------------------------- */
|
|
||||||
{
|
|
||||||
current_scc.clear();
|
|
||||||
|
|
||||||
if (scc_stack.empty() && node_stack.empty())
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* If both `scc_stack' and `node_stack' are empty (this holds if we have
|
|
||||||
* recently finished processing some component of the graph), try to find
|
|
||||||
* a graph node that has not yet been visited. If no such node is found,
|
|
||||||
* all nodes have been visited and there are no more strongly connected
|
|
||||||
* components to be found in the graph.
|
|
||||||
*/
|
|
||||||
|
|
||||||
current_node = 0;
|
|
||||||
for (typename vector<typename Graph<EdgeContainer>::size_type,
|
|
||||||
ALLOC(typename Graph<EdgeContainer>::size_type) >
|
|
||||||
::const_iterator node = dfs_ordering.begin();
|
|
||||||
node != dfs_ordering.end() && (*node) != 0;
|
|
||||||
++node)
|
|
||||||
++current_node;
|
|
||||||
|
|
||||||
if (current_node == graph.size())
|
|
||||||
return;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Prepare to continue the depth-first search in the unvisited node.
|
|
||||||
*/
|
|
||||||
|
|
||||||
edge = graph[current_node].edges().begin();
|
|
||||||
|
|
||||||
scc_stack.push(current_node);
|
|
||||||
++dfs_number;
|
|
||||||
dfs_ordering[current_node] = lowlink[current_node] = dfs_number;
|
|
||||||
}
|
|
||||||
|
|
||||||
typename Graph<EdgeContainer>::size_type child_node;
|
|
||||||
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* If there are still nodes left in the depth-first search backtracking
|
|
||||||
* stack, pop a node and its next unprocessed outgoing edge off the stack.
|
|
||||||
* Before continuing the depth-first search in the popped node, update
|
|
||||||
* its lowlink value if necessary. (This has to be done if the lowlink of
|
|
||||||
* the current node---a successor of the popped node---is less than the
|
|
||||||
* lowlink of the popped node but not equal to zero.)
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!node_stack.empty())
|
|
||||||
{
|
|
||||||
typename Graph<EdgeContainer>::size_type father_node
|
|
||||||
= node_stack.top().first;
|
|
||||||
edge = node_stack.top().second;
|
|
||||||
node_stack.pop();
|
|
||||||
|
|
||||||
if (lowlink[current_node] < lowlink[father_node]
|
|
||||||
&& lowlink[current_node] != 0)
|
|
||||||
lowlink[father_node] = lowlink[current_node];
|
|
||||||
|
|
||||||
current_node = father_node;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Scan through the successors of the current node.
|
|
||||||
*
|
|
||||||
* If the current nodes has an unvisited successor node (a successor i
|
|
||||||
* with dfs_ordering[i] == 0), push the current node and its next
|
|
||||||
* unprocessed edge onto the backtracking stack and then continue the
|
|
||||||
* search in the successor node. Push also the successor node onto the
|
|
||||||
* strongly connected component stack.
|
|
||||||
*
|
|
||||||
* Otherwise, update the lowlink of the current node to the lowlink of
|
|
||||||
* its already visited successor if necessary.
|
|
||||||
*/
|
|
||||||
|
|
||||||
while (edge != graph[current_node].edges().end())
|
|
||||||
{
|
|
||||||
child_node = (*edge)->targetNode();
|
|
||||||
++edge;
|
|
||||||
|
|
||||||
if (dfs_ordering[child_node] == 0)
|
|
||||||
{
|
|
||||||
node_stack.push(make_pair(current_node, edge));
|
|
||||||
scc_stack.push(child_node);
|
|
||||||
|
|
||||||
++dfs_number;
|
|
||||||
dfs_ordering[child_node] = lowlink[child_node] = dfs_number;
|
|
||||||
|
|
||||||
current_node = child_node;
|
|
||||||
edge = graph[current_node].edges().begin();
|
|
||||||
}
|
|
||||||
else if (lowlink[child_node] < lowlink[current_node]
|
|
||||||
&& lowlink[child_node] != 0)
|
|
||||||
lowlink[current_node] = lowlink[child_node];
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If the least node in the depth-first search order reachable from the
|
|
||||||
* current node is the current node itself at the end of the previous
|
|
||||||
* loop, we have found a maximal strongly connected component of the
|
|
||||||
* graph. In this case, collect the states satisfying `cond' in the
|
|
||||||
* strongly connected component stack to form the component and exit.
|
|
||||||
* (Otherwise, return to the start of the outermost while loop and
|
|
||||||
* continue by popping a state off the depth-first search backtracking
|
|
||||||
* stack.)
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (dfs_ordering[current_node] == lowlink[current_node])
|
|
||||||
{
|
|
||||||
do
|
|
||||||
{
|
|
||||||
child_node = scc_stack.top();
|
|
||||||
scc_stack.pop();
|
|
||||||
if (cond(&graph[child_node]))
|
|
||||||
current_scc.insert(child_node);
|
|
||||||
lowlink[child_node] = 0;
|
|
||||||
}
|
|
||||||
while (child_node != current_node);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
*
|
|
||||||
* Inline function definitions for template class NullSccFilter<EdgeContainer>.
|
|
||||||
*
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
/* ========================================================================= */
|
|
||||||
template<class EdgeContainer>
|
|
||||||
inline bool NullSccFilter<EdgeContainer>::operator()
|
|
||||||
(const typename Graph<EdgeContainer>::Node*) const
|
|
||||||
/* ----------------------------------------------------------------------------
|
|
||||||
*
|
|
||||||
* Description: Default test for filtering the nodes in a strongly connected
|
|
||||||
* graph component. The default is to simply include all nodes
|
|
||||||
* in the result.
|
|
||||||
*
|
|
||||||
* Arguments: A constant pointer to a Graph<EdgeContainer>::Node (required
|
|
||||||
* only to satisfy the class interface requirements).
|
|
||||||
*
|
|
||||||
* Returns: true, so the test will succeed for every node in the
|
|
||||||
* component.
|
|
||||||
*
|
|
||||||
* ------------------------------------------------------------------------- */
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* !SCCITERATOR_H */
|
|
||||||
|
|
@ -1,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 */
|
|
||||||
|
|
@ -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());
|
|
||||||
}
|
|
||||||
|
|
@ -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 */
|
|
||||||
|
|
@ -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 */
|
|
||||||
}
|
|
||||||
|
|
@ -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
|
|
@ -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 */
|
|
||||||
|
|
@ -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();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -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 */
|
|
||||||
|
|
@ -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 */
|
|
||||||
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -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 */
|
|
||||||
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -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 */
|
|
||||||
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
@ -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
|
|
@ -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 */
|
|
||||||
|
|
@ -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 */
|
|
||||||
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -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 */
|
|
||||||
|
|
@ -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 */
|
|
||||||
|
|
@ -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) + ").");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -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
|
|
@ -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 */
|
|
||||||
1055
lbtt/src/getopt.c
1055
lbtt/src/getopt.c
File diff suppressed because it is too large
Load diff
|
|
@ -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
Loading…
Add table
Add a link
Reference in a new issue