From e2f17f65b89253b6784538d9da5920a8a31d4373 Mon Sep 17 00:00:00 2001 From: Alexandre Duret-Lutz Date: Sat, 27 Oct 2012 20:11:55 +0200 Subject: [PATCH] Remove LBTT. * configure.ac: Detect lbtt using AC_CHECK_PROG. * m4/lbtt.m4: Delete. * lbtt/: Remove directory. * Makefile.am, README: Adjust. --- Makefile.am | 6 +- README | 46 +- configure.ac | 3 +- lbtt/.cvsignore | 22 - lbtt/.gitignore | 22 - lbtt/AUTHORS | 1 - lbtt/COPYING | 340 -- lbtt/ChangeLog | 1332 -------- lbtt/Makefile.am | 2 - lbtt/NEWS | 392 --- lbtt/README | 94 - lbtt/configure.ac | 221 -- lbtt/doc/.cvsignore | 4 - lbtt/doc/.gitignore | 14 - lbtt/doc/Makefile.am | 3 - lbtt/doc/gpl.texi | 394 --- lbtt/doc/intersectioncheck.eps | 747 ----- lbtt/doc/intersectioncheck.png | Bin 14956 -> 0 bytes lbtt/doc/intersectioncheck.txt | 56 - lbtt/doc/lbtt.texi | 5166 ------------------------------ lbtt/doc/testprocedure.eps | 769 ----- lbtt/doc/testprocedure.png | Bin 14430 -> 0 bytes lbtt/doc/testprocedure.txt | 55 - lbtt/m4/intel.m4 | 52 - lbtt/src/.cvsignore | 15 - lbtt/src/.gitignore | 20 - lbtt/src/BitArray.cc | 453 --- lbtt/src/BitArray.h | 432 --- lbtt/src/Bitset.h | 626 ---- lbtt/src/BuchiAutomaton.cc | 880 ----- lbtt/src/BuchiAutomaton.h | 925 ------ lbtt/src/BuchiProduct.cc | 96 - lbtt/src/BuchiProduct.h | 510 --- lbtt/src/Config-lex.ll | 130 - lbtt/src/Config-parse.y | 663 ---- lbtt/src/Config-parse_.cc | 16 - lbtt/src/Configuration.cc | 2192 ------------- lbtt/src/Configuration.h | 784 ----- lbtt/src/DispUtil.cc | 179 -- lbtt/src/DispUtil.h | 159 - lbtt/src/EdgeContainer.h | 28 - lbtt/src/Exception.h | 1222 ------- lbtt/src/ExternalTranslator.cc | 137 - lbtt/src/ExternalTranslator.h | 309 -- lbtt/src/FormulaRandomizer.cc | 229 -- lbtt/src/FormulaRandomizer.h | 329 -- lbtt/src/FormulaWriter.h | 450 --- lbtt/src/Graph.h.in | 2028 ------------ lbtt/src/IntervalList.cc | 186 -- lbtt/src/IntervalList.h | 500 --- lbtt/src/LbtWrapper.h | 135 - lbtt/src/LbttAlloc.h | 161 - lbtt/src/Ltl-parse.y | 610 ---- lbtt/src/Ltl-parse_.cc | 16 - lbtt/src/LtlFormula.cc | 1126 ------- lbtt/src/LtlFormula.h | 2642 --------------- lbtt/src/Makefile.am | 92 - lbtt/src/NeverClaim-lex.ll | 188 -- lbtt/src/NeverClaim-parse.y | 301 -- lbtt/src/NeverClaim-parse_.cc | 16 - lbtt/src/NeverClaimAutomaton.cc | 317 -- lbtt/src/NeverClaimAutomaton.h | 455 --- lbtt/src/PathEvaluator.cc | 986 ------ lbtt/src/PathEvaluator.h | 165 - lbtt/src/PathIterator.cc | 198 -- lbtt/src/PathIterator.h | 204 -- lbtt/src/Product.h | 2933 ----------------- lbtt/src/ProductAutomaton.cc | 1063 ------ lbtt/src/ProductAutomaton.h | 596 ---- lbtt/src/Random.h | 96 - lbtt/src/SccCollection.h | 1172 ------- lbtt/src/SccIterator.h | 752 ----- lbtt/src/SharedTestData.h | 55 - lbtt/src/SpinWrapper.cc | 119 - lbtt/src/SpinWrapper.h | 122 - lbtt/src/SpotWrapper.cc | 102 - lbtt/src/SpotWrapper.h | 143 - lbtt/src/StatDisplay.cc | 1636 ---------- lbtt/src/StatDisplay.h | 108 - lbtt/src/StateSpace.cc | 454 --- lbtt/src/StateSpace.h | 450 --- lbtt/src/StateSpaceProduct.h | 430 --- lbtt/src/StateSpaceRandomizer.cc | 285 -- lbtt/src/StateSpaceRandomizer.h | 154 - lbtt/src/StringUtil.cc | 586 ---- lbtt/src/StringUtil.h | 352 -- lbtt/src/TempFsysName.cc | 125 - lbtt/src/TempFsysName.h | 157 - lbtt/src/TestOperations.cc | 1917 ----------- lbtt/src/TestOperations.h | 534 --- lbtt/src/TestRoundInfo.h | 251 -- lbtt/src/TestStatistics.cc | 96 - lbtt/src/TestStatistics.h | 581 ---- lbtt/src/TranslatorInterface.h | 91 - lbtt/src/UserCommandReader.cc | 940 ------ lbtt/src/UserCommandReader.h | 174 - lbtt/src/UserCommands.cc | 2019 ------------ lbtt/src/UserCommands.h | 151 - lbtt/src/getopt.c | 1055 ------ lbtt/src/getopt1.c | 188 -- lbtt/src/gnu-getopt.h | 180 -- lbtt/src/main.cc | 819 ----- lbtt/src/translate.cc | 267 -- lbtt/src/translate.h | 39 - m4/lbtt.m4 | 40 - 105 files changed, 29 insertions(+), 52054 deletions(-) delete mode 100644 lbtt/.cvsignore delete mode 100644 lbtt/.gitignore delete mode 100644 lbtt/AUTHORS delete mode 100644 lbtt/COPYING delete mode 100644 lbtt/ChangeLog delete mode 100644 lbtt/Makefile.am delete mode 100644 lbtt/NEWS delete mode 100644 lbtt/README delete mode 100644 lbtt/configure.ac delete mode 100644 lbtt/doc/.cvsignore delete mode 100644 lbtt/doc/.gitignore delete mode 100644 lbtt/doc/Makefile.am delete mode 100644 lbtt/doc/gpl.texi delete mode 100644 lbtt/doc/intersectioncheck.eps delete mode 100644 lbtt/doc/intersectioncheck.png delete mode 100644 lbtt/doc/intersectioncheck.txt delete mode 100644 lbtt/doc/lbtt.texi delete mode 100644 lbtt/doc/testprocedure.eps delete mode 100644 lbtt/doc/testprocedure.png delete mode 100644 lbtt/doc/testprocedure.txt delete mode 100644 lbtt/m4/intel.m4 delete mode 100644 lbtt/src/.cvsignore delete mode 100644 lbtt/src/.gitignore delete mode 100644 lbtt/src/BitArray.cc delete mode 100644 lbtt/src/BitArray.h delete mode 100644 lbtt/src/Bitset.h delete mode 100644 lbtt/src/BuchiAutomaton.cc delete mode 100644 lbtt/src/BuchiAutomaton.h delete mode 100644 lbtt/src/BuchiProduct.cc delete mode 100644 lbtt/src/BuchiProduct.h delete mode 100644 lbtt/src/Config-lex.ll delete mode 100644 lbtt/src/Config-parse.y delete mode 100644 lbtt/src/Config-parse_.cc delete mode 100644 lbtt/src/Configuration.cc delete mode 100644 lbtt/src/Configuration.h delete mode 100644 lbtt/src/DispUtil.cc delete mode 100644 lbtt/src/DispUtil.h delete mode 100644 lbtt/src/EdgeContainer.h delete mode 100644 lbtt/src/Exception.h delete mode 100644 lbtt/src/ExternalTranslator.cc delete mode 100644 lbtt/src/ExternalTranslator.h delete mode 100644 lbtt/src/FormulaRandomizer.cc delete mode 100644 lbtt/src/FormulaRandomizer.h delete mode 100644 lbtt/src/FormulaWriter.h delete mode 100644 lbtt/src/Graph.h.in delete mode 100644 lbtt/src/IntervalList.cc delete mode 100644 lbtt/src/IntervalList.h delete mode 100644 lbtt/src/LbtWrapper.h delete mode 100644 lbtt/src/LbttAlloc.h delete mode 100644 lbtt/src/Ltl-parse.y delete mode 100644 lbtt/src/Ltl-parse_.cc delete mode 100644 lbtt/src/LtlFormula.cc delete mode 100644 lbtt/src/LtlFormula.h delete mode 100644 lbtt/src/Makefile.am delete mode 100644 lbtt/src/NeverClaim-lex.ll delete mode 100644 lbtt/src/NeverClaim-parse.y delete mode 100644 lbtt/src/NeverClaim-parse_.cc delete mode 100644 lbtt/src/NeverClaimAutomaton.cc delete mode 100644 lbtt/src/NeverClaimAutomaton.h delete mode 100644 lbtt/src/PathEvaluator.cc delete mode 100644 lbtt/src/PathEvaluator.h delete mode 100644 lbtt/src/PathIterator.cc delete mode 100644 lbtt/src/PathIterator.h delete mode 100644 lbtt/src/Product.h delete mode 100644 lbtt/src/ProductAutomaton.cc delete mode 100644 lbtt/src/ProductAutomaton.h delete mode 100644 lbtt/src/Random.h delete mode 100644 lbtt/src/SccCollection.h delete mode 100644 lbtt/src/SccIterator.h delete mode 100644 lbtt/src/SharedTestData.h delete mode 100644 lbtt/src/SpinWrapper.cc delete mode 100644 lbtt/src/SpinWrapper.h delete mode 100644 lbtt/src/SpotWrapper.cc delete mode 100644 lbtt/src/SpotWrapper.h delete mode 100644 lbtt/src/StatDisplay.cc delete mode 100644 lbtt/src/StatDisplay.h delete mode 100644 lbtt/src/StateSpace.cc delete mode 100644 lbtt/src/StateSpace.h delete mode 100644 lbtt/src/StateSpaceProduct.h delete mode 100644 lbtt/src/StateSpaceRandomizer.cc delete mode 100644 lbtt/src/StateSpaceRandomizer.h delete mode 100644 lbtt/src/StringUtil.cc delete mode 100644 lbtt/src/StringUtil.h delete mode 100644 lbtt/src/TempFsysName.cc delete mode 100644 lbtt/src/TempFsysName.h delete mode 100644 lbtt/src/TestOperations.cc delete mode 100644 lbtt/src/TestOperations.h delete mode 100644 lbtt/src/TestRoundInfo.h delete mode 100644 lbtt/src/TestStatistics.cc delete mode 100644 lbtt/src/TestStatistics.h delete mode 100644 lbtt/src/TranslatorInterface.h delete mode 100644 lbtt/src/UserCommandReader.cc delete mode 100644 lbtt/src/UserCommandReader.h delete mode 100644 lbtt/src/UserCommands.cc delete mode 100644 lbtt/src/UserCommands.h delete mode 100644 lbtt/src/getopt.c delete mode 100644 lbtt/src/getopt1.c delete mode 100644 lbtt/src/gnu-getopt.h delete mode 100644 lbtt/src/main.cc delete mode 100644 lbtt/src/translate.cc delete mode 100644 lbtt/src/translate.h delete mode 100644 m4/lbtt.m4 diff --git a/Makefile.am b/Makefile.am index 28492cf53..84d16ccfd 100644 --- a/Makefile.am +++ b/Makefile.am @@ -23,9 +23,6 @@ if WITH_INCLUDED_BUDDY MAYBE_BUDDY = buddy endif WITH_INCLUDED_BUDDY -if WITH_INCLUDED_LBTT - MAYBE_LBTT = lbtt -endif WITH_INCLUDED_LBTT if NEVER # For Automake a conditional directory # is conditionally built, but unconditionally distributed. @@ -34,8 +31,7 @@ if NEVER NEVER_BENCH = bench endif -SUBDIRS = $(MAYBE_BUDDY) $(MAYBE_LBTT) \ - $(NEVER_BENCH) doc lib src wrap ltdl iface +SUBDIRS = $(MAYBE_BUDDY) $(NEVER_BENCH) doc lib src wrap ltdl iface UTF8 = utf8/doc/ReleaseNotes utf8/doc/utf8cpp.html utf8/utf8.h \ utf8/utf8/checked.h utf8/utf8/core.h utf8/utf8/unchecked.h diff --git a/README b/README index e38bddfaf..5e6f249ad 100644 --- a/README +++ b/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 the --disable-python option (see below). -Spot also uses modified versions of BuDDy (a binary decision diagram), -and LBTT (an LTL to Büchi test bench). You do not need to install -these yourself: they are included in this package (directories buddy/ -and lbtt/) and will be built and installed alongside of Spot. +The Boost libraries should also be installed. + + +Third-party dependencies +------------------------ + +Spot also uses a modified version of BuDDy (a binary decision diagram +library), that is already included in the buddy/ directory. So you +do not need to install it yourself. + +Spot used to distribute a modified version of LBTT (an LTL to Büchi +test bench), mostly fixing errors reported by recent compilers. +However Spot now distributes its own reimplementation of LBTT, called +ltlcross, so the use of LBTT is completely optional. The last +modified version of LBTT we used to distribute can now be found at + http://spot.lip6.fr/dl/lbtt-1.2.1a.tar.gz +If some lbtt binary is found on your system, it will be used in the +test suite in addition to ltlcross. Building and installing @@ -60,20 +74,13 @@ flags specific to Spot: CVS repository hosted by the Università di Torino. --with-included-buddy - --with-included-lbtt - After you have installed Spot the first time, LBTT and a modified - version of BuDDy will be installed. The next time you reconfigure - Spot, configure will detect that these versions are already - installed, and will attempt to use these installed versions - directly (this is in case you had to modify one of these yourself - for another purpose). These two options will *force* the use, - build, and installation of the included versions of these package, - even when compatible versions are already installed. - - --without-included-lbtt - Explicitly Turn off the configuration and compilation of LBTT. - This is required on systems (such as MinGW) where LBTT does not - compile. + After you have installed Spot the first time, a modified version + of BuDDy will be installed. The next time you reconfigure Spot, + configure will detect that this version is already installed, and + will attempt to use it directly (this is in case you had to modify + one of these yourself for another purpose). This option will + *force* the use, build, and installation of the included version + of BuDDy, even when a compatible version is already installed. --disable-python Turn off the compilation of Python bindings. These bindings are @@ -101,7 +108,7 @@ flags specific to Spot: --enable-optimizations Here are the meaning of the fine-tuning options, in case -enable/disable-devel is not enough. +--enable/disable-devel is not enough. --disable-assert --enable-assert @@ -198,7 +205,6 @@ Third party software -------------------- buddy/ A patched version of BuDDy 2.3 (a BDD library). -lbtt/ lbtt 1.2.1a (an LTL to Büchi automata test bench). ltdl/ Libtool's portable dlopen() wrapper library. lib/ Gnulib's portability modules. diff --git a/configure.ac b/configure.ac index 5dc9667c3..b7633d0bd 100644 --- a/configure.ac +++ b/configure.ac @@ -65,7 +65,6 @@ AC_HEADER_TR1_UNORDERED_MAP AC_HEADER_EXT_HASH_MAP AX_CHECK_BUDDY -AX_CHECK_LBTT AX_CHECK_GSPNLIB AX_CHECK_BOOST([1.34], [103400]) @@ -96,6 +95,8 @@ AC_CHECK_PROG([MODELLA], [modella], [modella]) AC_CHECK_PROG([LTL2NBA], [script4lbtt.py], [script4lbtt.py]) AC_CHECK_PROG([PERL], [perl], [perl]) AC_CHECK_PROG([SPIN], [spin], [spin]) +AC_CHECK_PROG([LBTT], [lbtt], [lbtt]) +AC_CHECK_PROG([LBTT_TRANSLATE], [lbtt-translate], [lbtt-translate]) AX_CHECK_VALGRIND AC_CHECK_PROG([WRING2LBTT], [wring2lbtt], [wring2lbtt]) # Debian has a binary for SWIG 2.0 named swig2.0 and they kept swig as diff --git a/lbtt/.cvsignore b/lbtt/.cvsignore deleted file mode 100644 index 04b16848d..000000000 --- a/lbtt/.cvsignore +++ /dev/null @@ -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 diff --git a/lbtt/.gitignore b/lbtt/.gitignore deleted file mode 100644 index 04b16848d..000000000 --- a/lbtt/.gitignore +++ /dev/null @@ -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 diff --git a/lbtt/AUTHORS b/lbtt/AUTHORS deleted file mode 100644 index 5fd9b83c0..000000000 --- a/lbtt/AUTHORS +++ /dev/null @@ -1 +0,0 @@ -Heikki Tauriainen diff --git a/lbtt/COPYING b/lbtt/COPYING deleted file mode 100644 index d60c31a97..000000000 --- a/lbtt/COPYING +++ /dev/null @@ -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. - - - Copyright (C) - - 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. - - , 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. diff --git a/lbtt/ChangeLog b/lbtt/ChangeLog deleted file mode 100644 index edd44909f..000000000 --- a/lbtt/ChangeLog +++ /dev/null @@ -1,1332 +0,0 @@ -2012-06-27 Alexandre Duret-Lutz - - Fix issues reported by Clang++ 3.1. - - * src/Graph.h.in (PathElement::hasEdge): Check the correct - pointer, not the address of some member function. - * src/BuchiAutomaton.cc, src/Configuration.cc, - src/TestOperations.cc, src/TestOperations.hh: Recode these files in - utf-8. - -2012-06-19 Alexandre Duret-Lutz - - Adjust parsers to accommodate old and new versions of Automake. - - * src/Config-parse.yy, src/Ltl-parse.yy, src/NeverClaim-parse.yy: - Rename these as.. - * src/Config-parse.y, src/Ltl-parse.y, src/NeverClaim-parse.y: - ... these. - * src/Config-parse_.cc, src/Ltl-parse_.cc, - src/NeverClaim-parse_.cc: New files to hack around - incompatibilities between Automake 1.12 and Automake 1.11. - * src/Makefile.am: Adjust. - * NEWS: Mention this change. - -2012-05-21 Alexandre Duret-Lutz - - Make it clearer this is not LBTT 1.2.1. - - * configure.ac: Bump the version number to 1.2.1a. - * NEWS: Summarize all changes since 1.2.1. - * README: Warn this is not 1.2.1, and add pointers to NEWS and - ChangeLog. - -2012-05-21 Tomáš Babiak - - Count deterministic automata and deterministic states. - - * src/BuchiAutomaton.h, src/BuchiAutomaton.cc - (BuchiState::isDeterministic, BuchiAutomaton::isDeterministic, - BuchiAutomaton::nondeterminismIndex): New methods. - * src/TestOperations.cc (generateBuchiAutomaton): Collect - nondeterminism indices, and count deterministic automata. - * src/TestStatistics.cc, src/TestStatistics.h: Add storage - for these statistics. - * src/StatDisplay.cc (printBuchiAutomatonStats, - printCollectiveStats): Display these statistics. - -2012-04-27 Alexandre Duret-Lutz - - * doc/gpl.texi: Fix make pdf for newer texinfo.tex. - -2012-04-27 Alexandre Duret-Lutz - - * configure.ac: Do not check for mkstemp(), it is not used. - -2010-04-07 Alexandre Duret-Lutz - - Accept W and M in lbtt-translate --spot. - - * src/SpotWrapper.cc: Translate W and M operators. - -2010-01-22 Alexandre Duret-Lutz - - Let "make dvi" work on Ubuntu. - - * doc/lbtt.texi (The formula generation algorithm): Use op^\prime - instead of op', because etex on Ubuntu hangs (an infinite loop?) - on the later when texi2dvi tries to compile a dvi. - -2010-01-21 Alexandre Duret-Lutz - - Kill some warnings on Ubuntu. - - * src/UserCommandReader.cc (UserCommandInterface): Explicitly - ignore the return code of system() to kill a warning. - * src/TestOperations.cc (generateBuchiAutomaton): Explicitly - ignore the return code of write() to kill a warning. - -2010-01-16 Guillaume Sadegh - - Add a missing include. - - * src/translate.cc: exit(2) requires cstdlib. - -2009-11-26 Alexandre Duret-Lutz - - Fix generation of random formulae on 64bits systems. - - * src/main.cc (testLoop): Generate random short ints between 0 and - SHRT_MAX, not between 0 and LONG_MAX. On systems where long ints - are 64bits, LRAND(0,LONG_MAX) was returning a value with the lower - 32 bits set to 0, and the latter truncation to short int always - yielded the value 0. Consequently all generated formulae were - identical... - -2009-11-25 Alexandre Duret-Lutz - - * src/Configuration.cc (registerAlgorithm): Do not complain about - a missing path for disabled algorithms. - -2009-06-12 Guillaume Sadegh - - Adjust to support the Intel compiler (icpc). - - * configure.ac: Adjust to call... - * m4/intel.m4: ...this new macro. - * Makefile.am: Add the directory `m4' as an includedir of - autoconf's macros. - -2009-05-31 Alexandre Duret-Lutz - - Adjust parser to Bison 2.4.1. - - * src/Config-parse.yy (yyerror): Move to the end of the file, to - please newer versions of Bison. With Bison 2.4.1 the various - token used by yyerror() are now defined only after the first - %{...%} block has been emitted (in which yyerror() was previously - defined). - -2008-03-13 Alexandre Duret-Lutz - - * src/main.cc: Include for LONG_MAX. lbtt won't - compile with g++-4.3 otherwise. - * src/Ltl-parse.yy (matchCharactersFromStream): Declare the chars - as const to kill a g++ warning. - * src/NeverClaim-parse.yy (yyerror): Declare the error - message as const to kill a g++ warning. - -2005-08-30 Heikki Tauriainen - - * src/main.cc: [HAVE_ISATTY && HAVE_UNISTD_H]: Include the - unistd.h header. - (testLoop): Add support for reading LTL formulas from standard - input using the new variable `round_info.formula_input_stream'. - (main) [HAVE_ISATTY]: If formulas are to be read from the - standard input which is not a terminal, force lbtt to work in - non-interactive mode. - * src/TestOperations.cc (generateFormula): - Use `round_info.formula_input_stream' instead of - `round_info.formula_input_file'. - * src/TestRoundInfo.h (TestRoundInfo::formula_input_stream): New - variable. - * src/Configuration.cc (Configuration::showCommandLineHelp): - Update description of the --formulafile command line option. - (Configuration::print): Do not display a file name when reading - formulas from standard input. - - * src/SpotWrapper.h, src/SpotWrapper.cc: Merge files from - Spot 0.2 (contributed by Alexandre Duret-Lutz); remove #pragma - definitions. - * src/ExternalTranslator.h, src/Makefile.in, src/translate.cc: - Merge changes from Spot 0.2 (contributed by Alexandre Duret-Lutz). - - * doc/lbtt.texi: Fix typo in URL of the FormulaOptions block - generator. Update version, add documentation and references about - support for Spot. Describe the new semantics of the --formulafile - command line option. - - * NEWS, README, configure.ac: Update. - - * Version 1.2.0 released. - -2005-08-18 Heikki Tauriainen - - * NEWS, README: Update to next version. - - * Version 1.1.3 released. - -2005-08-18 Heikki Tauriainen - - * src/TestOperations.cc (generateBuchiAutomaton): Do not - block interrupt signals while running a child process; if lbtt - is currently in the foreground, transfer the controlling terminal - to the child instead. - * configure.ac: Add tests for the getpgrp, tcgetpgrp and - tcsetpgrp functions. - -2005-08-17 Heikki Tauriainen - - * src/BitArray.h (BitArray::set, BitArray::clear): Do not - set/clear more bits than specified. - - * src/main.cc (main): Add a space before error message. - -2005-08-16 Heikki Tauriainen - - * src/main.cc: Include the sys/types.h header. - (translator_process): New global variable. - (abortHandler): If a translator process is still active when - aborting, terminate it. - * src/TestOperations.cc: Declare the external translator_process - variable. - (generateBuchiAutomaton): Replace the pid variable with the - translator_process variable. - Use setpgid instead of setsid. Always try to terminate the - subprocess if waitpid fails (not only in case of timeouts). - * configure.ac: Replace test for setsid with test for - setpgid. - -2005-08-15 Heikki Tauriainen - - * configure.ac: Update version and e-mail address. - Remove test for the slist header. - - * AUTHORS, doc/lbtt.texi: Update e-mail address. - - * src/LbttAlloc.h: Remove definition for the ALLOC macro. - Update copyright information. - * src/BuchiAutomaton.cc, src/BuchiProduct.cc, src/BuchiProduct.h, - src/Configuration.cc, src/Configuration.h, src/DispUtil.cc, - src/ExternalTranslator.h, src/FormulaRandomizer.cc, - src/FormulaRandomizer.h, src/Graph.h.in, src/IntervalList.cc, - src/IntervalList.h, src/Ltl-parse.yy, src/LtlFormula.cc, - src/LtlFormula.h, src/main.cc, src/NeverClaimAutomaton.cc, - src/NeverClaimAutomaton.h, src/PathEvaluator.cc, - src/PathEvaluator.h, src/Product.h, src/SccCollection.h, - src/SharedTestData.h, src/StatDisplay.cc, src/StatDisplay.h, - src/StateSpace.cc, src/StateSpaceRandomizer.cc, - src/StringUtil.cc, src/StringUtil.h, src/TestOperations.cc, - src/TestOperations.h, src/TestRoundInfo.h, src/TestStatistics.cc, - src/TestStatistics.h, src/UserCommandReader.cc, - src/UserCommandReader.h, src/UserCommands.cc, - src/UserCommands.h: - Remove uses of the ALLOC macro. - Update copyright information. - * src/BitArray.cc, src/BitArray.h, src/Bitset.h, - src/BuchiAutomaton.h, src/Config-lex.ll, src/Config-parse.yy, - src/DispUtil.h, src/EdgeContainer.h, src/Exception.h, - src/ExternalTranslator.cc, src/FormulaWriter.h, src/LbtWrapper.h, - src/NeverClaim-lex.ll, src/NeverClaim-parse.yy, - src/PathIterator.cc, src/PathIterator.h, src/Random.h, - src/SpinWrapper.cc, src/SpinWrapper.h, src/StateSpace.h, - src/StateSpaceProduct.h, src/StateSpaceRandomizer.h, - src/TempFsysName.cc, src/TempFsysName.h, src/translate.cc, - src/translate.h, src/TranslatorInterface.h: - Update copyright information. - - * src/Configuration.cc (Configuration::showCommandLineHelp): - Use the PACKAGE_BUGREPORT macro instead of a hard-coded - e-mail address. - -2004-08-02 Heikki Tauriainen - - * Version 1.1.2 released. - -2004-08-01 Heikki Tauriainen - - * src/TestOperations.cc (generateBuchiAutomaton): Use - process groups to terminate the child process along with - all of its children (if any) on timeouts. - Do not write the time elapsed before a timeout into the - log file. - - * configure.ac: Add test for the setsid library function. - -2004-07-31 Heikki Tauriainen - - * src/Product.h (ProductEdge::edge_1, ProductEdge::edge_2): - Change type to GraphEdgeContainer::const_iterators to move all - edge dereference operations to member functions instead of the - class constructor (where dereferencing is not always safe). - (ProductEdge::ProductEdge, ProductEdge::firstComponent) - (ProductEdge::secondComponent, ProductEdge::targetNode): - Change member initialization and access accordingly. - - * configure.ac, NEWS, README: Update version. - -2004-07-30 Heikki Tauriainen - - * Version 1.1.1 released. - -2004-07-30 Heikki Tauriainen - - * src/TestOperations.cc (generateBuchiAutomaton): Protect - against referencing a null pointer returned by strsignal on - some platforms. - (performBuchiIntersectionCheck): Handle product size - exceptions gracefully. Skip redundant writes to an unopened - transcript file. - - * configure.ac: Update version. - * NEWS: Update. - * README: Update. - -2004-07-16 Alexandre Duret-Lutz - - * configure.ac: Call AC_GNU_SOURCE to make glibc's strsignal - definition visible even to non-GNU compilers. - -2004-07-07 Heikki Tauriainen - - * Version 1.1.0 released. - -2004-07-06 Heikki Tauriainen - - * configure.ac: Make detection of the need for obstack.h - compilation workaround with glibc 2.3.2 more accurate. - Remove check for single_client_alloc. - * src/LbttAlloc.h: Remove conditional definition of - the ALLOC macro. - * src/UserCommandReader.cc: Remove workaround for - compilation with gcc 2.95. - -2004-07-02 Heikki Tauriainen - - * doc/texinfo.tex: New upstream version. - * doc/lbtt.texi: Update to edition 1.1.0. - * NEWS: Update. - -2004-07-02 Heikki Tauriainen - - * src/UserCommandReader.cc (parseCommand): Recognize - `implementations' and `translators' as aliases of the - `algorithms' command. - * src/UserCommands.cc (printCommandHelp): List - `implementations' and `translators' as aliases of the - `algorithms' command. - -2004-06-30 Heikki Tauriainen - - * src/Configuration.h (CommandLineOptionType): Rearrange the - values to list constants with an explicit character value - first. Change the value of OPT_VERSION to `V'. - * src/Configuration.cc (Configuration::read): Treat the single- - character option `V' as an alias of the `--version' option. - (Configuration::showCommandLineHelp): Describe the `-V' option. - * src/translate.cc (main): Rename the single character option - `v' to `V'. - -2004-06-29 Heikki Tauriainen - - * src/BuchiAutomaton.h (BuchiAutomaton::regularize) - (BuchiAutomaton::intersect): Remove. - (BuchiAutomaton::BuchiTransition::print(_, _, _)): Override - the corresponding virtual function in parent class explicitly. - * src/BuchiAutomaton.cc (BuchiAutomaton::regularize) - (BuchiAutomaton::intersect): Remove. - -2004-05-31 Heikki Tauriainen - - * src/LtlFormula.h: Do not include the map header. Include the - set header instead. - (LtlFormula::refcount): New variable. - (LtlFormula::formula_storage): Change type to a set of - pointers to LtlFormulas. - (LtlFormula::LtlFormula): Initialize `this->refcount' to 1. Do - not initialize `info_flags' explicitly (this is always done in - subclasses). - (LtlFormula::destruct): Update the reference counts of formulas - directly. - (LtlFormula::clone, LtlFormula::insertToStorage): Likewise. - (Atom::Atom): Do not call parent class constructor explicitly. - (UnaryFormula::UnaryFormula): Likewise. - (BinaryFormula::BinaryFormula): Likewise. - * src/LtlFormula.cc: Update definition of the static member - `LtlFormula::formula_storage'. - * src/FormulaRandomizer.h: Include the map header. - -2004-05-19 Heikki Tauriainen - - * configure.ac (BIGUINT): Define as unsigned long long int - if the compiler supports it (unsigned long int otherwise). - * src/TestStatistics.h - (TestStatistics::total_number_of_buchi_states) - (TestStatistics::total_number_of_buchi_transitions) - (TestStatistics::total_number_of_acceptance_sets) - (TestStatistics::total_number_of_product_states) - (TestStatistics::total_number_of_product_transitions): - Change type to BIGUINT. - (TestStatistics::total_number_of_msccs): Remove. - (TestStatistics::TestStatistics): Remove initialization - of `total_number_of_msccs'. - * src/StatDisplay.cc (printCollectiveStats): Use BIGUINTs - for referencing total state, transition and acceptance set - counts. - -2004-05-18 Heikki Tauriainen - - * src/ProductAutomaton.h, src/ProductAutomaton.cc, - src/SccIterator.h: Remove. The functionality provided by - these files has been rearranged into more general product - computation and emptiness checking routines in: - * src/Product.h, src/SccCollection.h: New files. - * src/BuchiProduct.h, src/BuchiProduct.cc, src/StateSpaceProduct.h: - New files for providing specializations of the general product - computation operation applicable to Büchi automata and state - spaces. - - * src/Makefile.am: Add BuchiProduct.h, BuchiProduct.cc, - Product.h, SccCollection.h and StateSpaceProduct.h to - lbtt_SOURCES. - Remove ProductAutomaton.h, ProductAutomaton.cc and - SccIterator.h from lbtt_SOURCES. - - * src/Graph.h.in (Graph::EdgeContainerType, Graph::Path): New - type definitions. - (Graph::PathElement): New class. - - * src/PathEvaluator.h (evaluate): Change prototype to accept - a path prefix and a cycle as parameters. - * src/PathEvaluator.cc (evaluate): Rewrite to support the - changed prototype. - - * src/TestRoundInfo.h: Do not include the ProductAutomaton.h - header. - (TestRoundInfo::product_automaton): Remove. - (TestRoundInfo::TestRoundInfo): Remove initialization of - `product_automaton'. - - * src/TestStatistics.h: Do not include the ProductAutomaton.h - header. Include the EdgeContainer.h and Graph.h headers. - (AutomatonStats::number_of_product_states): Change type to - Graph::size_type. - - * src/main.cc (testLoop): Remove references to - `round_info.product_automaton' and `generateProductAutomaton'. - - * src/TestOperations.h (generateProductAutomaton): Remove. - * src/TestOperations.cc: Include the BuchiProduct.h, Product.h, - SccCollection.h and StateSpaceProduct.h headers. Do not - include the ProductAutomaton.h and SccIterator.h headers. - Define static members of - Product and Product. - (generateProductAutomaton): Remove. - (performEmptinessCheck): Display output messages from the - removed `generateProductAutomaton' function here. Do the - same for updating product automaton statistics. Use the - Product interface for constructing the product and checking - it for emptiness. - (performBuchiIntersectionCheck): Use the Product interface - for constructing the intersection of Büchi automata and - checking it for emptiness. - - * src/UserCommandReader.cc: Do not include the - ProductAutomaton.h header. - (executeUserCommands): Remove the variables `product_automaton' - and `last_computed_product_automaton'. - - * src/UserCommands.h: Do not include the ProductAutomaton.h - header. Include the EdgeContainer.h, Graph.h and Product.h - headers. - (computeProductAutomaton): Remove. - (synchronizePrefixAndCycle): Remove. - (printCrossComparisonAnalysisResults): Remove - `product_automaton' and `last_product_automaton' from - prototype. - (printPath): Change the types of `prefix' and `cycle' to - constant references to StateSpace::Path objects. - (printAcceptingCycle). Expect also a prefix and cycle of a - state space as parameters. Represent the path segments as - constant references to {BuchiAutomaton,StateSpace}::Path - objects. - * src/UserCommands.cc: Include the BuchiProduct.h, Product.h - and StateSpaceProduct.h headers. - (computeProductAutomaton): Remove. - (synchronizePrefixAndCycle): Remove. - (printCrossComparisonAnalysisResults): Update parameter list and - documentation. Use the Product interface for constructing and - analyzing a witness for the nonemptiness of a product automaton. - (printAutomatonAnalysisResults): Use the Product interface - for constructing and analyzing a witness for the nonemptiness - of the intersection of two Büchi automata. - (printPath): Update parameter list and documentation. Standardize - the output to resemble that produced by printAcceptingCycle. - (printAcceptingCycle): Update parameter list and documentation. - Display all relevant information about an accepting execution - of a Büchi automaton. - -2004-05-18 Heikki Tauriainen - - * configure.ac (YACC): Do not add `-d' here. - - * src/Makefile.am: Rearrange to make future updates easier. - (BUILT_SOURCES): New variable. - (AM_YFLAGS): New variable for adding the `-d' flag to be - passed to YACC. - Move Config-parse.h and NeverClaim-parse.h from - EXTRA_lbtt_SOURCES and EXTRA_lbtt_translate_SOURCES to - BUILT_SOURCES. - - Thanks to Alexandre Duret-Lutz for patches. - -2004-05-13 Heikki Tauriainen - - * configure.ac: Add checks for the sys/times.h and sys/wait.h - headers. Add checks for the strerror, mkstemp, open, read, write, - close, popen, pclose, pipe, fork, execvp, getpid, waitpid, alarm, - sigaction, sigprocmask, sigemptyset, sigaddset, times, sysconf, - and strsignal library functions. Remove check for the return type - of signal. - -2004-05-13 Heikki Tauriainen - - * src/NeverClaim-lex.ll: Add %option nounput to avoid a - compiler warning. - - * src/ExternalTranslator.h: Include the TempFsysName.h header. - (ExternalTranslator::TempFileObject): Remove. - (ExternalTranslator::registerTempFileObject): Change - prototype to match that of TempFsysName::allocate. - (ExternalTranslator::temporary_file_objects): Change to a - stack of pointers to TempFsysName objects. - * src/ExternalTranslator.cc - (ExternalTranslator::registerTempFileObject): Use the - TempFsysName interface for creating temporary names. - (ExternalTranslator::translate): Handle temporary file names - as C-style strings. - (ExternalTranslator::TempFileObject): Remove. - * src/translate.cc: Make `translator' a static variable. - (signalHandler): Delete `translator' if necessary to remove - any temporary files before aborting. Restore the default - signal handler using sigaction. - (installSignalHandler): New function. - (main): Fix the number of dashes in the descriptions of - single-character command line options. - Install handler for signals that terminate the - process. - - * src/Makefile.am: Add TempFsysName.h and TempFsysName.cc to - lbtt_translate_SOURCES. - -2004-05-12 Heikki Tauriainen - - * src/Graph.h.in (Graph::Edge) Fix return - type of targetNode() and the type of the `target_node' - variable to allow compilation with gcc 3.4.0. - (Graph::stats): Fix type definition of - `result' to allow compilation with gcc 3.4.0. - * src/FormulaWriter.h: Include the LtlFormula.h header - to allow compilation with gcc 3.4.0. Remove forward - declarations of class LtlFormula and class Atom. - -2004-03-18 Heikki Tauriainen - - * src/UserCommandReader.cc (executeUserCommands): Print a - newline after each nonempty input line regardless of whether - the line consists only of an external command or not. Don't - print a newline after piping the output of a command to an - external program. Print a newline after the output of a - command. Do not interpret failures when writing to pipe as - errors to allow external programs to ignore some of the input. - - * src/UserCommands.cc (printAlgorithmList) - (printCrossComparisonAnalysisResults) - (printConsistencyAnalysisResults, printAutomatonAnalysisResults) - (printAcceptingCycle, printBuchiAutomaton, evaluateFormula) - (printCommandHelp, printInconsistencies, printStateSpace): - Remove extra newlines from the end of output. - - * src/StatDisplay.cc (printBuchiIntersectionCheckStats): - Remove extra newlines from the end of output. - - * src/TestOperations.cc (performBuchiIntersectionCheck): Print - a newline after the results to transcript file and to console - in verbosity modes >= 3. - -2004-03-17 Heikki Tauriainen - - * src/BuchiAutomaton.h: Include the cstdlib header. - Fix description of the BuchiAutomaton class. - (BuchiAutomaton::connect): Add parameters for the acceptance - sets associated with a transition. - (BuchiAutomaton::BuchiTransition::BuchiTransition): Add - parameters for the acceptance sets associated with a transition. - Remove copy constructor. - (BuchiAutomaton::BuchiTransition::print): Remove default values - for arguments. Add parameter for the number of acceptance sets - associated with a transition. - (BuchiAutomaton::BuchiTransition::acceptanceSets) New functions. - (BuchiAutomaton::BuchiTransition::acceptance_sets): New - variable. - - * src/BuchiAutomaton.cc - (BuchiAutomaton::BuchiAutomaton(const BuchiAutomaton&): Copy - also the acceptance sets of each transition. - (BuchiAutomaton::operator=): Copy also the acceptance sets of - each transition. - (BuchiAutomaton::regularize): Handle also acceptance sets on - transitions. - (BuchiAutomaton::read): Update description. Accept automata with - acceptance sets on states and/or transitions. - (BuchiAutomaton::intersect): Take care of acceptance sets - associated with transitions when forming the intersection of two - automata. - (BuchiAutomaton::print): Change output to refer to "acceptance - sets" instead of "sets of accepting states". Pass the number of - acceptance sets to BuchiAutomaton::BuchiTransition::print when - displaying the automaton in dot format. - (BuchiAutomaton::BuchiTransition::print): List the acceptance - sets associated with each transition in all output modes. - (BuchiAutomaton::BuchiState::print): Pass the number of - acceptance sets to BuchiAutomaton::BuchiTransition::print. - -2004-03-15 Heikki Tauriainen - - * src/UserCommands.h (printFormula): Change prototype to accept - the vector of input tokens as an additional parameter. - * src/UserCommands.cc (printFormula): Accept the vector of - input tokens as an additional parameter. Use the optional - parameter "nnf" or "normal" to choose the display mode. - Display only the formula to accommodate feeding the output (if - redirected to a file) back to lbtt using the --formulafile - command line option. - (printCommandHelp): Update the description of the `formula' - command. - - * src/UserCommandReader.cc (executeUserCommands): Accept one - optional parameter for the `formula' command. Pass the input - tokens as an additional parameter in the printFormula call. - Print an additional newline after the call if the output is - not redirected to a file. - -2004-03-12 Heikki Tauriainen - - * src/Exception.h: Include the istream header. - (Exceptional_istream::get, Exceptional_istream::read): New - functions. - - * src/Ltl-parse.yy: New file. - - * src/LtlFormula.h (parseFormula): Declare. - (LtlFormula::read(istream&)): Read the formula by calling - parseFormula (provided by Ltl-parse.yy). - (LtlFormula::read(Exceptional_istream&)): Remove. - * src/LtlFormula.cc (LtlFormula::read(Exceptional_istream&)): - Remove. - - * src/Makefile.am: Add Ltl-parse.yy to lbtt_SOURCES and - lbtt_translate_SOURCES. - -2004-03-08 Heikki Tauriainen - - * src/TempFsysName.h, src/TempFsysName.cc New files. - * src/Makefile.am: Add TempFsysName.h and TempFsysName.cc to - lbtt_SOURCES. - - * src/TestRoundInfo.h: Include the TempFsysName.h header. - (TestRoundInfo::formula_file_name[]) - (TestRoundInfo::automaton_file_name) - (TestRoundInfo::{cout,cerr}_capture_file): Change type to - TempFsysName*. - (TestRoundInfo::TestRoundInfo): Initialize temporary file - name pointers to 0. - - * src/main.cc: Include the TempFsysName.h header. - (allocateTempFilenames, deallocateTempFilenames): New functions. - (abortHandler): New signal handler. - (installSignalHandler): New function. - (testLoop): Do not explicitly remove the temporary formula files. - (main): Use the above functions for allocating and deallocating - names for temporary files. Handle signals that terminate the - process by cleaning up temporary files before aborting; however, - for SIGINT, do this only if user breaks are not handled by lbtt. - - * src/TestOperations.h (removeFile): Rename as truncateFile. - * src/TestOperations.cc: Include the TempFsysName.h header. - (removeFile): Rename as truncateFile; truncate file instead of - removing it. - (writeFormulaeToFiles): Use the TempFsysName interface for - referring to the names of temporary files. - (generateBuchiAutomaton): Truncate all temporary files before - exec'ing an external process. Use the TempFsysName interface - for referring to the names of temporary files. - - * src/ExternalTranslator.cc: Include the cstring header. - (ExternalTranslator::TempFileObject::TempFileObject): Use - mkstemp instead of tmpnam to allocate a name for a temporary - file. - -2004-03-08 Heikki Tauriainen - - * src/StringUtil.h (findInQuotedString): New function prototype. - * src/StringUtil.cc (findInQuotedString): New function. - - * src/UserCommandReader.cc (executeUserCommands): - [HAVE_READLINE] Add the input line to history before extracting - the external command from the line. - Ignore white space within quotes when splitting input line into - tokens. - Move parsing the algorithm identifiers given for the - `buchianalysis' command to - src/UserCommands.cc (printAutomatonAnalysisResults). - (parseRedirection): Explicitly unquote the file name. - - * src/UserCommands.h: Include the map and the IntervalList.h - headers. - (parseAlgorithmId, parseAlgorithmIdList): New function prototypes. - (printAutomatonAnalysisResults): Change function prototype to - accept a list of tokens instead of two algorithm identifiers. - - * src/ProductAutomaton.h: Include the string header. Rewrite - the friend declaration of - UserCommands::printAutomatonAnalysisResults. - - * src/UserCommands.cc (parseAlgorithmId, parseAlgorithmIdList): - New functions. - (printCrossComparisonAnalysisResults) - (printConsistencyAnalysisResults): Parse algorithm identifier - using the parseAlgorithmId function. - (printAutomatonAnalysisResults): Parse algorithm identifiers - using the parseAlgorithmId function. Throw a CommandErrorException - in the case one of the algorithm identifiers refers to lbtt's - internal model checking algorithm. - (printBuchiAutomaton): Parse algorithm identifier using the - parseAlgorithmId function. Throw a CommandErrorException in the - case the identifier refers to lbtt's internal model checking - algorithm. - (printCommandHelp): Do not treat the internal model checking - algorithm as a special case in command descriptions. - (evaluateFormula, printInconsistencies, printTestResults) - (printStateSpace, changeAlgorithmState): Parse lists of - algorithms and states using the parseAlgorithmIdList and the - StringUtil::parseIntervalList functions, respectively. Access the - numeric algorithm and state identifiers via IntervalLists. Make - error messages more consistent. - -2004-03-07 Heikki Tauriainen - - * src/StatDisplay.h: Include the IntervalList.h header. - (printStatTableHeader): New function prototype. - (printCrossComparisonStats, printBuchiIntersectionCheckStats): - Change the function prototypes to accept a reference to an - IntervalList for the algorithm identifiers. - * src/StatDisplay.cc (printStatTableHeader): New function. - * src/StatDisplay.cc (printBuchiAutomatonStats) - (printProductAutomatonStats, printAcceptanceCycleStats) - (printConsistencyCheckStats): Display statistics in a table in - verbosity mode <= 2. - (printCrossComparisonStats): Iterate over the set of algorithms - using an IntervalList. Do not handle the internal model checking - algorithm as a special case. - (printBuchiIntersectionCheckStats) Iterate over the set of - algorithms using an IntervalList. Skip the internal model - checking algorithm when displaying automata generation or - intersection check statistics. - (printAllStats): Display statistics in a table in verbosity - mode <= 2. - (printCollectiveStats): Skip the internal algorithm when - displaying the rows of the cross-comparison result table. Use - the changed semantics of Configuration::AlgorithmInformation - to find the name of an implementation. - - * src/main.cc (testLoop): Display test statistics in a table in - verbosity modes 1 and 2. - - * src/TestOperations.cc: Include the IntervalList.h header. - Remove inclusion of the TestStatistics.h header. - (generateBuchiAutomaton, generateProductAutomaton) - (performEmptinessCheck): Display the test statistics in a table - in verbosity modes 1 and 2. - (compareResults, performBuchiIntersectionCheck): Display the - result of the test also in verbosity mode 2. Show test statistics - using the changed semantics of - StatDisplay::printCrossComparisonStats and - StatDisplay::printBuchiIntersectionCheckStats. - (verifyFormulaOnPath, generateProductAutomaton) - (performEmptinessCheck, performBuchiIntersectionCheck): More - consistent error messages when the test is aborted. - - * src/UserCommands.cc (evaluateFormula): Use the changed - semantics of Configuration::AlgorithmInformation to find the - name of an implementation. - (printTestResults): Display the test results using the changed - semantics of StatDisplay::printCrossComparisonStats and - StatDisplay::printBuchiIntersectionCheckStats. - -2004-03-04 Heikki Tauriainen - - * src/TestOperations.h (openFile(const char*, int&, int, int)): - New function prototype. - * src/TestOperations.cc: Include the csignal, cstring, cerrno, - [HAVE_SYS_TYPES_H] sys/types.h, [HAVE_SYS_STAT_H] sys/stat.h, - [HAVE_FCNTL_H] fcntl.h, and [HAVE_SYS_WAIT_H] sys/wait.h headers. - (timeout): New variable. - (timeoutHandler): New function. - (openFile(const char*, int&, int, int)): New function. - (verifyFormulaOnPath): Fix references to the internal model - checking algorithm. - (generateBuchiAutomaton): Execute external program using fork/exec - instead of `system' to improve the detection of the case when an - external program was terminated by a signal (the behavior of - "system" in the presence of signals varies between architectures). - Handle timeouts when running the external programs. Discard I/O - exceptions while displaying the stdout/stderr capture file. - (performBuchiIntersectionCheck): Skip the internal model checking - algorithm when iterating over algorithms. - -2004-03-04 Heikki Tauriainen - - * src/main.cc (breakHandler): Make function static and change - return type to void. - (testLoop): Do not add the internal model checking algorithm to - the list of implementations (it is done in Configuration::read). - Apply the internal model checking algorithm if it is enabled. - Otherwise skip the automata generation loop as it is not - applicable for this algorithm. - (main): Enable interrupt handler only if mandated by the program - configuration. Use sigaction instead of signal to register the - signal handler. - -2004-03-04 Heikki Tauriainen - - * src/Config-lex.ll, src/Config-parse.yy, src/Configuration.h, - src/Configuration.cc: Rewrite the configuration file parser to - allow reusing a common set of functions for changing the various - settings independently of whether the settings were given in the - configuration file or as command-line options. Rearrange the - structure of Configuration::AlgorithmInformation, remove the - "nopause" and "pauseonbreak" command line options (and make - "pause" an alias of "interactive"), recognize lists of - interactivity modes (with the new mode "onbreak") both in the - configuration file and command line, and add the new - configuration setting "translatortimeout". In more detail, - the changes are: - - * src/Config-lex.ll: Do not include any standard headers. Add - %option nounput to suppress a compiler warning. Accept - "Implementation" or "Translator" as an alias of the Algorithm - block identifier. Do not accept newlines in "option = value" - strings. Do not interpret option values in the lexer. Make - specifying option values more flexible: quotes are now needed - only for values including white space. Both single and double - quotes may be used (as before, \ works as an escape character in - double quotes). Reject values with unmatched quotes. Remove the - getCharacter function (add rules for matching unknown tokens in - full). - - * src/Config-parse.yy: Do not include the cstdio header. Add - namespace StringUtil to the current namespace. - ([declarations]) Change %union declaration to make all semantic - values constant C-style strings. Remove tokens CFG_TRUTH_VALUE, - CFG_INTERACTIVITY_VALUE, CFG_FORMULA_MODE_VALUE, - CFG_STATESPACE_MODE_VALUE, CFG_PRODUCT_TYPE_VALUE, CFG_INTEGER, - CFG_REAL, CFG_INTEGER_INTERVAL and CFG_STRING_CONSTANT. Add - new token CFG_VALUE and nonterminal equals_value. - (algorithm_information): Replaced with `algorithm_name', - `algorithm_path', `algorithm_parameters' and `algorithm_enabled'. - (current_block_type, current_option_type): Removed. - (yyerror): Make parameter const. Remove the loop for reading the - remainder of the current token (the token is recognized in full - directly by the lexer). Remove error messages for all tokens in - the above list. - (checkIntegerRange, checkProbability, isLocked): Removed. - ([grammar rule `equals_value']): New rule. - ([grammar rules for the "Algorithm" configuration file section]): - Read the implementation information into `algorithm_name', - `algorithm_path', `algorithm_parameters' and `algorithm_enabled'. - Use the functions provided by the Configuration class to update - the configuration. - ([grammar rules for the other configuration file sections]): Use - the functions provided by the Configuration class to update the - configuration. Remove the rules `formula_size' and - `statespace_size'. - - * src/Configuration.h: Include the cstdio header. Add - declarations for variables and functions provided by the parser. - Declare yyparse() as a friend. - (Configuration::AlgorithmInformation::path_to_program) - (Configuration::IntPair, Configuration::locked_options) - (Configuration::GENERATION_RANGE, Configuration::PRIORITY_RANGE) - (Configuration::PROPOSITION_COUNT_RANGE) - (Configuration::FORMULA_SIZE_RANGE) - (Configuration::FORMULA_MAX_SIZE_RANGE) - (Configuration::STATESPACE_SIZE_RANGE) - (Configuration::STATESPACE_MAX_SIZE_RANGE) - (Configuration::OPT_NOCOMPARISONTEST) - (Configuration::OPT_NOCONSISTENCYTEST) - (Configuration::OPT_NOINTERSECTIONTEST) - (Configuration::OPT_NOABBREVIATEDOPERATORS) - (Configuration::OPT_PAUSE, Configuration::OPT_NOPAUSE) - (Configuration::OPT_PAUSEONERROR): - Remove. - (Configuration::AlgorithmInformation::extra_parameters): Redefine - as `char** parameters'. - (Configuration::AlgorithmInformation::num_parameters) - (Configuration::GlobalConfiguration::handle_breaks) - (Configuration::GlobalConfiguration::translator_timeout) - (Configuration::algorithm_names: New variables. - (Configuration::IntegerRange): Change the type of lower and upper - bounds to unsigned long int. Make `error_message' const. - (Configuration::DEFAULT_RANGE, Configuration::RANDOM_SEED_RANGE) - (Configuration::ATOMIC_PRIORITY_RANGE) - (Configuration::OPERATOR_PRIORITY_RANGE): New IntegerRange - declarations. - (Configuration::OPT_TRANSLATORTIMEOUT): New OPT_ constant. - (Configuration::registerAlgorithm, Configuration::readProbability) - (Configuration::readSize, Configuration::readTruthValue) - (Configuration::readInteractivity, Configuration::readProductType) - (Configuration::readFormulaMode, Configuration::readStateSpaceMode) - (Configuration::readTranslatorTimeout): New function - prototypes. - (Configuration::isInternalAlgorithm): New function. - (Configuration::readInteger): New template function. - - * src/Configuration.cc: Do not include the cstdio and - Config-parse.h headers. Include the IntervalList.h header. Remove - declarations for checkIntegerRange and checkProbability. Move - remaining extern declarations to Configuration.h. - (Configuration::GENERATION_RANGE, Configuration::PRIORITY_RANGE) - (Configuration::PROPOSITION_COUNT_RANGE) - (Configuration::FORMULA_SIZE_RANGE) - (Configuration::FORMULA_MAX_SIZE_RANGE) - (Configuration::STATESPACE_SIZE_RANGE) - (Configuration::STATESPACE_MAX_SIZE_RANGE) - (Configuration::parseCommandLineInteger): Remove. - (Configuration::DEFAULT_RANGE, Configuration::RANDOM_SEED_RANGE) - (Configuration::ATOMIC_PRIORITY_RANGE) - (Configuration::OPERATOR_PRIORITY_RANGE): New IntegerRange - definitions. - (Configuration::ROUND_COUNT_RANGE): Change upper bound to - ULONG_MAX. - (Configuration::~Configuration): Use the changed semantics - of Configuration::AlgorithmInformation. - (Configuration::read): The - --{comparison,consistency,intersection}{test,check} and - --abbreviatedoperators command line options now take an optional - argument. - The options - --no{{comparison,consistency,intersection}{test,check}, - abbreviatedoperators} return the same OPT_ constant as the - corresponding positive option. - The --interactive and --pause options take an optional argument. - Remove the --nopause and --pauseonerror command line options. - Store the command line parameters into a vector of - pairs (preprocess the special options --configfile, --formulafile, - --help, --logfile, --showconfig, --showoperatordistribution, - --skip and --version; preprocess also the options accepting an - optional argument). Then read the configuration file. Add the - internal model checking algorithm to the set of algorithms if - necessary here instead of in src/main.cc (testLoop). Finally - process the parameter vector again to override any settings made - in the configuration file. - Use the new functions for modifying the configuration. - Allow symbolic algorithm identifiers for the options --enable - and --disable. - Make error messages more consistent. - Exit with the status 2 if an unknown command line option was - encountered or an argument for an option was missing. - (Configuration::print): Tell whether the user break handler is - enabled; tell also the value of the timeout for translators. - (Configuration::algorithmString): Use the new structure of - Configuration::AlgorithmInformation. - (Configuration::showCommandLineHelp): Rewrite the descriptions of - the --{comparison,consistency,intersection}test, - --abbreviatedoperators, --interactive and --pause command line - options. Correct typos in the description of the - --abbreviatedoperators option. Remove descriptions of the - --nopause and --pauseonerror options. - (Configuration::reset): Initialize the values of - `global_options.handle_breaks' and - `global_options.translator_timeout' to false and 0, respectively. - (Configuration::registerAlgorithm): New function for adding a - new implementation to the configuration. The names of - implementations should be unique and different from the reserved - name "lbtt". - (Configuration::readProbability, Configuration::readSize) - (Configuration::readTruthValue, Configuration::readInteractivity) - (Configuration::readProductType, Configuration::readFormulaMode) - (Configuration::readStateSpaceMode) - (Configuration::readTranslatorTimeout): New functions. The - interactivity can now be specified using a comma-separated list - of modes that may include the new keyword "onbreak". - -2004-03-02 Heikki Tauriainen - - * src/StringUtil.h (toLowerCase, unquoteString) - (substituteInQuotedString, parseTime): New function prototypes. - (QuoteMode): New enumeration type. - * src/StringUtil.cc: Include the cctype header. - (toLowerCase, interpretSpecialCharacters, unquoteString) - (substituteInQuotedString, parseTime): New functions. - -2004-02-19 Heikki Tauriainen - - * src/TestRoundInfo.h (TestRoundInfo::all_tests_successful): New - variable. - (TestRoundInfo::TestRoundInfo): Initialize the value of - all_tests_successful to true. - - * src/main.cc (testLoop): Update the value of - round_info.all_tests_successful to indicate the occurrence of an - error. Use the value of this variable as return value from - testLoop. - (main): Return 1 if an error occurred during testing. Return 2 if - there was an error in program configuration; remove extra space - after colon in output. Return 3 if an unexpected exception - occurred. In this case print an additional newline before the - error message. - -2004-02-19 Heikki Tauriainen - - * src/StringUtil.h: Include the IntervalList.h header. - (IntervalStringType): New enumeration type for describing the - boundedness of interval strings. - (parseInterval): New function prototype. Renamed the old prototype - to `parseIntervalList'. - * src/StringUtil.cc: Include the climits header. - (parseNumber): Be more strict about ensuring that the numbers are - positive. - (parseInterval): New function for parsing interval strings. - (parseIntervalList): Use the `parseInterval' function as a - subroutine when parsing a list of intervals. Add a parameter for - optionally storing tokens not recognized as intervals into a - vector of strings. Store the result into an IntervalList. Throw an - IntervalRangeException if an interval does not fit within the - given bounds. - -2004-02-18 Heikki Tauriainen - - * src/IntervalList.h, src/IntervalList.cc: New files. - * src/Makefile.am: Add IntervalList.h and IntervalList.cc to - lbtt_SOURCES. - -2004-02-17 Heikki Tauriainen - - * src/TestOperations.cc (writeFormulaeToFiles): Make the order of - debugging messages (verbosity level 5) more consistent. - -2004-02-15 Heikki Tauriainen - - * src/DispUtil.h (printText): Move function declarations to their - correct place (out of struct StreamFormatting). - -2004-02-15 Heikki Tauriainen - - * configure.ac: Require Autoconf 2.59. - Remove use of deprecated macros. - --with-readline-prefix, --with-readline-includes, - --with-readline-libs: New options. - -2004-02-13 Heikki Tauriainen - - * src/BitArray.{h,cc}, src/BuchiAutomaton.{h,cc}, - src/Configuration.{h,cc}, src/DispUtil.{h,cc}, - src/ExternalTranslator.{h,cc}, src/FormulaRandomizer.{h,cc}, - src/LtlFormula.{h,cc}, src/NeverClaimAutomaton.{h,cc}, - src/PathEvaluator.{h,cc}, src/PathIterator.{h,cc}, - src/ProductAutomaton.{h,cc}, src/SpinWrapper.{h,cc}, - src/StatDisplay.{h,cc}, src/StateSpace.{h,cc}, - src/StateSpaceRandomizer.{h,cc}, src/StringUtil.{h,cc}, - src/TestOperations.{h,cc}, src/TestStatistics.{h,cc}, - src/translate.{h,cc}, src/UserCommandReader.{h,cc}, - src/UserCommands.{h,cc}: Remove all #pragmas. - - * Version 1.0.3 released. - -2004-02-12 Heikki Tauriainen - - * doc/texinfo.tex: New upstream version. - - * doc/lbtt.texi: Update edition to 1.0.2. - Remove node names with commands to fix dvi file generation. - Move the node about the lbtt-translate utility to correct menu. - Reformat the automata file format section to avoid overfull lines - in dvi generation. - Fix description of the Algorithm block used with lbtt-translate. - - * doc/testprocedure.txt, doc/intersectioncheck.txt: Add initial - newlines. - -2004-02-11 Heikki Tauriainen - - * src/UserCommandReader.cc [HAVE_ISATTY]: Include the unistd.h - header. - (executeUserCommands) Stop waiting for new commands if an EOF is - detected. [HAVE_ISATTY]: If standard input is not connected to a - terminal, echo the input line. - -2004-02-10 Heikki Tauriainen - - * configure.ac: Remove duplicate checks for headers. - (GLIBC_OBSTACK_WORKAROUND): New config.h macro for checking for a - version of the obstack.h header that requires a workaround to be - compiled with g++. - Add check for the `isatty' library function. - Include the stdio.h header when testing for readline libraries. - - * src/Alloc.h: Rename to LbttAlloc.h to avoid a name conflict with - system header files on Darwin. - [GLIBC_OBSTACK_WORKAROUND] (__INT_TO_PTR): Redefine macro to - work around a C++ bug in the obstack.h header file in glibc 2.3.2. - Thanks to Alexandre Duret-Lutz for the original patch. - - * src/BuchiAutomaton.h, src/Configuration.h, src/DispUtil.cc, - src/ExternalTranslator.h, src/FormulaRandomizer.h, src/Graph.h.in, - src/LtlFormula.h, src/main.cc, src/Makefile.am, - src/NeverClaimAutomaton.h, src/PathEvaluator.h, - src/ProductAutomaton.h, src/SccIterator.h, src/SharedTestData.h, - src/StatDisplay.h, src/StateSpace.h, src/StateSpaceRandomizer.cc, - src/StringUtil.h, src/TestOperations.h, src/TestRoundInfo.h, - src/TestStatistics.h, src/UserCommandReader.h, - src/UserCommands.h: Adjust includes. - - * Update copyright information in source files. - -2003-07-04 Alexandre Duret-Lutz - - * src/Config-parse.yy: Remove stray `,' in %token arguments. - -2003-07-18 Heikki Tauriainen - - * UserCommands.cc (printAutomatonAnalysisResults): Ensure that - the states in a witness for the nonemptiness of two Bûchi - automata are distinct to prevent the truth valuation for the - atomic propositions from being defined multiple times in any - state of the witness. - - * Version 1.0.2 released. - -2003-07-17 Heikki Tauriainen - - * NeverClaimAutomaton.cc (ParseErrorException::ParseErrorException): - Fix a string buffer overflow. - - * ProductAutomaton.cc (findAcceptingExecution): Concatenate - fragments of an accepting cycle in the correct order. (Thanks to - Joachim Klein for pointing out an example uncovering the bug - in previous releases.) - -2002-11-04 Heikki Tauriainen - - * StatDisplay.cc (printCollectiveStats): If using more than five - formula operators (but the total number of operators is not - a multiple of 5), insert an empty line in the output before the - last row of the operator distribution table. - -2002-10-21 Heikki Tauriainen - - * BitArray.cc (BitArray::find): Fix bug in testing whether - all accessed bytes were zero. - -2002-10-01 Heikki Tauriainen - - * Version 1.0.1 released. - -2002-01 -- 2002-09-25 Heikki Tauriainen - - * Alloc.h: Use preprocessor macro HAVE_SINGLE_CLIENT_ALLOC - instead of HAVE_SGI_STL in #ifdef conditionals. - - * BitArray.cc (BitArray::BitArray): Do not clear the allocated - array after initialization. All callers updated to reflect the - changed constructor semantics. - - * BitArray.cc (BitArray::bitwiseAnd, BitArray::bitwiseOr) - (BitArray::bitwiseXor): New functions. - - * BitArray.cc (BitArray::equal, BitArray::subset) - (BitArray::count): Fix `&' operator precedence in comparisons. - - * BitArray.cc (BitArray::hammingDistance): Use the `bit_counts' - array to compute the result instead of scanning the array bit by - bit. - - * BitArray.cc: Documentation fixes. - - * BitArray.h (BitArray::bitwiseAnd, BitArray::bitwiseOr) - (BitArray::bitwiseXor): New functions. - - * BitArray.h: Documentation fixes. - - * Bitset.h (Bitset::Bitset(const BitArray&, const unsigned long)) - (Bitset::Bitset(const Bitset&)): Use `memcpy' instead of - `BitArray::copy'. - - * Bitset.h (Bitset::operator=(const Bitset&)): Reallocate memory - only if necessary. - - * Bitset.h: Documentation fixes. - - * BuchiAutomaton.cc (BuchiAutomaton::regularize): Changed - semantics: instead of modifying the object itself, the function - now returns a pointer to a newly allocated BuchiAutomaton (the - regularized automaton). - - * BuchiAutomaton.cc: Documentation fixes. - - * BuchiAutomaton.h (BuchiAutomaton::regularize): Changed - semantics (see above). - - * BuchiAutomaton.h - (BuchiAutomaton::BuchiTransition::enabled(const BitArray&, - const unsigned int)): New function. - (BuchiAutomaton::BuchiTransition::enabled(const Bitset&)): - Use the above function internally. - - * BuchiAutomaton.h - (BuchiAutomaton::BuchiState::print(ostream&, const int, const - GraphOutputFormat)): New function. - - * BuchiAutomaton.h (BuchiAutomaton::BuchiTransition::operator<) - (BuchiAutomaton::BuchiTransition::operator==): Fix function - prototypes to match those of the base class. Make functions - private to prevent external comparison of plain Graph::Edges - with BuchiAutomaton::BuchiTransitions. - - * Configuration.cc (Configuration::read): Use autoconf-generated - PACKAGE_VERSION macro for displaying program version instead of - including version.h. - - * configure.in: Renamed to configure.ac. Updated to Autoconf - 2.53 and Automake 1.6. Improved checking for the presence of - the slist STL extension. Revised checking for the availability of - the GNU readline library and the libraries to include. - Replace the old preprocessor macro HAVE_SGI_STL with new macros - HAVE_SINGLE_CLIENT_ALLOC and HAVE_SLIST. Introduce new - preprocessor macro SLIST_NAMESPACE. - - * EdgeContainer.h: Remove uses of redundant preprocessor macros. - - * Graph.h: Renamed to Graph.h.in to implement the optional - inclusion of the slist header using an autoconf substitution - variable. - - * Graph.h.in: Use HAVE_SLIST macro instead of HAVE_SGI_STL in - #ifdef conditionals. - - * Graph.h.in (Graph::Edge, Graph::Node): Make classes public (to - prevent warnings from Intel C++ Compiler). - - * Graph.h.in (Graph::operator[], Graph::node, Graph::size) - (Graph::expand, Graph::stats, Graph::subGraphStats) - (Graph::Edge::targetNode, Graph::Node::operator=) - (operator<<(ostream&, const Graph::Edge&) - (operator<<(ostream&, const Graph::Node&): - Added explicit `typename' specifiers to parameter and/or return - types (to prevent warnings from gcc 3.1). - - * Graph.h.in (Graph::subGraphStats): Make `s' a const variable. - - * Graph.h.in (Graph::Edge::ptr_equal::ptr_equal): Change - definition to match that of `Graph::Edge::ptr_less'. All callers - modified accordingly. - - * Graph.h.in (Graph::Edge::operator<, Graph::Edge::operator==): - Make member functions protected. - Make class Graph::Edge a friend of Graph::Edge::ptr_equal and - Graph::Edge::ptr_less. - - * LtlFormula.cc (LtlFormula): New static variable - `eval_proposition_id_limit' stores the maximum proposition - id during the evaluation of a strictly propositional formula. - - * LtlFormula.cc (LtlFormula::sat_eval): Make `max_atom' a const - variable. - Access the identifier of a proposition through Atom::getId. - - * LtlFormula.h - (LtlFormula::evaluate(const BitArray&, const unsigned long int)): - New function. - (LtlFormula::evaluate(const Bitset&)): Use the above function - internally. - - * LtlFormula.h (ptr_less): Make class public. - - * LtlFormula.h (LtlFormula::eval): Use a BitArray instead of a - Bitset internally. - - * LtlFormula.h (Atom::eval, Constant::eval, LtlNegation::eval) - (UnaryFormula::eval, LtlNext::eval, LtlFinally::eval) - (LtlGlobally::eval, BinaryFormula::eval, LtlDisjunction::eval) - (LtlConjunction::eval, LtlImplication::eval, LtlEquivalence::eval) - (LtlXor::eval, LtlUntil::eval, LtlV::eval, LtlWeakUntil::eval) - (LtlStrongRelease::eval, LtlBefore::eval): Use BitArray instead - of a Bitset for evaluation. Make subformula parameters (if any) - `const'. - - * main.cc (testLoop): Use autoconf-generated PACKAGE_VERSION - macro for displaying program version instead of including - version.h. - - * src/Makefile.am: Remove redundant references to @LEXLIB@ (the - sources are independent of any external lexer library). - - * NeverClaimAutomaton.cc (NeverClaimAutomaton::write): Add - detection for jumps to undefined never claim labels. - - * NeverClaim-parse.yy (yyerror): Fix computation of the position - of a parse error. - - * PathEvaluator.cc (PathEvaluator::eval) Avoid creating a - temporary Bitset object during evaluation of atomic propositions. - - * ProductAutomaton.cc (ProductAutomaton::computeProduct): - Avoid creating a temporary Bitset object when checking the - enabledness of a product transition. - - * ProductAutomaton.cc (ProductAutomaton::findAcceptingExecution) - Use BitArrays instead of Bitsets. - - * ProductAutomaton.h (ProductAutomaton::operator[]) - (ProductAutomaton::node): Make state id parameter `const'. - - * ProductAutomaton.h (ProductAutomaton::ProductState::print): - Change function prototype to match that of the base class. - - * SccIterator.h: Add `typename' specifiers to prevent warnings - from gcc 3.1. - - * SpinWrapper.cc (SpinWrapper::SpinAutomaton::parseAutomaton): - Remove redundant `try' block. - - * StateSpace.cc (StateSpace::State::print): Fix typo when - displaying empty sets of propositions in dot format (the open - brace was previously missing). - - * StateSpace.h - (StateSpace::print(ostream&, const int, const GraphOutputFormat): - New function. - - * TestOperations.cc (performEmptinessCheck): Added a colon to - the end of the "Accepting cycles" message. - - * TestRoundInfo.h: Removed redundant inclusion of BitArray.h. - - * translate.cc (main): Use autoconf-generated PACKAGE_VERSION - macro for displaying program version. - - * translate.cc (main): Fix bug in checking the number of - command line arguments. - - * UserCommands.cc (printCrossComparisonAnalysisResults): Fix - bug in the construction of the witness path in which the formula - should be evaluated when the witness path is extracted directly - from the original state space (i.e., when analyzing results - against the internal model checking algorithm). - - * version.h.in: Removed. - -2001-11-12 Heikki Tauriainen - - * Version 1.0.0 released. diff --git a/lbtt/Makefile.am b/lbtt/Makefile.am deleted file mode 100644 index 041e990b8..000000000 --- a/lbtt/Makefile.am +++ /dev/null @@ -1,2 +0,0 @@ -SUBDIRS = doc src -ACLOCAL_AMFLAGS = -I m4 diff --git a/lbtt/NEWS b/lbtt/NEWS deleted file mode 100644 index 1a707cec7..000000000 --- a/lbtt/NEWS +++ /dev/null @@ -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 . 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 ). - - 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 - . 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 - . - -* 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 `| '. - - - 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 - . diff --git a/lbtt/README b/lbtt/README deleted file mode 100644 index ffa0099a7..000000000 --- a/lbtt/README +++ /dev/null @@ -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 . 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 -. - -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 - . diff --git a/lbtt/configure.ac b/lbtt/configure.ac deleted file mode 100644 index a65ccd9e1..000000000 --- a/lbtt/configure.ac +++ /dev/null @@ -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 ]], - [[ - #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 - #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 diff --git a/lbtt/doc/.cvsignore b/lbtt/doc/.cvsignore deleted file mode 100644 index cc5fa0863..000000000 --- a/lbtt/doc/.cvsignore +++ /dev/null @@ -1,4 +0,0 @@ -Makefile.in -Makefile -*.info* -texinfo.tex diff --git a/lbtt/doc/.gitignore b/lbtt/doc/.gitignore deleted file mode 100644 index a9e6e1b4e..000000000 --- a/lbtt/doc/.gitignore +++ /dev/null @@ -1,14 +0,0 @@ -Makefile.in -Makefile -*.info* -texinfo.tex -*.cp -*.cps -*.fn -*.fns -*.ky -*.kys -*.pg -*.vr -*.vrs -*.tp diff --git a/lbtt/doc/Makefile.am b/lbtt/doc/Makefile.am deleted file mode 100644 index 8c515df49..000000000 --- a/lbtt/doc/Makefile.am +++ /dev/null @@ -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 diff --git a/lbtt/doc/gpl.texi b/lbtt/doc/gpl.texi deleted file mode 100644 index e6ffc0fe8..000000000 --- a/lbtt/doc/gpl.texi +++ /dev/null @@ -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. diff --git a/lbtt/doc/intersectioncheck.eps b/lbtt/doc/intersectioncheck.eps deleted file mode 100644 index 9cb22e5bf..000000000 --- a/lbtt/doc/intersectioncheck.eps +++ /dev/null @@ -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 diff --git a/lbtt/doc/intersectioncheck.png b/lbtt/doc/intersectioncheck.png deleted file mode 100644 index 596e95c4b26d594cc2308bfdef7fe80a7e860d88..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14956 zcmeAS@N?(olHy`uVBq!ia0y~yVA5n@VEV(s#K6F?ifPkT1_lPs0*}aI1_mBq5N5n| zZmk~!1A}adYeY$Kep*R+Vo@rCyI-h+dq#e7NpW&fWr*aGpf-=R-3>nGym{n!gGU*+CsrE#Up<&yF<9AN| z?S8fXFw6b--#1N|w{(4%)7RrA%eYMZI2N`32-~{u(c8?E{ADN2U-7jkG51{y_WHjj zj?p%C`tQI0KQ;aOy!OrHm-EZlpVHsI+r_lp?%U6rV`3QrVlPUn>u1;3eX7ZxesJl2 zRc_m)*Y65?-U;doR-IDq+Zj9I_xTCeHlMzs;{E+`O-|tQd3&dMPUDH&T;1~fnDDmc zDNJXp+uALQcCYLTP@Jxu-{O_gx##WnfI#;ZcRnBJQJeHmf~#HX)MWOXhI4Xm%@ds@ zD=KKGu;$*4v-e*!T!~HBdGh6Qah-?V=}E5Js$?Sc{`Wq7m|fcL{6;YA?!y^3m0ONh zzE#ug+nMRDe(U-F^K8@iewy58bW{7~^Ue0>T~oZpuj$72F0S5UwVtcDxH2O&`-08Z zRoi=Fqb3&xTzYmTa-ZhacLg1`PHU}YzE>Z4zW&v2_aE~?7I)XA@_al)utE}ik^KiW47yk*XsvZ zGQR|GO$vXv_Ph9v&l|&j+VwrWp!|n(N_9=ip_?mIBmMvWVLSDzQ~qK1q0UAB7Q~#J zS14|qB-FR_Vg0;PW2)*<=5lZrI;- zO4rUhTd_$a+&^KDZx> zPyTtep2hCnovmjl=KsmLT=sjp7*j5nXcF(o9S_!@oOMg-ce%_>z1K3woO0N&CUG5{ zP?5WaZTsm2p<9NpWz?Fp*{3GE@5tsY`15^*MDW}VHS4Y)x_aB>wM@_28|=DUPu7~7 z?Q8tydBW*d^~nk!-347e3HO4<7dA@G`MYG5zs0;Q+kX3%1WjAanUb-lv~btQxM-`I ztVhbPWp*De)O~e|>6xwQ!dc5c-tcZ!?TekU?rP=?o7u;H$+cZ&t!MP>xY{|3eYhlw@N(<{$ZksSMx4g&e znn?LQXY1YBSKk~Dx%M;APS+*6)!y;8$=siYXIB}|D2;lis(5RaT2{30ol5?B7ia#> znNnKU6R*(jSLT7-OZrN`?Z8dY_b+rp&4?}lM^G%mat?+#}uaxDyn)8;c zp(`p`1)tkWBt3X@yztu3$^w_Zhy44FX5Iht{9#3Z>?-ypI zRoMLIoLyR{H-D4Vwlo2k1!{iv^PY#@Wjk-hv~Hqtt6=gfjj7(ov(_$eJ83n&?y857 zQBz^^Jcr|V45rq6=v{O9@fwFZU6$`oDWzp`S5iXHUZ^~s`pIsEXK9bz(D>- z>}r{Hz72(T$61f2tR9Qd~PQ0;NK(|*@HE%_Eb z_7y(j>16oW`pC4;a*zHtoL%!-IPsgX*PNLG{I6vQxG$<|i1oC;xh=#mt&2v?=&)k6(H2%xbf!=YcJr zd#~TxV7w+K=}utUX6p+)c|Z4G)h>uWu;7@@tUrJ2R=fY#<-TDt{l~xMHLpMaT$82c z@_$-xQUAonyM8_Cd$P~T%**~=a$@fVxv*4)TMql@t}Eu2xUQgHk@9jb9}m~=@Ra+L zydUg%v-a}wisQ!;b7B^+j7VNp`C_r-yBELzzB75>srF+A)0Y=7)t;y~|9c|GX080D zTy$0!>$lsTnkG@)=iGLm-O9$mV1B}ufgu;v@G&dmXK;wVUYa+3ztK*c=aGA#-92$v z-^lrz*N?O9kLNf4$W}l8WSP+BxicwbOveV=ZcE0YwwaIV7Eqd%@y zt*+ZO)E0nCwa=YXzRVZpVF89U36PgPA75UTp1J5J0=_M z{>s?WR&@Txs|^7=XEc^I$@1o8+DW}__-yO!*JY=d@>cWar$4t>nQqiCvepbw`1xzW z@mp@zS*&ilwQo-CIcv+EeA$Zod)jgby@ge)boUyZJpS(l&$(NjF&?ic3C}tecTG+1 z`{U^McNMJq4Nj%6Xp{M9!~Jsq79YLmMW(CfPtpIAu{Nb@+lNita{2uKp54AB*;??L zy0%M(`ti`?->&=lNM6cVJzr#2$!dX_e?R(WYYz8&{-dCa%7RP zXzFpv?%w+Q%nUcCEPQ>3LE>WZk@F|SH)=k!W%%dO|LML}=(_)|Z@TX=GhA>3HNTa= zGcar^T+7&Cf9`(l9ox6-L9&(n4PD1G9sYOU5ZuYmu%H*DdfVTha@_Wwk1f86g_%yh z=KG(av2|kZs<+Q=vxCo_UnP1#*L&8f%I~XQtyOFkTd(=tMEm=VH_6G@U&#b~h?r0| z>EH2ZYKz-%-k2F{c<|e2xdS?U$Cz}3&wc+hsi5lqr+D=P{+V>n`T3z_ z^{Ceh>)Dh~@Yue6lEEIk7L*nQZ*iVIHaYC@3z?fO&$Mb*KR4d)W@df(){#p8vYy?0 zViUe9{P_9s)7^8<&p#dCbbbH-%(cgMTOBZ6I9KLv#;UE8opZFdOwKsfcF}kf=h@I7 zVXrF}PTA=@ldI&J7q+Cg_OA`=`Lt;zPrmx`-OHRFeayXgV%w6PY2NbIPI|kq zJvjK~?VW$8_50>ZC#~Imam!6VyO?r;!+R$B)D?s&(88wbihZ4xMJyO7*HF*m_DZbG%(b?@`y*4*po zb+6vn*E-L1YUA4{5?4Yt@o&ET_|l$FOh3?gVPaXM}8zUS4 zFEWlbTI}nZ4_{m#em#9wCbV&y@WUIWlW(8A*!S#i*(I%2IzKgTdG4H7^n2%>0~~LU zObHY%Ew^};xz64F^`zOao0F; znt@?AI8{xoW?;C5T98SDlGEGswQGLvG_|@IvO!jAt>zh!vYva_@1Es-emCcYn9lWW zPfMMrE}tNIN9>tx@kb9U291f;%as2~2THJqU zGuumcgQg>!S$3vNUgF;%)0r+>blz);e1f9Td8a3G41yCYt|@)jId(-|B$<8Zaj{GM2ArM8MT+aQ}p@+r+vC#Tj32xV+og{e^jt%Ok_?JIPWn z*(-XEBunl*Zgq+O14HL=iz5C7y?;Azdf0rMSZ#J7fc1;=$DGDHo7pe%Gx(pdy{+(< zVfu_OZ<_9G7QV!YE;>K$ zMmAfWhs|uI?{B)kFek)6nb$k9PC#bzyxNJ?-`svVMySkNJF$A3`>&fKjn&OZHd`0< zv-c!%v>tiPu#^3OpNEazgz7m7ubMeLZ1N^l|55nMaD#Q{anVcsGRc=7bM8DYed)X# zN0_}(zwr~fc8QA*csh^E7xnuuk>BC?sIc=6^8r1f{_rPq+h_brC|8j?e!_O%#5#r> zU(UZ0{h=(YasL12$Dfbs{|#ur!T0u??P+DL&vO4a-Q+h`44yH2-lnjul#Y^Pers=? zvMqacbY^iw@{DHR%-<>>T@tjvPswOvp4-{Z!?M}K#xdf&twd7_^XX0BJd0(I7Ky2U z{}KN7WJ!L6+wVCCL$r*hSNmM;;}6l)S-nhBYHjtiBLA*$=BK{@*43UI>#e-wimvnV z{sSfN4n~w@Mg*(HM!k$kdp-G%u(ugwQn_?lNcwY$qfvLG&e&dibwWN%LTt%yyDcX( zbe_$Vzx602{j1T}gHb-^NttEUkZTdu3vRoAIJUtY25R_MTjN z@!-{I71zGK{cOv_b!tUH#-hEN+|dus*A-{ae8|W=!$1i*JTiH#6p6%ODAG=l+*yz-{U*4}>XXCGj>*fc|-@ha8 zFNb#Z-k8(ZdS|bypB7yadF6(xp8Ri~upg&gUxfTffBswQkIqe&oqPB4e_!=2ZF9MN zl&D>bMeY70VXgPApN08W{e3dgB--n>f2-;($5!Xbr@y7`+^8AyZj$0UXR;%#b58w@9&Sk=l|CF`sMC%?=^LSGoNyaXZ^k@lpeC9wfWimmAS6< z)xuKIk$rQ&rL8L89+nW-+ArlNud{Lap~}3MQXxNhp2#gc)BJ5&2iN{1#v%+1w<^-U zZI#?@5VE78_82_9fXn2Hv~Q+miBkd}UT~?tTyo9qv)qAc`uykJ7|iF*>}`a^^5R4K zhVK~}G9FuP&yHbR-1GWQ+hQZuk^-8cX94oR-F z*9vyNP=4ajAbRrjb z_2%w=QPFif*C<|rZEA?cuf6icnfd%S>%MK?wsrkRzvMerE-pL0Uj8|E zi|?HA=WR(@yxgiw-dA-^;XiHtBlYyc=KG7TomKA(@t!9VRJSau)^_c;B2E5%8FMB| zt((UaZ(Z}IuFftsCHm50?Z56(Eyu3?`h4a7AGw;-YZSl6?EAE7_VnI@gsrnJo?VmL zu<6V1%kgi1KHMGuB|V5YSx))+`Do6?@&321-)smHw&>li)2Dyny8mnEo(aF6>TA@rR43TVPu~6Wg!5dxrtqivDx1z6 zig=*^=-;*sk*u`N#;fnXS(!hc{dn1-%e;v?2B&?ie{bBcdrs?5`WvyC7Wa(>oF59k zX>nrQTixk-^u>Qqe zZ=Y3V`8(6uqV^bR$;`^gpLOomx3YcgA5tEy-OCURZh)LkPy4?A(~s_(A>lu}`@`!x z%wO**`}{Sz{kz-N?Y*}j6mlgQ7+ZFYj3GwG8MqF{U)mHw#Lg^zz+Qd4OiPc{wR4_dD zu+KVS>*Zm?P@wcZL*XOC?u1v1o9{3))K91rnNYnf`BL+A39he!&o@u3ex~%1VYbp= zAJ=y?JB~2t^nNks-n3WqWSok( znaB1wEb#Nb9jxz4Yq@tmXOj|p_HvJQ?D^wtbr%m=<+Oac{NB^_=$bokx83@b_pj)h zR{HL1OVf_ex>-2){_fpZ=e&QpDLL7z-|?V@(o@dobyWpt-rnl#WH(~k#jW&I^z%G! z6*-1-!>>DC-Z5U=EwfzW#5U(&6DL-yMEh6S&F5F1rOuLVy+odI=kmpNZLF0Of*le16zp!Owy(d#=yEj(<&rKu{eS;gu*QAu`^ntlP0`t6WaN_evazA zbC+N0xo?@?ec}45|0^Ru7mCKt^OD);B5(0=veI{#BOTkOpRYe>e|_Egg%t}IwD!t& zd?|hu)m(2m`-_aMa?v$*ohuEu9P6{w#eenJM@j5lbM;=_j&~2*E6*3+kSLp4`#);0 z)$xNJVFI(Bo=#peOGm{!d&XaxC-ao!9woY1&$;&`dfnt}lACsay%7J|dD;toANwWq zU+h$mdQ|E5LS=Se#CZT>fSM~bqx)^Fpz3BNvn|Mi~TTg2?b z-Ulz$zr3%$ljAY<&ehA;qr*Ewt=+QMteiGs@6^(5@9)ol5OQBDd|7?x)zGac%Y$1E z_`Z0b=W*xG<790Xy>#Zdo%y{2KRW*1UCU8*=B)dMR6YO9o<(Jy260M0ajs`<1%>#( zIW_m_JnNj_v6DR^Xh*j~BG-(%Lr>+@Y#DgErqv}ql@sF6;WB-(KsDqS=alM2s&anI znQwPau3PkEUPdRok0p%=jW6^U3t&R_uqy?yDZ;Lo37KY z7G3hhVDFRPCuTptBfRG>zvbMzu!Qpx;dR-QO2TiscgVY(O3MiPcWBA^!e526tDDs4 zeeVfh@U(RH*@}#y_t!7KK5_ee_OFkX`_dPmvpj!V>c#)6Z#B~wZ&Z)7JG-zZph+s* z{O7){YWtj~=PT~tuOK;{Fa74@vP<@xkN3&;mt~$`Z(#IohSaQi?izy20{<+P z&)<1Gvf|AS(~d26b6lT0E^&L?U!A40+9}xA?0NL!O?}Hf_CC@1yTj`KV@(6Ly(^<1 z8Hq0BJal=dy#3DhBa+je}SlF5xJlkYh5&pCdjPV6~q=m`j_zT<#=foN5(XcGIV~t~@;L{hj1= z-v!Mb`HcoEHwIrVzn=0qIj>Ah)~d|@gu;g{ne(?OW*^Bp`(dBwj6JvB&$CjQ=a-jt@@yN2OwQtF-y7Haw%@*4 zbdPz@5#iJ_#~D_+$NEBK}Tx1{Ue1^K*;%JD=-;(@Nr$*h}Zx zu1nUw54f3|JB-%GOUxYMgCY?D$S{-_2{UL;?;R zkZnJ07;O4oW6r-@FQ#l_{uL9vLx;pmNOj*dIReVaY`YZU&vIKN{w zJA98>M&bLBN2NEC*571olHl5@F0j6n{Xp3XTZT0WuY}oms&lE?+U@99eyPq;8Ez+-Gv!UFp2KY#wQ=(s&Wm4q?>vrN zafCTR`H9?*Cu!4ve*U@R=Cs{2epxL0btcC&v)cB*d@h?n!KKgLTTfqnb!SCJqVN3G zvgx;#dlKx5{Ub6bmtG4>)%)!0Jx9@^^j!qYowDhRWQw_O#5waGXM8N}wc?nJ%al99 zjyLUJZq#e_+G2RSKr*S`@%zl`KSw#Ib5sc!Zk}jwSIl20(f7Ag>~h9!Y4?sh!V7;+ zvu+mLW+hxOSy^F?Uh4^4#@4s%_L<-LevNYzZ-2oJ-McB%3(IF$$GEKyev;cBz9lRD z&a-&|hyJZuekz-{;_kY-D-G)Ziv3r7lgdgKym0f7vP{|Mv-R&fn~xNK3K#vi?Zrlm z(2uu+*57_@`Mshy^4WG~iIn8V=4)E_sc5+f@dmVoZehlE)Zd_M%UVl!D8K06I*TXWkUxwz~ z;%aIBvP88J=7*Z=8ZGqurF>5^@8Q?QVtI+OQU1+hw-SHmIXEAxUGw@u;^DXT_ll4G zoAY+s!E?7{fvje}rek$~IuKt(nodO@{ z6>Rr%4++dx1L>3glnO+EnatmMMN6`0mFS?e9ISTBpZXZqxDqZO3if_d{}b z7-!4v1-e!hD+(r8|J$*Z`RmV`Q?}yktu^Dm`gg2;xNe$2`i~oYvUmD4j^9Z;@vZ)$ z^uxZk4u98oKc^R{1^m1A^XO@zcVhn@On&iQ;nCB`?1e0ca=UKw$(h}GGB4)qlZ78P z&J#K%tFiM#@aqab;s1?QO-lR%k(@2JjjTZ~i+wuJ4YxhZZxAL8ZQ_Sb9J$et; z^e=KRlhmfYSKh3>-+c3O`DXi8|7B0PzZ;0}(_RzzwKOrhKxow#<2!5l;8GIxnTP}F44UIJD=~Ux{&^D-G=pw)0L-x*cb8T_05B8{@si} zm&!SJz3{v5CWr58wG`Zc`e#P;E_1^R<}>5>U))($J~=XFn({xjJBMCRwB-0MxV72( zysiDQ#W%7l_dBz^WM8GfC}n5Sufw`~`ldXcCHPIHsr-Y$@jGUrw)^f_z392SRmuCv zUaorw=RTkJO4Hifac|7tSCPjRmMhKQDDyG>p;+AUYY**`$_t+Fd_E89Wbxlyr zy11=3f97>3NA^{u?`XX~@uv12c3GQ4Kj(eklDOJ7b^Y}EQ^AiHTX@~h3Vj)V&c5~P z?m3;i?UnxY$b9@)Am4lI9cTI075D$WSzExp{;|8|9e3;8J6z@2g@uRS+JBe1E6x`i z*QaUHsw28r-|X2^{l#Cd+)Is#(w9rx@m!Zfch*N@cYFnpKVThj_Fw;bpHv$6k%(kwmmR&zcTR!(f^c)BzniYG?!UTi-p+u1 zs(1dxXuSQjJ3xVb#jkZTo6a#s%OA*@B|E1e-0=NMi}`yCugFvuJhJgyDK1L7f-Q~sWya*q9nTa6(XsDA0a(>&2a{sD^Wnuh!%;)^GMrXSD}21EzS6xrX!du-mF zY!tQ+F=>k9tX;M9`R~7VcJgjAe=bPqC~#S1nz6l2&fEWG@t%MiF3AynN17)WB}WwO zYZqi!mpbgEA~)xYH1l<-1j9?`g;eC`OfzXS-P!(-P4iZ>kr4m1XtVc;I~=>dEoeK^ zd}Y6n^U$zQLg*ftYcG? zTeM;Q`FcL--%4sl=MS#a!wRb*W5z1bxX~Auql70XEbSs{9GOoQQ zoX$I+FIc@GAXn(klqqNU3^yFU!jP@~{m+e+vJ#1_&Pz;Dm0QJapLux0H5Hv_^ORSr zeJd#RvgYSq+_k1zt9k9AjCYnkVPey~kB414e?F4GL~=4eG33Cw?z@EH?Y0-A&tPYz!Z=`YX>T z+JRa<=hRSIJ^ON>*)G=&+7)^GZLH8c^KIPU9gp0VZIuPpeyg1OpPty&EQfM0 zh{@W7>^Ny#f9F=?uNu3j^SZCk6Y*MIQ*QZ4ZD)0(XTOb^YD=CJci=N0*{tNIl1Bf_8aDc_Ws zA1h03+B^R{*g8&R?^wffD0k*ukjvH;`Abz)%B$SYKkM|bdg-lso9@nevwN*j%l1vB z8FRPjOjpg15^%~`CI7m!qJBrTD#!ZiuP3a1mAa#KZE?Qaj;BfKptj(v>mD=14JIrF4mg!yEtibr z%EC2%xb0Z1_{bSrdL=LU?Kr)^=J-2~a*d~Fmv{cC29=51>ciGIwB_iVR=@t9@D0*f z$^3c9_Dt)0uGQhSu{Xr#v}nEMDSv&~-F-*v`%|yWUYE|9aya(y=e!-!`A0dwpQ=2s zZdj`6{&CCWFKhijtvUI5r~lLBBd7e+xU=@E)^Fchb@h5{?m^FWm*y30x0|Eq+R^mk zZZxPd;c0p2X*B<#yH(!CcdQPtKXA%$`$|#8H+fUubN!YovMl0!-|f18p6r=d^Z!1L znRel))x$b}<2!4ewsCy_R5N)~#hKg(YmD#CmUuDy%=-H;V)pJnsbh3nuwFRt;nx!~ zEx%{nIjFm2=BoCc?zz=%IwvZY=Wg9o{Qb!vhp(>UresLHjC=cX+$zVXUw^YzpAtIxVxXxxXjlUD2HJ!qAPJ1O{{|NF%i zZ|4<+cmMkO4IFa)MLYV-ZtW0#ckR)X!+STlM(#P6yCdvx+WOP=Tu)Q-c{R8Fcb!s| z_1;KttvJ8oozG$|VrL8X|M`5AYsZ#c(&w1aSWZREA9%)v*^J@lZ zsR!<4b@}z4<&$qR8D6`=Aei@U24^!D{~B&|1AsbI#veXC-&>{eza> zUCDX%Q{FCHesM|v(b@nh-{PqoAHLI>P@uo${z1-i?w#op4-af?kY~(!b+f@~$M>%b znuYTikKYlSe4hEB%6#A`R zy}VC9_5QACDc+EqHwy0SPAGUCed8c!dE1@I-nWBqPKx?%u{QtYQchN<oqz9ee~Yu?or?k=6%bLk&GOl?oyQ?O*Tg<%h;V+_n11b8RgusKXOL8M|l@rnlO!d{R!I@yMKGv{fzE$G+TK$x`VBO zXD54o$ugOup8WU4LElc^pKroH=Y;K#=@Uv%ZI^IKs;b;?z0A>KV)dfelBN=x3cKfg z54pcI)^(fXyUMahjLe0XB#bX?U2b$Q-TZ{@jOXv(X?+m#<+H#2MDDR=jdhGp!^(GN zDpL0xqL&oUyU)yUVcXd~&$qaGnRoB?mT+gUPhQM-4ir7GQ4x+Z^^Jm7KVol}7J%as zTw=%e?>xBiZJ*qmCg#Wu&7gEMdwykq|L@qM`KyJe8cb+jsUmwv(thW2aX%;S9WLzU z;E|Ev%`dHL_Q(GcHQ4(3l_nwOV!V(e!GKwN5Sk zpb5^nbpsR(Z{@)XfvZ9zG49r>lKJPuBok-@jM; z{--dT{gpZExqVMd)maM~pp`s_dM3l0K0Z6qozLU1I&Ybt`_9H{&fNd&rxk4fz&@Yn zX>i0|H~%-gpH&;)K6uz|{+-FI=h=wZT?=;F$$YhPuh(lE72*Gn-=F`Y=P$@?UuISD z;oe)V?@Jn|e|J2Ut=hkzcg3Dd8+FX?-qoA^V0rDt)UT6fT$_333-i@wKP#+6C%69c zyxzFxrvHo1tNl0MKbXEZ`o^xiJ9k}MaH~C9{P*`imET<-em%E-Po$W$M2&Xzk5usu z_YeN&F1dCv_Nm;1AMXp?w|%bOSNbnnZr^#kpKpIm-TmQL;G2fiuP<0_j-7V%mQ{lC zy1t!^&ri&or+UtA^4`$8O*S@4^_zCBiGCdr8?g1v=}C>c6RIBs{LgW)sGO$Ouv;~x z|3`e?-p?KO#j+L$49!`t?%MGGZtjkjx69hQ``2;@em|Jl{Fm?%nqYkskNUJy+^--_Nr; zb1(JdcU$K4xi9Y>ak%eTF8&VG2I1j2RK)&1e)~$p(Z{n;Do{ZmOSDV*WFM#+bB zjUmS8=dPLa-g44$7rr;g4xOy$)(c->b!}ocZ-e}4**)oZO{{8F)g^8J zd-~Zw*5&Q2x|){0BzU1!P=exV**&}RvaNTt+HCn0#XR?{-}4PuThrE0uMeB;9pzUx zW!u$Nn|{83@1OW}Rkw77BHM$8I|qMPf4}%5=Bee3e|+~g=iPkt#rnsp#3PSN^A2+^ z|NZN~$SKRNkT3gg{1Xq%Dt&N%j=Xf(cj;C4r(S=1?X|_%l4+;&Zd85D3$*3lwVO## z(&|1lPhnb<&ekQ%3(jx1TVJ0O@s5@I{?zMh|Cc6|KasPzQe3e3S9-nWbk&l5epZe? zihVm3`@S^Xa9De}VtdKD+jmpg-gMl#+?uyv{Pf2x*%#~ot=RC@>e!;ZuZ3rL4Hi}{ zo&3RSgJ}_e%*uI_&5g3+*WGS@E!E&VvHHQ~ID4}kRnbYjdmh#B?+N_3ap45ByuUXl z-2bj1Qp7KF>CeW8Py1Wh|E&@%Xim=CdoDJ1Gb>X?PEP%j@^~e9Q^?{zb4bA=))`%Q zg0Jt|zVXAf0^3Oex1N?W@+`l3@a5f5nc~#~@8Wdsf7|i(+S7dI{r_!Gw=d&7v+NE? z^2xkA&);vp-2d+Gv{&mU#6*=YWO#P*{ev&>wEA}b4cs<+p4;VJ_J!%0CcX~sb?nQ_ zw@;{U6XcWO{vpV)p_N^B&OKewn9dz#p$}d6bQQjb+}X>$siywX=}Q?4%sx7ouQ#!_ z*t@&+&S&?ZYoe@^|~ zbf8&&7xNQ2mhzvwznoLny}J4Ap9``X4`)a}lKQRv{T!30%>l=EjPoj|+3&c-`QzaX z=>_faQcU(w;BvKsftJF=6*4&bYL&fzkY|g=TfEU*Qf9AJ>C9eq4k7Y`rj|)Gai5Oz_DN-e8uru zL-TXCOnny*E=~mXptl{|(_Y-)kX-U%2Dm+xYw(`YLXyGaFsN4Tt>pK4oWk%x2sFq9 zUNkR#{7!<%b#aD1aC0j89A^L9;?lEgiNR}2D2#Zaq-f-{v=R}8)33iue za~+R*BDZD=Z<9||+Ua>WeAy0ZJ&{`z$XBB>Pu0UdqUlaEtHgUTtzsKtg%`@-9YV8b zBwyMr^OAkm30nt?lqwzfca5uFtvDXAV*Q%pMGU@AVLulL^=UFU~Ownk)Ig7;KR|{)Rp4gl&M+qnk`G*{x34 zUT}DHlj9{j*9qGheMdISUgA$v{+^&GbbgtK{fw?V&7B@L(aL`lzopr0E05Fn*aa+ diff --git a/lbtt/doc/intersectioncheck.txt b/lbtt/doc/intersectioncheck.txt deleted file mode 100644 index c2b7fa447..000000000 --- a/lbtt/doc/intersectioncheck.txt +++ /dev/null @@ -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 # - ################# diff --git a/lbtt/doc/lbtt.texi b/lbtt/doc/lbtt.texi deleted file mode 100644 index 7427c0745..000000000 --- a/lbtt/doc/lbtt.texi +++ /dev/null @@ -1,5166 +0,0 @@ -\input texinfo @c -*-texinfo-*- -@c %**start of header -@setfilename lbtt.info -@settitle @command{lbtt} -@afourpaper -@c %**end of header - -@smallbook - -@ifnottex -@ifhtml -@section @command{lbtt} -@end ifhtml -This file documents how to use the LTL-to-B@"uchi -translator testbench @command{lbtt}. - -Copyright @copyright{} 2005 Heikki Tauriainen -@ifinfo -@email{heikki.tauriainen@@tkk.fi} -@end ifinfo -@ifnotinfo -@ifnothtml -<@email{heikki.tauriainen@@tkk.fi}> -@end ifnothtml -@end ifnotinfo - -@ifhtml -@html -
-@end html -@end ifhtml -Permission is granted to make and distribute verbatim -copies of this manual provided the copyright notice and -this permission notice are preserved on all copies. - -@ignore -Permission is granted to process this file through TeX -and print the results, provided the printed document -carries a copying permission notice identical to this -one except for the removal of this paragraph (this -paragraph not being relevant to the printed manual). - -@end ignore -Permission is granted to copy and distribute modified -versions of this manual under the conditions for -verbatim copying, provided also that the section -entitled ``GNU General Public License'' is included exactly -as in the original, and provided that the entire resulting -derived work is distributed under the terms of a -permission notice identical to this one. - -Permission is granted to copy and distribute -translations of this manual into another language, -under the above conditions for modified versions. -@ifhtml -@html -
-@end html -@end ifhtml -@end ifnottex - -@iftex -@titlepage -@title @command{lbtt} - -@subtitle LTL-to-B@"uchi Translator Testbench -@subtitle @today, @command{lbtt} Versions 1.2.x -@author Heikki Tauriainen <@email{heikki.tauriainen@@tkk.fi}> -@page -@vskip 0pt plus 1filll -Copyright @copyright{} 2005 Heikki Tauriainen -<@email{heikki.tauriainen@@tkk.fi}> - -The latest version of this manual can be obtained from@* -<@url{http://www.tcs.hut.fi/Software/lbtt/}>. - -Permission is granted to make and distribute verbatim -copies of this manual provided the copyright notice and -this permission notice are preserved on all copies. - -Permission is granted to copy and distribute modified -versions of this manual under the conditions for -verbatim copying, provided also that the section -entitled ``GNU General Public License'' -is included exactly as in the original, and provided -that the entire resulting derived work is distributed -under the terms of a permission notice identical to this -one. - -Permission is granted to copy and distribute -translations of this manual into another language, -under the above conditions for modified versions. -@end titlepage - -@contents -@end iftex - -@ifnottex -@node Top, Copying, , (dir) -@top @command{lbtt} - -@command{lbtt} is a tool for testing implementations of algorithms -for translating propositional linear temporal logic formulas into -B@"uchi automata. - -This is edition 1.2.0 of the @command{lbtt} documentation. This edition -applies to @command{lbtt} versions 1.2.x. - -@command{lbtt} is free software, you may change and redistribute it -under the terms of the GNU General Public License. @command{lbtt} -comes with NO WARRANTY. See @ref{Copying} for details. - -@menu -* Copying:: GNU General Public License. - -* Overview:: A short introduction to @command{lbtt}. -* Test methods:: Description of the tests @command{lbtt} - performs. - -* Invocation:: How to run the program. -* Interpreting the output:: Explanation of @command{lbtt}'s output messages. -* Analyzing test results:: Working with @command{lbtt}'s internal - commands. - -* Interfacing with lbtt:: Interfacing LTL-to-B@"uchi translators - with @command{lbtt}. - -* References:: List of references. - -* Definitions:: A reference of the formal definitions of - the various objects that @command{lbtt} - manipulates. - -* Configuration file option index:: -* Command line option index:: -* User command index:: -* Concept index:: -@end menu -@end ifnottex - - -@node Copying, Overview, Top, Top -@include gpl.texi - - - -@node Overview, Test methods, Copying, Top -@chapter Overview - -@cindex model checking -@command{lbtt} is a tool for testing programs that translate -formulas expressed in propositional linear temporal logic (@dfn{LTL}) into -B@"uchi automata. These finite-state automata over infinite words are -used e.g.@: in automata-theoretic model checking -@ifnottex -@ref{[VW86]}, -@ref{[Var96]}, -@end ifnottex -@iftex -[VW86, Var96], -@end iftex -where they can help in detecting errors in the specifications of finite-state -hardware or software systems. Usually the model checking procedure involves -first composing an -automaton with a formal model of a given system, and the result of the -composition reveals whether any computation path of the system violates -some property that the automaton represents. -(For an introduction to model checking techniques in general, see, -for example, -@ifnottex -@ref{[CGP99]}.) -@end ifnottex -@iftex -[CGP99].) -@end iftex - -The property to be model checked can be specified as an -LTL formula, and the B@"uchi automaton used for model checking is obtained -automatically from the formula with a translation algorithm. -(For descriptions and optimization techniques for such algorithms, see the -references, for example, -@ifnottex -@ref{[VW86]}, -@ref{[Isl94]}, -@ref{[GPVW95]}, -@ref{[Cou99]} -@ref{[DGV99]}, -@ref{[Ete99]}, -@ref{[SB00]}, -@ref{[EH00]}, -@ref{[EWS01]}, -@ref{[GO01]}, -@ref{[Gei01]}, -@ref{[Sch01]}, -@ref{[Wol01]}, -@ref{[Ete02]}, -@ref{[GL02]}, -@ref{[GSB02]}, -@ref{[Thi02]}, -@ref{[Fri03]}, -@ref{[GO03]}, -@ref{[Lat03]}, -@ref{[ST03]}.) -@end ifnottex -@iftex -[VW86, Isl94, GPVW95, Cou99, DGV99, Ete99, SB00, EH00, EWS01, GO01, -Gei01, Sch01, Wol01, Ete02, GL02, GSB02, Thi02, Fri03, GO03, Lat03, ST03].) -@end iftex -In practice, ensuring the correctness of the implementation of such a -translation algorithm is crucial to guarantee the soundness of the -implementation of a model checking procedure. - -The goal of @command{lbtt} is to assist implementing LTL-to-B@"uchi -translation algorithms correctly by providing an automated -testing environment for LTL-to-B@"uchi translators. Testing consists of running -LTL-to-B@"uchi translators on randomly generated (or user-specified) LTL -formulas as input and then performing simple consistency checks on the -resulting automata to test whether the translators seem to function correctly -in practice. (See -@ifnottex -@ref{[TH02]} -@end ifnottex -@iftex -[TH02] -@end iftex -for more information on the theory behind the testing methods.) If the test -results suggest that there is an error in an implementation, -@command{lbtt} can generate sample data which causes -a test failure and which may also be useful for debugging the -implementation. - -Additionally, the testing environment can be used for very basic profiling of -different LTL-to-B@"uchi translators to evaluate their performance. - -@noindent -@emph{Note: although @command{lbtt} might be able to detect inconsistent -behavior in an LTL-to-B@"uchi translator, it is only a testing tool and is -therefore incapable of formally proving any translation algorithm -implementation to be correct. Therefore, the test results should never be used -as the sole basis for any formal conclusions about the correctness of an -implementation. -} - - - - - -@node Test methods, Invocation, Overview, Top -@chapter Test methods - -This chapter describes the algorithms @command{lbtt} uses for generating -input for the tests and introduces some terminology. -A short description of each test is also included -together with the outline of @command{lbtt}'s testing procedure. However, the -chapter is not intended to be a thorough introduction to the theoretical -background of the different tests; see, for example, -@ifnottex -@ref{[TH02]} -@end ifnottex -@iftex -[TH02] -@end iftex -or -@ifnottex -@ref{[Tau00]} -@end ifnottex -@iftex -[Tau00] -@end iftex -for more information. - -@menu -* Random input generation:: How @command{lbtt} generates input for the - tests. -* Testing procedure:: Outline of @command{lbtt}'s testing - procedure. -* Model checking result cross-comparison test:: - Model checking the same LTL formula in - a fixed state space using different - LTL-to-B@"uchi translators should - give the same model checking result. -* Model checking result consistency check:: - Model checking two complementary LTL - formulas in the same state space using - an LTL-to-B@"uchi translator should - give consistent results. -* Automata intersection emptiness check:: - The intersection of the languages - accepted by two B@"uchi automata - constructed from two complementary - LTL formulas should be empty. -@end menu - - - -@node Random input generation, Testing procedure, Test methods, Test methods -@section Random input generation - -By default, all tests @command{lbtt} makes are based on randomly generated -input. However, the LTL formulas used as input for the LTL-to-B@"uchi -translators can be optionally given by the user by telling @command{lbtt} to -read LTL formulas from a file or from standard input -(@pxref{--formulafile,,@samp{--formulafile} command line option}). - -@cindex state space -Additionally, some of the tests make use of randomly generated -``state spaces'', which are basically directed labeled graphs with labels on -nodes with the additional requirement of having at least one arc leaving -each node. The label of each node is a subset of a finite collection of atomic -propositions -@cindex atomic proposition -(an uninterpreted set of assertions which may or may not hold in a -state), which occur also in the LTL formulas used in the tests. - -The following sections describe how @command{lbtt} generates input for the -tests and list the parameters which can be used to adjust the behavior of -the input generation algorithms. - -@menu -* Random LTL formulas:: How @command{lbtt} generates random - LTL formulas. -* Random state spaces:: How @command{lbtt} generates random - state spaces. -@end menu - - - -@node Random LTL formulas, Random state spaces, Random input generation, Random input generation -@subsection Random LTL formulas - -@cindex random LTL formula -@cindex LTL formula, random - -The LTL formulas used by @command{lbtt} are built from -atomic propositions (with names of the form -@ifhtml -@samp{p}@var{n} -@end ifhtml -@ifnothtml -@samp{p@var{n}} -@end ifnothtml -for some nonnegative integer @var{n}), the Boolean constants -@ifnottex -@samp{true} and @samp{false}, -@end ifnottex -@iftex -@tex -\sc{True} -@end tex -and -@tex -\sc{False}, -@end tex -@end iftex -and logical or temporal operators. @command{lbtt} supports the -following logical operators: - -@cindex supported LTL formula operators -@cindex LTL formula operators, supported -@itemize @bullet -@item -@cindex @samp{\/} (LTL formula operator) -@cindex @emph{or} (LTL formula operator) -@cindex disjunction (LTL formula operator) -logical disjunction -@iftex -(@tex -$\vee$ -@end tex ---- @samp{\/} as shown in output messages), -@end iftex -@ifnottex -(@samp{\/} as shown in output messages), -@end ifnottex - -@item -@cindex @samp{/\} (LTL formula operator) -@cindex @emph{and} (LTL formula operator) -@cindex conjunction (LTL formula operator) -logical conjunction -@iftex -(@tex -$\wedge$ -@end tex ---- @samp{/\}), -@end iftex -@ifnottex -(@samp{/\}), -@end ifnottex - -@item -@cindex @samp{!} (LTL formula operator) -@cindex @emph{not} (LTL formula operator) -@cindex negation (LTL formula operator) -logical negation -@iftex -(@tex -$\neg$ -@end tex ---- @samp{!}), -@end iftex -@ifnottex -(@samp{!}), -@end ifnottex - -@item -@cindex @samp{->} (LTL formula operator) -@cindex implication (LTL formula operator) -logical implication -@iftex -(@tex -$\rightarrow$ -@end tex ---- @samp{->}) -@end iftex -@ifnottex -(@samp{->}) -@end ifnottex - -@item -@cindex @samp{<->} (LTL formula operator) -@cindex equivalence (LTL formula operator) -logical equivalence -@iftex -(@tex -$\leftrightarrow$ -@end tex ---- @samp{<->}) -@end iftex -@ifnottex -(@samp{<->}) -@end ifnottex - -@item -@cindex @samp{xor} (LTL formula operator) -@cindex exclusive or (LTL formula operator) -logical ``exclusive or'' -@iftex -(@tex -$\oplus$ -@end tex ---- @samp{xor}) -@end iftex -@ifnottex -(@samp{xor}) -@end ifnottex - -@end itemize - -@noindent -and the following temporal operators: - -@itemize @bullet -@item -@cindex @samp{X} (LTL formula operator) -@cindex next time (LTL formula operator) -``Next time'' -@iftex -(@tex -$\bf{X}$ -@end tex ---- @samp{X}), -@end iftex -@ifnottex -(@samp{X}), -@end ifnottex - -@item -@cindex @samp{U} (LTL formula operator) -@cindex until (LTL formula operator) -@cindex strong until (LTL formula operator) -``(Strong) Until'' -@iftex -(@tex -$\bf{U}$ -@end tex ---- @samp{U}), -@end iftex -@ifnottex -(@samp{U}), -@end ifnottex - -@item -@cindex @samp{W} (LTL formula operator) -@cindex weak until (LTL formula operator) -@cindex unless (LTL formula operator) -``Weak Until'' (also known as ``Unless'') -@iftex -(@tex -$\bf{W}$ -@end tex ---- @samp{W}), -@end iftex -@ifnottex -(@samp{W}), -@end ifnottex - -@item -@cindex @samp{F} (LTL formula operator) -@cindex finally (LTL formula operator) -@cindex eventually (LTL formula operator) -``Finally'' (``Eventually'') -@iftex -(@tex -$\bf{F}$ -@end tex ---- @samp{<>}) -@end iftex -@ifnottex -(@samp{<>}) -@end ifnottex - -@item -@cindex @samp{B} (LTL formula operator) -@cindex before (LTL formula operator) -``Before'' -@iftex -(@tex -$\bf{B}$ -@end tex ---- @samp{B}) -@end iftex -@ifnottex -(@samp{B}) -@end ifnottex - -@item -@cindex @samp{V} (LTL formula operator) -@cindex release (LTL formula operator) -@cindex weak release (LTL formula operator) -``(Weak) Release'', the dual of ``(Strong) Until'' -@iftex -(@tex -$\bf{V}$ -@end tex ---- @samp{V}), -@end iftex -@ifnottex -(@samp{V}), -@end ifnottex - -@item -@cindex @samp{M} (LTL formula operator) -@cindex strong release (LTL formula operator) -``Strong Release'', the dual of ``Weak Until'' -@iftex -(@tex -$\bf{M}$ -@end tex ---- @samp{M}), -@end iftex -@ifnottex -(@samp{M}), -@end ifnottex - -@item -@cindex @samp{G} (LTL formula operator) -@cindex globally (LTL formula operator) -@cindex always (LTL formula operator) -@cindex henceforth (LTL formula operator) -``Globally'' (``Always'', ``Henceforth'') -@iftex -(@tex -$\bf{G}$ -@end tex ---- @samp{[]}). -@end iftex -@ifnottex -(@samp{[]}). -@end ifnottex - -@end itemize - -@noindent -See @ref{LTL formulas}, for a reference on the exact semantics of these -operators. - -@cindex parameters for random LTL formula generation algorithm -@cindex random LTL formula, parameters for generation algorithm -@cindex LTL formula, parameters for generation algorithm -The behavior of @command{lbtt}'s random formula generation algorithm can be -adjusted with the following parameters: - -@itemize @bullet - -@item -@cindex LTL formula, size -@cindex formula size -@cindex random LTL formula, size -Number of nodes in the parse tree of a formula (i.e., the total number of -occurrences of propositions, Boolean constants and operators in the formula). - -@item -Number of different atomic propositions that can be used for generating a -formula. (Note that this does not restrict the total number of atomic -propositions in the formula, nor the number of occurrences of any individual -proposition. However, none of the generated formulas will have more than this -number of @emph{different} atomic propositions.) - -@item -@cindex priorities for formula constants, atomic propositions and operators -@cindex constants, priorities for -@cindex atomic propositions, priorities for -@cindex operators, priorities for -Priorities for the Boolean constants and atomic propositions. The priority of -a symbol determines the relative likelihood of its occurrence in a generated -formula. The higher the priority of a symbol, the more likely it is that the -symbol will occur (with respect to the other symbols) in a generated formula; a -zero priority will exclude the symbol altogether. - -@item -Priorities for the logical and temporal operators. - -@end itemize - -@noindent -Note that the priorities for atomic symbols (Boolean constants and atomic -propositions) and the priorities of the logical and temporal operators are -independent, i.e., changing the priority of an atomic symbol does not affect -the likelihood of the occurrence of any logical or temporal operator and vice -versa. - -@ifnottex -For further details, see @ref{The formula generation algorithm} for a -pseudocode description of the algorithm used for generating random LTL -formulas. -@end ifnottex - -@node The formula generation algorithm, , Random LTL formulas, Random LTL formulas - -@subsubsection The formula generation algorithm -@cindex random LTL formula, generation algorithm -@cindex LTL formula, generation algorithm - -@command{lbtt} uses an algorithm similar to the one outlined in -@ifnottex -@ref{[DGV99]} -@end ifnottex -@iftex -[DGV99] -@end iftex -for generating random LTL formulas. The algorithm can be described in -pseudocode as follows: - -@smallexample -@r{1} function RandomFormula(@var{n} : Integer) : LtlFormula; -@r{2} if @var{n} = 1 then begin -@r{3} @var{p} := @r{random atomic proposition or} @r{TRUE} @r{or} @r{FALSE}; -@r{4} return @var{p}; -@r{5} end -@r{6} else if @var{n} = 2 then begin -@r{7} @var{op} := @r{random unary operator}; -@r{8} @var{f} := RandomFormula(1); -@r{9} return @var{op} @var{f}; -@r{10} end -@r{11} else begin -@r{12} @var{op} := @r{random unary or binary operator}; -@r{13} if @var{op} @r{is a unary operator} then begin -@r{14} @var{f} := RandomFormula(@var{n}-1); -@r{15} return @var{op} @var{f}; -@r{16} end -@r{17} else begin -@r{18} @var{x} := @r{random integer in the interval} [1,@var{n}-2]; -@r{19} @var{f1} := RandomFormula(@var{x}); -@r{20} @var{f2} := RandomFormula(@var{n}-@var{x}-1); -@r{21} return (@var{f1} @var{op} @var{f2}); -@r{22} end; -@r{23} end; -@r{24} end; -@end smallexample - -Each invocation of the algorithm returns an LTL formula with @var{n} -nodes in the formula parse tree. The behavior of the algorithm can be adjusted -by giving values for the parameters @var{n} (the number of nodes in the -formula parse tree), -@iftex -@tex -$|\it{AP}|$ -@end tex -@end iftex -@ifnottex -@math{|AP|} -@end ifnottex -(the number of different atomic propositions), and -@iftex -@tex -$\it{pri}(\it{SYMBOL})$ -@end tex -@end iftex -@ifnottex -pri(@var{symbol}) -@end ifnottex -(the priorities for the different symbols). - -@cindex priorities for formula constants, atomic propositions and operators -@cindex constants, priorities for -@cindex probabilities for formula constants and atomic propositions -@cindex constants, computing probabilities for -In @command{lbtt}'s implementation of the above algorithm, the priority of a -symbol determines the probability with which the symbol is chosen -into a generated formula each time line 3, 7 or 12 of the algorithm is -executed. For Boolean constants -@ifnottex -@samp{true} and @samp{false} -@end ifnottex -@iftex -@tex -\sc{True} -@end tex -and -@tex -\sc{False} -@end tex -@end iftex -(line 3 of the algorithm), the probability is given by the equation - -@ifnottex -@math{pri(@var{CONSTANT}) / (pri(AP) + pri(@samp{true}) + pri(@samp{false}))} -@end ifnottex -@iftex -@tex -\smallskip -\center{$\it{pri}(\it{CONSTANT}) / \big(\it{pri}(\it{AP}) + \it{pri}($\sc{True}$) + \it{pri}($\sc{False}$)\big)$} -\smallskip -@end tex -@end iftex - -@noindent -where @var{CONSTANT} is either -@ifnottex -@samp{true} or @samp{false}, -@end ifnottex -@iftex -@tex -\sc{True} -@end tex -or -@tex -\sc{False}, -@end tex -@end iftex -and -@ifnottex -pri(@math{AP}) -@end ifnottex -@iftex -@tex -$\it{pri}(\it{AP})$ -@end tex -@end iftex -is the total priority of all atomic propositions. - -@cindex priorities for formula constants, atomic propositions and operators -@cindex atomic propositions, priorities for -@cindex probabilities for formula constants and atomic propositions -@cindex atomic propositions, computing probabilities for -The probability of choosing a particular atomic proposition into a formula -(line 3) is - -@ifnottex -@math{pri(AP) / (|AP| * (pri(AP) + pri(@samp{true}) + pri(@samp{false})))}, -@end ifnottex -@iftex -@tex -\smallskip -\center{$\it{pri}(\it{AP}) / \Big(|\it{AP}|\times\big(\it{pri}(\it{AP}) + \it{pri}($\sc{True}$) + \it{pri}($\sc{False}$)\big)\Big)$} -\smallskip -@end tex -@end iftex - -@noindent -where -@ifnottex -@math{|AP|} -@end ifnottex -@iftex -@tex -$|AP|$ -@end tex -@end iftex -and -@ifnottex -pri(@math{AP}) -@end ifnottex -@iftex -@tex -$\it{pri}(\it{AP})$ -@end tex -@end iftex -are as defined above. - -@cindex priorities for formula constants, atomic propositions and operators -@cindex operators, priorities for -@cindex probabilities for formula operators -@cindex operators, computing probabilities for -Line 7 of the algorithm concerns choosing a unary operator -@ifnottex -(@samp{!}, @samp{X}, @samp{<>} or @samp{[]}) -@end ifnottex -@iftex -@tex -($\neg$, $\bf{X}$, $\bf{F}$ or $\bf{G}$) -@end tex -@end iftex -into a formula. Here the probability of choosing the unary operator -@iftex -@tex -$\it{op}$ -@end tex -@end iftex -@ifnottex -@var{op} -@end ifnottex -is given by the equation - -@iftex -@tex -$$ -\it{pri}(\it{op}) / \sum_{\rm{op}^\prime \in \{\neg, \bf{X}, \bf{F}, \bf{G}\}}\it{pri}(\it{op}^\prime) -$$ -@end tex -@end iftex -@ifnottex -@math{pri(@var{op}) / Sum (pri(@var{op'}))}, -@end ifnottex - -@noindent -where -@iftex -@tex -$\it{op}^\prime$ -@end tex -@end iftex -@ifnottex -@var{op'} -@end ifnottex -ranges over all unary operators. - -Finally, at line 12 of the algorithm, the probability of choosing the (unary or -binary) operator -@iftex -@tex -$\it{op}$ -@end tex -@end iftex -@ifnottex -@var{op} -@end ifnottex -into the formula is - -@iftex -@tex -$$ -\it{pri}(\it{op}) / \sum_{\rm{op}^\prime \in \{\neg, \vee, \wedge, \rightarrow, \leftrightarrow, \oplus, \bf{X}, \bf{U}, \bf{W}, \bf{F}, \bf{B}, \bf{V}, \bf{M}, \bf{G}\}}\it{pri}(\it{op}^\prime) -$$ -@end tex -@end iftex -@ifnottex -@math{pri(@var{op}) / Sum (pri(@var{op'}))}, -@end ifnottex - -@noindent -where -@iftex -@tex -$\it{op}^\prime$ -@end tex -@end iftex -@ifnottex -@var{op'} -@end ifnottex -ranges over all unary and binary -@ifnottex -operators (@samp{!}, @samp{\/}, @samp{/\}, @samp{->}, @samp{<->}, @samp{xor}, -@samp{X}, @samp{U}, @samp{W}, @samp{<>}, @samp{B}, @samp{V}, @samp{M}, -@samp{[]}). -@end ifnottex -@iftex -operators. -@end iftex - -An analysis of this algorithm is included in an appendix of -@ifnottex -@ref{[Tau00]}. -@end ifnottex -@iftex -[Tau00]. -@end iftex -The analysis shows how to use the operator priorities to calculate the -expected number of occurrences of an operator in a randomly generated -formula. @command{lbtt} can optionally compute the expected operator -distribution for a given combination of operator priorities; see the -@samp{--showoperatordistribution} command line option -(@pxref{--showoperatordistribution,,@samp{--showoperatordistribution} command line option}) -for more information. - -See also the web page@* -@ifinfo -@url{http://www.tcs.hut.fi/Software/lbtt/formulaoptions.php} -@end ifinfo -@ifnotinfo -<@uref{http://www.tcs.hut.fi/Software/lbtt/formulaoptions.php}> -@end ifnotinfo -for an interface to a small database for adjusting the operator priorities -towards certain simple distributions. - - - -@node Random state spaces, , Random LTL formulas, Random input generation -@subsection Random state spaces - -@cindex state space -@cindex state space, random -@cindex random state space -State spaces are needed as input for tests only in the -model checking result cross comparison test -(@pxref{Model checking result cross-comparison test}) and the -model checking result consistency check -(@pxref{Model checking result consistency check}). -The state spaces are directed labeled graphs, each node of which is labeled -with a randomly chosen set of atomic propositions (the propositions that -hold in the state corresponding to the graph node). In addition, each state of -the state space always has at least one successor. - -@command{lbtt} provides three different random state space generation -algorithms that differ in the structure of the generated state spaces. The -common parameters for each of these algorithms are: - -@cindex state space, generation parameters -@cindex random state space, generation parameters -@cindex parameters for random state space generation algorithm -@itemize @bullet - -@item -Number of states in the state space. - -@item -Maximum number of different atomic propositions allowed in the label of any -state of the state space. - -@item -The probability with which each atomic proposition should hold in a state of -the state space (which is, for simplicity, common to all atomic propositions). - -@end itemize - -@noindent -The different types of random state spaces that can be generated are: -@cindex state space, generation modes - -@enumerate - -@item -@cindex random connected graph -@cindex graph density -@cindex density (of a state space) -@cindex state space, density -@cindex random state space, density -Random connected graphs. These state spaces are guaranteed to have at least -one state such that every other state of the state space is reachable from -this state. In addition to the three above parameters, the behavior of the -algorithm generating these state spaces can be adjusted by specifying a -probability which approximates the @dfn{density} of the graph, i.e., the -probability that there is a directed edge from a state @var{x} to another -state @var{y}, where @var{x} and @var{y} are any two states in the state -space. For more details, see @ref{Algorithm for generating connected graphs}. - -@item -@cindex random graph -Random graphs. These state spaces are constructed simply by taking all -pairs (@var{x}, @var{y}) of states in the state space and connecting state -@var{x} to state @var{y} with a user-specified probability that approximates -the graph density. - -@item -@cindex random path -Random paths. A random path is simply a non-branching sequence of states, -where the last state of the sequence is connected to a randomly chosen state -earlier in the sequence. - -@end enumerate - -@cindex enumerated path -@command{lbtt} also includes a state space generation algorithm which -systematically enumerates all ``paths'' (see above) of a given size with a -given number of atomic propositions in each state. If -@iftex -@tex -$|S|$ -@end tex -@end iftex -@ifnottex -@math{|S|} -@end ifnottex -is the number of states in the path and -@iftex -@tex -$|\it{AP}|$ -@end tex -@end iftex -@ifnottex -@math{|AP|} -@end ifnottex -is the number of atomic propositions in each state of the path, it is easy to -see that the number of different paths having these parameters is - -@iftex -@tex -$$|S|\cdot 2^{|S|\cdot|AP|},$$ -@end tex -@end iftex -@ifnottex -@math{|S| * 2^(|S| * |AP|)}, -@end ifnottex - -@noindent -a number which grows exponentially in the product of the two parameters. -Obviously, this makes the exhaustive enumeration of all paths of a given size -practicable only for very small values of -@iftex -@tex -$|S|$ -@end tex -@end iftex -@ifnottex -@math{|S|} -@end ifnottex -and -@iftex -@tex -$|\it{AP}|$. -@end tex -@end iftex -@ifnottex -@math{|AP|}. -@end ifnottex - -In practice, testing should be started using only very small state spaces -(say, with only 10--50 states and a small density) regardless of the particular -algorithm chosen for generating the state spaces. The size of the state spaces -can then be increased if @command{lbtt}'s memory consumption and the time spent -running the tests stay within acceptable limits. - - - -@node Algorithm for generating connected graphs, , Random state spaces, Random state spaces - -@subsubsection Algorithm for generating connected graphs -@cindex random connected graph, generation algorithm -@cindex random state space, algorithm for generating random connected graphs -@cindex state space, algorithm for generating random connected graphs - -@command{lbtt} uses the following algorithm for generating random connected -graphs: - -@smallexample -@r{1} function RandomGraph(@var{n} : Integer; @var{d} : Real in [0.0,1.0]; - @var{t} : Real in [0.0,1.0]) : Graph; -@r{2} @var{S} := @{s1, s2, ..., sn@}; -@r{3} @var{NodesToProcess} := @{s1@}; -@r{4} @var{UnreachableNodes} := @{s2, s3, ..., sn@}; -@r{5} @var{Edges} := @{@}; -@r{6} while @var{NodesToProcess} @r{is not empty} do begin -@r{7} @var{state} := @r{a random node in} @var{NodesToProcess}; -@r{8} @r{remove} @var{state} @r{from} @var{NodesToProcess}; -@r{9} @var{Label}(@var{state}) := @{@}; -@r{10} for @r{all} @var{p} @r{in} @var{AP} do -@r{11} if RandomNumber(0.0, 1.0) < @var{t} then -@r{12} @r{insert} @var{p} @r{into} @var{Label}(@var{state}); -@r{13} if @var{UnreachableNodes} @r{is not empty} then begin -@r{14} @var{state'} := @r{a random node in} @var{UnreachableNodes}; -@r{15} @r{remove} @var{state'} @r{from} @var{UnreachableNodes}; -@r{16} @r{insert} @var{state'} @r{into} @var{NodesToProcess}; -@r{17} @r{insert} (@var{state},@var{state'}) @r{into} @var{Edges}; -@r{18} end; -@r{19} for @r{all} @var{state'} @r{in} @var{S} do -@r{20} if RandomNumber(0.0, 1.0) < @var{d} then begin -@r{21} @r{insert} (@var{state},@var{state'}) @r{into} @var{Edges}; -@r{22} if @var{state'} @r{is in} @var{UnreachableNodes} then begin -@r{23} @r{remove} @var{state'} @r{from} @var{UnreachableNodes}; -@r{24} @r{insert} @var{state'} @r{into} @var{NodesToProcess}; -@r{25} end; -@r{26} end; -@r{27} if @r{there is no edge} (@var{state},@var{state'}) @r{in} @var{Edges} - @r{for any} @var{state'} @r{in} @var{S} then -@r{28} @r{insert} (@var{state},@var{state}) @r{into} @var{Edges}; -@r{29} end; -@r{30} return <@var{S}, @var{Edges}, s1, @var{Label}>; -@r{31} end; -@end smallexample - -The algorithm receives the parameters @var{n} (number of states in the -state spaces), @var{d} (approximate density of the generated graph) and -@var{t} (the probability with which each of the propositions in @math{AP} -should hold in a state) and returns the generated state space as a quadruple -<@var{S}, @var{Edges}, s1, @var{Label}>. Here @var{S} is the set of -states, @var{Edges} is the set of directed edges between the states, @math{s1} -is a state from which every state of the state space can be reached, and -@var{Label} is a function which maps each state to its label (a subset of -@var{AP}). - - - -@node Testing procedure, Model checking result cross-comparison test, Random input generation, Test methods -@section Testing procedure - -@cindex testing procedure -The following figure illustrates the first two tests in @command{lbtt}'s -testing procedure: -@ifhtml -@* -@end ifhtml - -@image{testprocedure,6.5cm} - -@noindent -After obtaining an LTL formula -@ifnottex -@math{f} -@end ifnottex -@iftex -@tex -$f$ -@end tex -@end iftex -(either by reading it from a file or by calling the random formula generation -algorithm), -@command{lbtt} invokes each LTL-to-B@"uchi translator participating in -the tests in turn to construct a collection of B@"uchi automata for the formula -@ifnottex -@math{f} -@end ifnottex -@iftex -@tex -$f$ -@end tex -@end iftex -@emph{and} the negated formula -@ifnottex -@math{! f}. -@end ifnottex -@iftex -@tex -$\neg f$. -@end tex -@end iftex -Each of these automata is then composed with the -randomly generated state space, whereafter @command{lbtt} performs the -model checking result cross-comparison test -(@pxref{Model checking result cross-comparison test}) -and the model checking result consistency check -(@pxref{Model checking result consistency check}) -on the model checking results, and reports all detected failures. - -The B@"uchi automata intersection emptiness check -(@pxref{Automata intersection emptiness check}) operates as follows (note that -the LTL-to-B@"uchi translation phase is repeated in this figure only for -completeness; in reality, @command{lbtt} performs this phase only once): -@ifhtml -@* -@end ifhtml - -@image{intersectioncheck,6.5cm} - -The test procedure can then be repeated using a different LTL formula -and/or a different state space. - - - - - -@node Model checking result cross-comparison test, Model checking result consistency check, Testing procedure, Test methods -@section Model checking result cross-comparison test - -@cindex model checking result cross-comparison test -@cindex tests, model checking result cross-comparison test - -LTL model checking can be used to test whether any of the infinite paths -starting from some state of a state space satisfies a given LTL -formula. For a fixed LTL formula, this question may have a different answer in -different states of the state space, but the answer should be independent -of the details of any (correct) implementation of the LTL model checking -procedure. - -Therefore, it is possible to test LTL-to-B@"uchi translators by comparing -the results obtained by model checking an LTL formula in a fixed state space -several times, using each time a different translator for constructing a -B@"uchi automaton from the LTL formula. Differences in the model checking -results then suggest that at least one of the translators failed to translate -the LTL formula correctly into an automaton. - -@cindex model checking modes -@cindex local model checking -@cindex global model checking -To extract as much test data as possible from a state space, -@command{lbtt} will by default make the model checking result comparison -``globally'' in the state space, which means using each LTL-to-B@"uchi -translator to find @emph{all} states in the state space with an infinite -path supposedly satisfying some LTL formula and then comparing the resulting -state sets for equality. Alternatively, the test can be performed only -``locally'' in a single state of each state space (i.e., by choosing some -state of the state space and checking that all B@"uchi automata constructed -using the different translators give the same model checking result in -that state), which may speed up testing, but -will reduce the number of comparison tests. In addition, @command{lbtt} repeats -the result -cross-comparison test for the negation of each LTL formula, since model -checking also the negated formula permits making an additional consistency -check (see below) on the results computed using each implementation. - -@cindex internal model checking algorithm -@cindex using the internal model checking algorithm -@cindex tests, against internal model checking algorithm -Note: If the generated state spaces are paths (either random or -systematically enumerated, @pxref{Random state spaces}), @command{lbtt} -will then include its internal LTL model checking algorithm (a restricted model -checking algorithm used normally in test failure analysis, -@pxref{Analyzing test results}) into the model -checking result cross-comparison test. This is especially useful if there is -only one translation algorithm implementation available for testing -(in which case normal model checking result cross-comparison is obviously -redundant) but may be of advantage also in other cases by -providing an additional implementation to include in the tests. - - - -@node Model checking result consistency check, Automata intersection emptiness check, Model checking result cross-comparison test, Test methods -@section Model checking result consistency check - -@cindex model checking result consistency check -@cindex tests, model checking result consistency check - -LTL model checking tells whether any of the infinite paths starting from some -state of a state space satisfies a given LTL formula. If there -are no such paths beginning from the state, it follows that all infinite paths -beginning from the state must then satisfy the @emph{negation} of the same -formula. Since all state spaces used by @command{lbtt} always have at least -one path beginning from each state of the state space (guaranteed by the -state space generation algorithms), at least -one path beginning from any state must satisfy either the formula or its -negation, i.e., it cannot be the case that none of the paths is a model of -either formula. - -However, implementation errors in an LTL-to-B@"uchi translator used for model -checking may actually lead to this inconsistent model checking result if the -translation of either of the formulas results in an incorrect automaton, in -which case @command{lbtt} will report an error. - -@cindex model checking modes -@cindex local model checking -@cindex global model checking -Similarly to the model checking result cross-comparison test, the -model checking result consistency check can be performed either in all states -of the state space (``globally'') or only in a single state of the state -space (``locally''), with the same trade-offs between testing speed and -number of tests as described in the previous -@ifnottex -section (@pxref{Model checking result cross-comparison test}). -@end ifnottex -@iftex -section. -@end iftex - - -@node Automata intersection emptiness check, , Model checking result consistency check, Test methods -@section Automata intersection emptiness check - -@cindex B@"uchi automata intersection emptiness check -@cindex tests, B@"uchi automata intersection emptiness check - -The semantics of LTL guarantees that no model of an LTL formula -can be the model of the negation of the same formula. In terms of -B@"uchi automata, this implies that the languages accepted by automata -constructed from two complementary LTL formulas should be disjoint. -This can be confirmed by intersecting the automata (i.e., by composing the -automata to construct a third B@"uchi automaton that accepts precisely -those inputs accepted by both of the original automata) and checking the -result for emptiness. If the intersection is found to be nonempty, however, -at least one of the LTL-to-B@"uchi translator(s) used for constructing the -original automata must have failed to perform the translation of either -formula correctly. - - - -@node Invocation, Interpreting the output, Test methods, Top -@chapter Invocation - -@cindex invoking @command{lbtt} -@cindex starting @command{lbtt} -@cindex tests, starting -@cindex @command{lbtt} (executable file) -@command{lbtt} is started with the command @command{lbtt} with optional -command line parameters. Before starting the program, however, you need -to create a configuration file which lists the LTL-to-B@"uchi translators -to be tested and defines additional testing parameters. -@xref{Configuration file}. If no suitable configuration file is found or -if the configuration file cannot be processed successfully, @command{lbtt} -exits with an error message. - -After reading the configuration file, @command{lbtt} starts tests on the -LTL-to-B@"uchi translators listed in the configuration file (for -details about the testing procedure, see @ref{Test methods}). The program -exits after a predetermined number of test rounds. - -@cindex exiting @command{lbtt} -@cindex quitting @command{lbtt} -@cindex tests, aborting -If the program is started in any of its interactive modes -(see @ref{Interactivity modes}), the program -may occasionally pause to wait for user input between test rounds. Type -@samp{quit @key{ENTER}} at the prompt to exit @command{lbtt} at this -point (or see @ref{Analyzing test results}, for more information on -how to use @command{lbtt}'s internal commands). - -@menu -* Configuration file:: Description of the configuration file - format. -* Command line options:: List of command line options. -@end menu - - - -@node Configuration file, Command line options, Invocation, Invocation -@section Configuration file - -@cindex configuration file, formatting -@cindex conventions for writing configuration files - -The configuration file of @command{lbtt} contains a list of the -LTL-to-B@"uchi translators to be tested along with other options -which affect the way the tests are performed. The configuration -file is processed before starting the tests. By default, @command{lbtt} -will try to read the configuration from the file @file{config} in the -current working directory; a different file name can be specified with the -@option{--configfile=@var{filename}} command line option. - -The configuration file consists of one or more sections, each of which -provides a collection of interrelated configuration options. The general -format of the configuration file is - -@smallexample -@var{section-name} -@{ - @var{option-name} = @var{value} - @var{option-name} = @var{value} - @dots{} -@} - -@dots{} -@end smallexample - -@cindex configuration file, option values -@cindex truth values in configuration file -@cindex string values in configuration file -@cindex numeric values in configuration file - -@noindent -Section and option names are case-insensitive. Values can be numbers, -strings or truth values (@samp{yes} and @samp{no}, or equivalently, -@samp{true} and @samp{false}). String values are case-sensitive and are subject -to common quoting and escaping rules (i.e., string values containing white -space should be enclosed in quotes, or the white space characters should be -escaped with @samp{\}). - -@cindex comments in configuration file -@cindex configuration file, comments - -Comments can be included by putting a @samp{#} symbol before them; the end of -any line containing the @samp{#} character will be ignored when processing the -configuration file. - -@cindex configuration file, minimal requirements -@cindex minimal requirements for configuration files - -The configuration file must contain at least one @samp{Translator} -section specifying an LTL-to-B@"uchi translator. The other sections -are optional and can be used to override the default testing parameters. - -@menu -* Translator section:: Each LTL-to-B@"uchi translator to be - tested requires a separate - @samp{Translator} section in the - configuration file. -* GlobalOptions section:: Options for changing the general - behavior of @command{lbtt}. -* FormulaOptions section:: Options controlling the way random - LTL formulas are generated. -* StateSpaceOptions section:: Options controlling the way random - state spaces are generated. -* Sample configuration file:: An example of a configuration file. -@end menu - - -@node Translator section, GlobalOptions section, Configuration file, Configuration file -@subsection The @samp{Translator} section - -@cindex configuration file, @samp{Algorithm} section -@cindex configuration file, @samp{Implementation} section -@cindex configuration file, @samp{Translator} section -@cindex @samp{Algorithm} section (configuration file) -@cindex @samp{Implementation} section (configuration file) -@cindex @samp{Translator} section (configuration file) -@cindex configuration file, minimal requirements - -Each LTL-to-B@"uchi translator to be tested requires a separate -@samp{Translator} -section@footnote{The @samp{Algorithm} and @samp{Implementation} keywords are -recognized as aliases of the @samp{Translator} keyword.} in the configuration -file; there must be at least one such section in the file. - -The translators are assumed to be accessible -through external executable files. Therefore, this section must at a minimum -specify the full file name of the executable to run in order to invoke -the translator; see @ref{Translator interface}, for information about the -conventions @command{lbtt} uses to communicate with the -LTL-to-B@"uchi translators. - -@cindex LTL-to-B@"uchi translators, identifiers -@cindex identifiers for LTL-to-B@"uchi translators -Translators specified in the configuration file are given unique -integer identifiers in the order they are listed in the file, -starting from zero. These numbers can be used when referring to the -different translators when using @command{lbtt}'s internal commands -(@pxref{Analyzing test results}). Alternatively, the translators can be -referred to using the names specified in the configuration file. - -The following options (in alphabetical order) are available within this -section: - -@table @samp -@item Enabled = @var{TRUTH-VALUE} -@cindex enabling LTL-to-B@"uchi translators -@cindex LTL-to-B@"uchi translators, enabling -@cindex disabling LTL-to-B@"uchi translators -@cindex LTL-to-B@"uchi translators, disabling -@findex Enabled @r{[}Translator@r{]} -This option determines whether the translator should be initially included in -or excluded from the tests. The default value is @samp{Yes}. The translator -can be enabled or disabled during testing with @command{lbtt}'s -internal commands (@pxref{Test control commands}). - -@item Name = @var{STRING} -@findex Name @r{[}Translator@r{]} -This option can be used to specify a unique textual identifier for the -LTL-to-B@"uchi translator. @command{lbtt} will use this identifier when -displaying various messages concerning the implementation; the identifier can -also be used to refer to the implementation when working with @command{lbtt}'s -internal commands (@pxref{Analyzing test results}). (If no name has been -explicitly given for the translator, @command{lbtt} assigns the translator a -name of the -form @samp{Algorithm @var{n}}, where @var{n} is the running integer identifier -for the translators.) - -The identifier @samp{lbtt} is reserved for @command{lbtt}'s internal model -checking algorithm (@pxref{Model checking result cross-comparison test}). - -@item Parameters = @var{STRING} -@findex Parameters @r{[}Translator@r{]} -This option can be used to specify any additional parameters that should -be passed to the translator executable whenever running it. (The parameter -string defaults to the empty string if the option is not used.) - -@item Path = @var{STRING} -@findex Path @r{[}Translator@r{]} -This option must be given a value for each translator specified in the -configuration file. The value should be the complete file name of the program -which is used to run the translator. - -@end table - - - -@node GlobalOptions section, FormulaOptions section, Translator section, Configuration file -@subsection The @samp{GlobalOptions} section - -@cindex configuration file, @samp{GlobalOption} section -@cindex @samp{GlobalOptions} section (configuration file) - -The @samp{GlobalOptions} section includes options that affect the general -behavior of @command{lbtt}. Options available within this section are (in -alphabetical order): - -@table @samp -@item ComparisonCheck = @var{TRUTH-VALUE} -@itemx ComparisonTest = @var{TRUTH-VALUE} -@cindex tests, enabling and disabling -@cindex enabling and disabling tests -@findex ComparisonCheck @r{[}GlobalOptions@r{]} -@findex ComparisonTest @r{[}GlobalOptions@r{]} -This option can be used to enable or disable the model checking result -cross-comparison test (@pxref{Model checking result cross-comparison test}). -The test is enabled by default. - -@item ConsistencyCheck = @var{TRUTH-VALUE} -@itemx ConsistencyTest = @var{TRUTH-VALUE} -@cindex tests, enabling and disabling -@cindex enabling and disabling tests -@findex ConsistencyCheck @r{[}GlobalOptions@r{]} -@findex ConsistencyTest @r{[}GlobalOptions@r{]} -This option can be used to enable or disable the model checking result -consistency check (@pxref{Model checking result consistency check}). The test -is enabled by default. - -@item @anchor{Interactivity modes}Interactive = @var{MODE-LIST} -@cindex interactivity modes -@findex Interactive @r{[}GlobalOptions@r{]} -This option determines when @command{lbtt} should pause to wait for user input -between test rounds. The @var{MODE-LIST} is a comma-separated list of the -following modes (with no spaces in between the modes): -@table @samp -@item Always -Pause unconditionally after each test round. - -@item OnError -Pause testing only after failed test rounds. - -@item Never -Run all tests without interruption. - -@item OnBreak -Pause testing when requested by the user (for example, after receiving a break -signal from the keyboard). If this mode is not specified, @samp{lbtt} will -respond to break signals by aborting. -@end table - -(Since the first three interactivity modes are mutually exclusive, it does not -make sense to combine these modes with each other.) The default mode list -consists of the value @samp{Always}, that is, testing is paused after -every test round, and signalling a break will abort testing. - -@item IntersectionCheck = @var{TRUTH-VALUE} -@itemx IntersectionTest = @var{TRUTH-VALUE} -@cindex tests, enabling and disabling -@cindex enabling and disabling tests -@findex IntersectionCheck @r{[}GlobalOptions@r{]} -@findex IntersectionTest @r{[}GlobalOptions@r{]} -This option can be used to enable or disable the B@"uchi automata intersection -emptiness check (@pxref{Automata intersection emptiness check}). The test is -enabled by default. - -@item ModelCheck = Local @r{|} Global -@findex ModelCheck @r{[}GlobalOptions@r{]} -@cindex model checking modes -@cindex local model checking -@cindex global model checking -This option determines whether @command{lbtt} should perform model checking -with respect to all states of each state space or only with respect -to a single state of each state space. This affects the number of tests that -@command{lbtt} makes during the model checking result cross-comparison test -(@pxref{Model checking result cross-comparison test}) and the model checking -result consistency check (@pxref{Model checking result consistency check}). -Global model checking (the default) maximizes the number of tests, but may -require more time and memory. (Note: This option has no effect if none of the -model checking tests is enabled.) - -@item Rounds = @var{INTEGER} -@findex Rounds @r{[}GlobalOptions@r{]} -The @samp{Rounds} option can be used to specify the number of test rounds to -run; the default value is 10. - -@item @anchor{Timeouts}TranslatorTimeout = @var{TIME-SPECIFICATION} -@findex TranslatorTimeout @r{[}GlobalOptions@r{]} -@cindex timeouts for translators -This option can be used to specify a time limit (in wall-clock time) after -which the execution of a translator is aborted if it fails to produce a -result within the given limit. A timeout is considered a test failure. The time -specification is of the form -@samp{@r{[}@var{hours}@r{]}h@r{[}@var{minutes}@r{]}min@r{[}@var{seconds}@r{]}s} -where @var{hours}, @var{minutes} and @var{seconds} specify the time limit in -the obvious way (time units having value 0 can be omitted). For example, -a limit of @samp{1h30min} sets the limit at one hour and thirty minutes. - -@item Verbosity = @var{INTEGER} -@findex Verbosity @r{[}GlobalOptions@r{]} -@cindex verbosity, changing -@cindex changing verbosity of output -This option sets the verbosity level for output messages. The value -can be an integer between 0 and 5 (inclusive). A value of 0 will suppress all -messages (and is therefore useful only when storing test results into a log -file; @pxref{--logfile,,@samp{--logfile} command line option}); increasing -the value results in more output. The default value is 3. - -@end table - - - -@node FormulaOptions section, StateSpaceOptions section, GlobalOptions section, Configuration file -@subsection The @samp{FormulaOptions} section - -@cindex configuration file, @samp{FormulaOptions} section -@cindex @samp{FormulaOptions} section (configuration file) - -The @samp{FormulaOptions} section defines the parameters that affect the -algorithm @command{lbtt} uses for generating random LTL formulas -(for more information about the algorithm, see @ref{Random LTL formulas}). -This section provides the following options: - -@cindex parameters for random LTL formula generation algorithm -@cindex random LTL formula, parameters for generation algorithm -@cindex LTL formula, parameters for generation algorithm -@cindex priorities for formula constants, atomic propositions and operators -@cindex atomic propositions, priorities for -@cindex constants, priorities for -@cindex operators, priorities for - -@table @samp -@item AbbreviatedOperators = @var{TRUTH-VALUE} -@cindex abbreviated LTL formula operators -@cindex LTL formula operators, abbreviated -@cindex operators, abbreviated -@findex AbbreviatedOperators @r{[}FormulaOptions@r{]} -This option determines whether the generated formulas should be allowed to -include any of the operators @samp{->}, @samp{<->}, @samp{xor}, @samp{W}, -@samp{<>}, @samp{B}, @samp{V}, @samp{M} or @samp{[]} (all of which can be -given definitions using only the operators @samp{!}, @samp{\/}, @samp{/\}, -@samp{U} and @samp{V}). Setting this option to @samp{No} assigns each of the -abbreviated operators a zero priority, overriding any explicit priorities -defined for these operators in the program configuration. The default value -for the option is @samp{Yes}, so abbreviations are allowed by default. - -@item AndPriority = @var{INTEGER} -@findex AndPriority @r{[}FormulaOptions@r{]} -Priority of the logical conjunction operator (@samp{/\}). - -@item BeforePriority = @var{INTEGER} -@findex BeforePriority @r{[}FormulaOptions@r{]} -Priority of the temporal operator ``before'' (@samp{B}). (Note: This option -has no effect if @samp{AbbreviatedOperators} is set to @samp{No}.) - -@item ChangeInterval = @var{INTEGER} -@findex ChangeInterval @r{[}FormulaOptions@r{]} -This option determines how often (in number of test rounds) -@command{lbtt} should generate a new random LTL formula (or read a new formula -from a user-specified file). A value of 0 forces -@command{lbtt} to use a fixed LTL formula for all tests. The default value -is 1, i.e.,@: a new formula will be generated at the beginning of each test -round. - -@item DefaultOperatorPriority = @var{INTEGER} -@cindex default operator priority -@findex DefaultOperatorPriority @r{[}FormulaOptions@r{]} -This option sets the priority for all formula operators for which -no priority has been given explicitly in the program configuration (i.e., -it can be used as a shorthand to initialize the priority of all operators). -The default value of this option is 0, so all operators with no explicitly -given priorities are disabled by default. - -@item EquivalencePriority = @var{INTEGER} -@findex EquivalencePriority @r{[}FormulaOptions@r{]} -Priority of the logical equivalence operator (@samp{<->}). (Note: This -option has no effect if @samp{AbbreviatedOperators} is set to @samp{No}.) - -@item FalsePriority = @var{INTEGER} -@findex FalsePriority @r{[}FormulaOptions@r{]} -Priority of the Boolean constant -@iftex -@tex -\sc{False} -@end tex -@end iftex -@ifnottex -@samp{false} -@end ifnottex -(with respect to priorities of the constant -@iftex -@tex -\sc{True} -@end tex -@end iftex -@ifnottex -@samp{true} -@end ifnottex -and the atomic propositions). - -@item FinallyPriority = @var{INTEGER} -@findex FinallyPriority @r{[}FormulaOptions@r{]} -Priority of the temporal operator ``finally'' (@samp{<>}). (Note: This -option has no effect if @samp{AbbreviatedOperators} is set to @samp{No}.) - -@item GenerateMode = Normal @r{|} NNF -@cindex random LTL formula, generation modes -@cindex negation normal form -@findex GenerateMode @r{[}FormulaOptions@r{]} -This option determines whether @command{lbtt} should generate random formulas -directly into (a weakened version of) negation normal form in which the -negation operator may only precede atomic propositions. Note that the -formulas may still contain ``abbreviated'' operators if they have nonzero -priorities---use @samp{AbbreviatedOperators=No} or @samp{OutputMode=NNF} if you -wish to prevent this. The default value for this option is @samp{Normal}. -(See the @samp{OutputMode} option below for an example about the differences -in the effects of the @samp{GenerateMode} and @samp{OutputMode} options.) - -@item GloballyPriority = @var{INTEGER} -@findex GloballyPriority @r{[}FormulaOptions@r{]} -Priority of the temporal operator ``globally'' (@samp{[]}). (Note: This -option has no effect if @samp{AbbreviatedOperators} is set to @samp{No}.) - -@item ImplicationPriority = @var{INTEGER} -@findex ImplicationPriority @r{[}FormulaOptions@r{]} -Priority of the logical implication operator (@samp{->}). (Note: This -option has no effect if @samp{AbbreviatedOperators} is set to @samp{No}.) - -@item NextPriority = @var{INTEGER} -@findex NextPriority @r{[}FormulaOptions@r{]} -Priority of the temporal operator ``next time'' (@samp{X}). - -@item NotPriority = @var{INTEGER} -@findex NotPriority @r{[}FormulaOptions@r{]} -Priority of the logical negation operator (@samp{!}). - -@item OrPriority = @var{INTEGER} -@findex OrPriority @r{[}FormulaOptions@r{]} -Priority of the logical disjunction operator (@samp{\/}). - -@item OutputMode = Normal @r{|} NNF -@findex OutputMode @r{[}FormulaOptions@r{]} -@cindex random LTL formula, output modes -@cindex LTL formula, output modes -@cindex negation normal form -This option determines whether @command{lbtt} should transform each generated -LTL formula into (strict) negation normal form before passing it to -LTL-to-B@"uchi translators. If the value is set to @samp{NNF}, @command{lbtt} -will rewrite each generated formula into a form consisting of the -operators @samp{!}, @samp{\/}, @samp{/\}, @samp{U} and @samp{V} such that all -negations in the formula (if any) precede atomic propositions. The default -value is @samp{Normal}. (See also the @samp{GenerateMode} option that can be -used to force formulas to be generated directly into negation normal -form.) - -The option is probably useful only if you have a translator which does not -support the ``abbreviated'' operators directly, but you still wish to test it -with formulas which describe properties expressed using these operators. -Note, however, that rewriting may change the size of the formula. - -The following table illustrates the effects of the -@samp{GenerateMode} and the @samp{OutputMode} options. -@smallformat -@t{ - @r{LTL formula} @r{Can} f @r{be} OutputMode@r{'s effect on the} - f @r{generated if} @r{formula passed to the} - GenerateMode @r{LTL-to-B@"uchi translators} - =NNF @r{?} - ------------------------------------------------------------- - (p1 V ! p0) @r{Yes} Normal@r{/}NNF@r{:} (p1 V ! p0) - - [] p0 -> <> p1 @r{Yes*} Nor@r{:} [] p0 -> <> p1 - NNF@r{:} (true U ! p0) \/ (true U p1) - - ! <> p0 @r{No} Nor@r{:} ! <> p0 - NNF@r{:} (false V ! p0) - - @r{* only if} AbbreviatedOperators=Yes} -@end smallformat - -@item PropositionPriority = @var{INTEGER} -@cindex atomic propositions, priorities for -@findex PropositionPriority @r{[}FormulaOptions@r{]} -Priority for atomic propositions with respect to the priority of Boolean -constants. This priority is the common priority of @emph{all} atomic -propositions. - -@item Propositions = @var{INTEGER} -@findex Propositions @r{[}FormulaOptions@r{]} -This option sets the maximum number of different atomic propositions in -each generated LTL formula. No generated formula will have more than this -number of different atomic propositions. A value of 0 will generate random -formulas with only Boolean -constants (one of which must in this case have a nonzero priority). The -default value is 5. The names of the propositions are of the form -@ifhtml -@samp{p}@var{n}, -@end ifhtml -@ifnothtml -@samp{p@var{n}}, -@end ifnothtml -where @var{n} is a nonnegative integer less than the maximum number of -propositions. - -@item RandomSeed = @var{INTEGER} -@cindex random LTL formula, random seed for generation algorithm -@cindex random seed, LTL formula generation algorithm -@findex RandomSeed @r{[}FormulaOptions@r{]} -This option specifies a seed value for generating random numbers for the -random LTL formula generation algorithm. If this option is not present, the -seed defaults to 1. See the next section for information on how to change the -default seed for the random state space generation algorithm. - -(The reason for having two separate random seeds is to make the sequences of -random formulas and state spaces independent of each other. For example, -this makes it easy to repeat tests using the same batch of random LTL formulas, -but with state spaces of different size.) - -@item ReleasePriority = @var{INTEGER} -@findex ReleasePriority @r{[}FormulaOptions@r{]} -Priority of the temporal ``(weak) release'' operator (@samp{V}). - -@item Size = @var{INTEGER} -@itemx Size = @var{MINIMUM-SIZE}-@var{MAXIMUM-SIZE} -@itemx Size = @var{MINIMUM-SIZE}...@var{MAXIMUM-SIZE} -@findex Size @r{[}FormulaOptions@r{]} -This option defines how many nodes are allowed in the parse tree of each -randomly generated LTL formula. If the size is given as an interval (by -separating the bounds with @samp{-} or @samp{...} with no white space in -between), -@command{lbtt} chooses the size of each formula randomly in the interval -using a uniform random distribution. The default size is 5. - -@item StrongReleasePriority = @var{INTEGER} -@findex StrongReleasePriority @r{[}FormulaOptions@r{]} -Priority of the temporal ``strong release'' operator (@samp{M}). (Note: This -option has no effect if @samp{AbbreviatedOperators} is set to @samp{No}.) - -@item UntilPriority = @var{INTEGER} -@findex UntilPriority @r{[}FormulaOptions@r{]} -Priority of the temporal ``(strong) until'' operator (@samp{U}). - -@item TruePriority = @var{INTEGER} -@findex TruePriority @r{[}FormulaOptions@r{]} -Priority of the Boolean constant -@iftex -@tex -\sc{True} -@end tex -@end iftex -@ifnottex -@samp{true} -@end ifnottex -(with respect to the priorities of the constant -@iftex -@tex -\sc{False} -@end tex -@end iftex -@ifnottex -@samp{false} -@end ifnottex -and the atomic propositions). - -@item WeakUntilPriority = @var{INTEGER} -@findex WeakUntilPriority @r{[}FormulaOptions@r{]} -Priority of the temporal ``weak until'' operator (@samp{W}). (Note: This -option has no effect if @samp{AbbreviatedOperators} is set to @samp{No}.) - -@item XorPriority = @var{INTEGER} -@findex XorPriority @r{[}FormulaOptions@r{]} -Priority of the logical ``exclusive or'' operator (@samp{xor}). (Note: This -option has no effect if @samp{AbbreviatedOperators} is set to @samp{No}.) - -@end table - - - -@node StateSpaceOptions section, Sample configuration file, FormulaOptions section, Configuration file -@subsection The @samp{StateSpaceOptions} section - -@cindex configuration file, @samp{StateSpaceOptions} section -@cindex @samp{StateSpaceOptions} section (configuration file) - -The @samp{StateSpaceOptions} section defines the parameters that affect the -way @command{lbtt} generates random state spaces for the -model checking result cross-comparison test -(@pxref{Model checking result cross-comparison test}) -and the model checking result consistency check -(@pxref{Model checking result consistency check}). -See also @ref{Random state spaces}, for more information about the different -types of available state spaces and the algorithms used for constructing them. -The options available within this section are: - -@cindex parameters for random state space generation algorithm -@cindex state space, generation parameters -@cindex random state space, generation parameters - -@table @samp -@item ChangeInterval = @var{INTEGER} -@findex ChangeInterval @r{[}StateSpaceOptions@r{]} -This option determines how often (in number of test rounds) -@command{lbtt} should generate a new random state space. A value of 0 forces -@command{lbtt} to use a fixed state space for all tests. The default behavior -is to generate a new state space at the beginning of each test round. - -@item EdgeProbability = @var{PROBABILITY} -@cindex graph density -@cindex density (of a state space) -@cindex state space, density -@cindex random state space, density -@findex EdgeProbability @r{[}StateSpaceOptions@r{]} -This option sets the approximate probability (between 0.0 and 1.0) of adding a -transition from any state @var{x} to some other state @var{y} when generating -random graphs as state spaces. The default value is 0.2. The probability is -approximate because -@command{lbtt} still has -to ensure that all states of each generated state spaces have at least one -successor, which might require adding extra transitions to the graph. -Note: This option has no effect if @samp{GenerateMode} is set to -@samp{RandomPath} or @samp{EnumeratedPath}. - -@item GenerateMode = RandomConnectedGraph @r{|} RandomGraph @r{|} RandomPath @r{|} EnumeratedPath -@cindex state space, generation modes -@cindex random connected graph -@cindex random graph -@cindex random path -@cindex enumerated path -@findex GenerateMode @r{[}StateSpaceOptions@r{]} -This option selects the type of generated state spaces from the four available -types. The default value is @samp{RandomConnectedGraph}. See -@ref{Random state spaces}, for more information on the different state space -types. - -@cindex internal model checking algorithm -@cindex using the internal model checking algorithm -@cindex tests, against internal model checking algorithm -Note: Using the @samp{RandomPath} or the @samp{EnumeratedPath} setting includes -@command{lbtt}'s internal model checking algorithm into the various model -checking tests if they are enabled. For more information, see -@ref{Model checking result cross-comparison test}. - -@item Propositions = @var{INTEGER} -@findex Propositions @r{[}StateSpaceOptions@r{]} -This option sets the number of atomic propositions attached to each state of -the generated state spaces. The default value is 5. - -Usually this should probably be the same as the maximum number of -different atomic propositions in the generated formulas -(@pxref{FormulaOptions section}). -If the number of propositions attached to each state of -the state spaces is less than the maximum number of different propositions that -may occur in the generated formulas, all ``extra'' propositions in the formulas -are considered to be false in every state of the state space. - -@item RandomSeed = @var{INTEGER} -@cindex random state space, random seed for generation algorithm -@cindex random seed, state space generation algorithm -@findex RandomSeed @r{[}StateSpaceOptions@r{]} -This option specifies a seed value for generating random numbers required by -the random state space generation algorithm. If this option is not present, the -seed defaults to 1. See the previous section for how to change the random seed -used to initialize the random number generator for the random LTL formula -generation algorithm. - -@item Size = @var{INTEGER} -@itemx Size = @var{MINIMUM-SIZE}-@var{MAXIMUM-SIZE} -@itemx Size = @var{MINIMUM-SIZE}...@var{MAXIMUM-SIZE} -@findex Size @r{[}StateSpaceOptions@r{]} -This option sets the number of states in the generated state spaces. If the -size is given as an interval, @command{lbtt} either chooses a random size in -the interval (including its endpoints) each time a new state space is -generated, or, if @samp{GenerateMode} is set to @samp{EnumeratedPath}, -enumerates all state spaces in the specified range systematically, starting -from the minimum size. The default size is 20. - -@item TruthProbability = @var{PROBABILITY} -@findex TruthProbability @r{[}StateSpaceOptions@r{]} -Probability (between 0.0 and 1.0) with which each individual atomic proposition -has the value -@ifnottex -@samp{true} -@end ifnottex -@iftex -@tex -\sc{True} -@end tex -@end iftex -in any state of the state space. Note: This option has no effect if -@samp{GenerateMode} is set to @samp{EnumeratedPath}. The default value is 0.5. - -@end table - - -@node Sample configuration file, , StateSpaceOptions section, Configuration file -@subsection Sample configuration file - -@cindex configuration file, example - -The following configuration file sets @command{lbtt} up for testing two -imaginary LTL-to-B@"uchi translators. - -@smallexample -# Sample configuration file for lbtt - -Translator -@{ - Name = Translator\ 1 - Path = /home/lbtt-user/bin/t-1 # location of the translator - # executable - Enabled = Yes -@} - -Translator -@{ - Name = "Translator 2" - Path = /home/lbtt-user/bin/t-2 - Parameters = "-x -y 3 -v 0" # parameters to be passed to the - # executable - Enabled = Yes -@} - -GlobalOptions -@{ - Rounds = 100 # 100 test rounds - - Interactive = OnError,OnBreak # pause testing in case of an error - # or when receiving a break signal - - Verbosity = 1 # show only numeric statistics - - ComparisonTest = Yes # enable all tests except the - ConsistencyTest = Yes # B@"uchi automata intersection - IntersectionTest = No # emptiness test - - ModelCheck = Local # perform the tests only in a - # single state of each state - # space - - TranslatorTimeout = 30s # abort the execution of a - # translator if it fails to give - # a result in 30 seconds -@} - -FormulaOptions -@{ - AbbreviatedOperators = Yes # formula generation mode - GenerateMode = Normal - OutputMode = NNF # rewrite formulas in negation - # normal form before passing - # them to the translators - - ChangeInterval = 1 # new formula after each round - - RandomSeed = 4632912 # random seed - - Size = 5-15 # 5 to 15 nodes in the parse - # tree of each formula - - Propositions = 3 # allow at most three different - # propositions in each LTL formula - - PropositionPriority = 50 # priorities for propositional - TruePriority = 1 # symbols - FalsePriority = 1 - - AndPriority = 10 # priorities for some logical - OrPriority = 10 # operators - NotPriority = 10 - EquivalencePriority = 5 - - NextPriority = 5 # priorities for some temporal - UntilPriority = 5 # operators - ReleasePriority = 5 - FinallyPriority = 2 - - DefaultOperatorPriority = 0 # disable all the remaining - # operators -@} - -StatespaceOptions -@{ - GenerateMode = RandomGraph # generate random (not - # necessarily connected) graphs - # as state spaces - - ChangeInterval = 10 # new state space after every - # 10th test round - - RandomSeed = 37620 # random seed - - Size = 50 # 50 states in each state space - - Propositions = 3 # three propositions in each - # state of each state space - - EdgeProbability = 0.1 # approximate probability of - # having a transition between - # any two states - - TruthProbability = 0.5 # probability with which any - # atomic proposition is true in - # a state -@} -@end smallexample - - -@node Command line options, , Configuration file, Invocation -@section Command line options - -This section lists the command line options that may be used when -invoking @command{lbtt}. The command line options are processed only -after reading the configuration file, so they can be used to override the -settings given in the file. There are also a few options for which -there is no direct equivalent in the configuration file options. - -@menu -* Special options:: Options available only as command line - parameters. -* Global options:: Options corresponding to the - @samp{GlobalOptions} section of the - configuration file. -* LTL formula options:: Options corresponding to the - @samp{FormulaOptions} section of the - configuration file. -* State space options:: Options corresponding to the - @samp{StateSpaceOptions} section of the - configuration file. -@end menu - - - -@node Special options, Global options, Command line options, Command line options -@subsection Special options - -The following list presents all command line options for which there is -no (directly) corresponding option that may be set in the program -configuration file. - -@table @samp -@item --configfile=@var{FILE-NAME} -@cindex configuration file, changing the name of -@vindex --configfile -This option can be used to instruct @command{lbtt} to read program -configuration from another file instead of the default configuration -file @samp{config} in the current working directory. - -@item @anchor{--formulafile}--formulafile=@var{FILE-NAME} -@vindex --formulafile -@cindex LTL formula, reading from a file or standard input -@cindex file formats, formula input file for @command{lbtt} -This option instructs @command{lbtt} to read the LTL formulas used in the tests -from a file (or standard input) instead of generating them randomly. The -special filename @samp{-} refers to standard input. Each -input formula should be followed by a newline. The formulas can be specified -either in @command{lbtt}'s own prefix notation -(@pxref{Format for LTL formulas}; also the infix notation used in output -messages is supported) or in a variety of formats found in -some LTL-to-B@"uchi translator implementations (Spin, LTL2BA, LTL2AUT, -Temporal Massage Parlor, Wring, Spot, LBT), however with the restriction that -all atomic propositions should have names of the form -@samp{p@var{N}} for some nonnegative integer @var{N}. - -@cindex operators, precedence in input files -(When using one of the alternative -formats, it is recommended to use parentheses to avoid possible ambiguities in -the precedence and associativity of the various operators; in @command{lbtt}, -the unary operators have the highest precedence, @samp{/\} has higher -precedence than @samp{\/}, which in turn has higher precedence than any of -@samp{->}, @samp{<->} or @samp{xor}, and the binary temporal operators have -the lowest precedence. All binary logical operators are left-associative; -all binary temporal operators are nonassociative.) - -If this option is used, all command line or configuration file parameters -affecting the generation of random LTL formulas (excluding their mode of -output) are ignored. - -@item --h -@itemx --help -@vindex -h -@vindex --help -These options list all the available command line parameters. - -@item @anchor{--logfile}--logfile=@var{FILE-NAME} -@vindex --logfile -@cindex log file for test failures -@cindex using a test failure log file -This option instructs @command{lbtt} to create a log of all errors -encountered during testing. By default no log will be created. - -@item --profile -@vindex --profile -@cindex tests, enabling and disabling -@cindex enabling and disabling tests -@cindex tests, profiling LTL-to-B@"uchi translators -This option can be used as a shorthand for disabling all B@"uchi automata -correctness tests. -The test report generated at the end of testing then shows -only the running times of each tested LTL-to-B@"uchi translator and the sizes -of the generated automata. - -@item --quiet -@itemx --silent -@vindex --quiet -@vindex --silent -@cindex suppressing output -These options suppress any messages that are normally displayed during -testing. Use the @samp{--logfile} option (see -above) with these options to save a test failure report into a log file. - -@item @anchor{--showconfig}--showconfig -@vindex --showconfig -If this option is present on the command line, @command{lbtt} will -write the current configuration to standard output -(@pxref{Configuration information}) and then exit. -This option can be used together with the @samp{--configfile} option to -test the settings defined in a configuration file without actually performing -any tests. - -@item @anchor{--showoperatordistribution}--showoperatordistribution -@vindex --showoperatordistribution -@cindex operators, computing distribution for -@cindex random LTL formula, computing operator distribution -With this option @command{lbtt} uses the priorities defined for the -LTL formula operators available for random LTL formula generation to compute -the expected number of occurrences of each operator in a single randomly -generated formula. The distribution is then displayed along with other -configuration information when the program starts. - -@item @anchor{--skip}--skip=@var{NUMBER-OF-ROUNDS} -@vindex --skip -@cindex tests, skipping test rounds -@cindex skipping test rounds -This option can be used to skip the first @var{NUMBER-OF-ROUNDS} test rounds, -i.e., begin testing from round @var{NUMBER-OF-ROUNDS}+1. - -@item -V -@itemx --version -@vindex -V -@vindex --version -This option displays the version of the @command{lbtt} executable. - -@end table - - - -@node Global options, LTL formula options, Special options, Command line options -@subsection Global options - -The following list presents the options that can be used to override the -values specified in the @samp{GlobalOptions} section of the configuration -file. - -@table @samp -@item --comparisontest@r{[}=yes | no@r{]} -@itemx --nocomparisontest -@cindex tests, enabling and disabling -@cindex enabling and disabling tests -@vindex --comparisontest -@vindex --nocomparisontest -These options enable or disable the model checking result cross-comparison -test (@pxref{Model checking result cross-comparison test}). - -@item --consistencytest@r{[}=yes | no@r{]} -@itemx --noconsistencytest -@cindex tests, enabling and disabling -@cindex enabling and disabling tests -@vindex --consistencytest -@vindex --noconsistencytest -These options enable or disable the model checking result consistency check -(@pxref{Model checking result consistency check}). - -@item --disable=@var{IMPLEMENTATION-ID}@r{[},@var{IMPLEMENTATION-ID}@r{...]} -@cindex disabling LTL-to-B@"uchi translators -@cindex LTL-to-B@"uchi translators, disabling -@vindex --disable -This option can be used to exclude some implementations from the tests by -specifying a comma-separated list of implementation names or their numeric -identifiers. (The implementations are numbered in the order in which they -appear in the configuration file, starting from zero. Use the -@samp{--showconfig} option, see @ref{Special options}, to obtain a list of the -implementations specified in the configuration file, together with their -identifiers.) - -@item --enable=@var{IMPLEMENTATION-ID}@r{[},@var{IMPLEMENTATION-ID}@r{...]} -@cindex enabling LTL-to-B@"uchi translators -@cindex LTL-to-B@"uchi translators, enabling -@vindex --enable -This option can be used to include implementations into the tests (in the -case they are initially disabled in the configuration file). - -@item --globalmodelcheck -@vindex --globalmodelcheck -@cindex model checking modes -@cindex global model checking -This option instructs @command{lbtt} to perform model checking globally -(with respect to all states of each random state space) in the model -checking result cross-comparison test and the model checking result -consistency check. Using a global check increases the number of possible -tests. - -@item --interactive@r{[}=@var{MODE-LIST}@r{]} -@itemx --pause@r{[}=@var{MODE-LIST}@r{]} -@vindex --interactive -@cindex interactivity modes -These options can be used to override whether @command{lbtt} should pause -between test rounds to wait for user input. The optional @var{MODE-LIST} is a -comma-separated list of interactivity modes (@samp{Always}, @samp{OnError}, -@samp{Never}, @samp{OnBreak}) with no spaces in between -(@pxref{Interactivity modes}, for the mode descriptions). If omitted, the -mode list defaults to @samp{Always}. - -@item --intersectiontest@r{[}=yes | no@r{]} -@itemx --nointersectiontest -@cindex tests, enabling and disabling -@cindex enabling and disabling tests -@vindex --intersectiontest -@vindex --nointersectiontest -These options enable or disable the B@"uchi automata intersection emptiness -check (@pxref{Automata intersection emptiness check}). - -@item --localmodelcheck -@vindex --localmodelcheck -@cindex model checking modes -@cindex local model checking -This option instructs @command{lbtt} to perform model checking only with -respect to a single state of each random state space in the model checking -result cross-comparison test and the model checking result consistency -check. - -@item --modelcheck=global | local -@vindex --modelcheck -@cindex model checking modes -@cindex local model checking -@cindex global model checking -This option can be used to select the model checking mode. - -@item --pause@r{[}=@var{MODE-LIST}@r{]} -@vindex --pause -See @samp{--interactive}. - -@item --rounds=@var{NUMBER-OF-ROUNDS} -@vindex --rounds -This option can be used to override the number of test rounds to run. - -@item --translatortimeout=@var{TIME-SPECIFICATION} -@vindex --translatortimeout -This option can be used to override the running time limit (in wall-clock -time) for translators (@pxref{Timeouts}, for more information). - -@item --verbosity=@var{INTEGER} -@vindex --verbosity -@cindex verbosity, changing -@cindex changing verbosity of output -This option sets the verbosity of output messages. The value must be -between 0 and 5 (inclusive). - -@end table - - - -@node LTL formula options, State space options, Global options, Command line options -@subsection LTL formula options - -The following command line options can be used to control the behavior of -@command{lbtt}'s random LTL formula generation algorithm. They correspond -to the options available in the @samp{FormulaOptions} section of the -configuration file. - -@cindex parameters for random LTL formula generation algorithm -@cindex random LTL formula, parameters for generation algorithm -@cindex LTL formula, parameters for generation algorithm -@cindex priorities for formula constants, atomic propositions and operators -@cindex atomic propositions, priorities for -@cindex constants, priorities for -@cindex operators, priorities for - -@table @samp -@item --abbreviatedoperators@r{[}=yes | no@r{]} -@itemx --noabbreviatedoperators -@vindex --abbreviatedoperators -@vindex --noabbreviatedoperators -@cindex abbreviated LTL formula operators -@cindex LTL formula operators, abbreviated -@cindex operators, abbreviated -These options can be used to allow or prevent @command{lbtt} from using any of -the ``abbreviated'' operators (@samp{->}, @samp{<->}, @samp{xor}, @samp{W}, -@samp{<>}, @samp{B}, @samp{M} and @samp{[]}) when generating random LTL -formulas. - -@item --andpriority -@vindex --andpriority -This option sets the priority for logical conjunction (the @samp{/\} operator). - -@item --beforepriority -@vindex --beforepriority -This option sets the priority for the temporal ``before'' operator -(@samp{B}). - -@item --defaultoperatorpriority -@vindex --defaultoperatorpriority -@cindex default operator priority -This option sets the default priority for all logical and temporal operators. - -@item --equivalencepriority -@vindex --equivalencepriority -This option sets the priority for logical equivalence (the @samp{<->} -operator). - -@item --falsepriority -@vindex --falsepriority -This option sets the priority for the Boolean constant @samp{false}. - -@item --finallypriority -@vindex --finallypriority -This option sets the priority for the temporal ``finally'' operator -(@samp{<>}). - -@item --formulachangeinterval=@var{NUMBER-OF-ROUNDS} -@vindex --formulachangeinterval -This option determines how often (in number of test rounds) -@command{lbtt} should generate a new random LTL formula. A value of 0 forces -@command{lbtt} to use a fixed LTL formula for all tests. - -@item --formulageneratemode=normal | nnf -@vindex --formulageneratemode -@cindex random LTL formula, generation modes -@cindex negation normal form -This option can be used to choose how @command{lbtt} should generate random -LTL formulas. With the option @samp{--formulageneratemode=nnf}, all generated -formulas will be in (a weakened) negation normal form in which all negations in -the formula (if any) precede atomic propositions. (Note that the formulas may -still contain some of the ``abbreviated'' operators if their priorities are -not explicitly set to zero.) - -@item --formulaoutputmode=normal | nnf -@vindex --formulaoutputmode -@cindex random LTL formula, output modes -@cindex LTL formula, output modes -@cindex negation normal form -This option can be used to force or prevent @command{lbtt} from converting each -LTL formula into (strict) negation normal form (i.e., rewriting it with the -operators @samp{!}, @samp{/\}, @samp{\/}, @samp{U} and @samp{V}) before passing -it to the LTL-to-B@"uchi translators. - -@item --formulapropositions -@vindex --formulapropositions -This option sets the maximum number of different atomic propositions that -@command{lbtt} may use for generating random LTL formulas. - -@item --formularandomseed=@var{INTEGER} -@cindex random seed, LTL formula generation algorithm -@vindex --formularandomseed -This option gives a seed value for generating random numbers used by the -random LTL formula generation algorithm. - -@item --formulasize=@var{INTEGER} -@itemx --formulasize=@var{MINIMUM-SIZE}-@var{MAXIMUM-SIZE} -@itemx --formulasize=@var{MINIMUM-SIZE}...@var{MAXIMUM-SIZE} -@vindex --formulasize -This option sets the size of the random LTL formulas generated for the tests. -The size can be given either as a fixed integer or as an interval, in which -case the size of each generated formula will be chosen randomly in the -interval using a uniform random distribution. - -@item --generatennf -@itemx --nogeneratennf -@vindex --generatennf -@vindex --nogeneratennf -@cindex random LTL formula, generation modes -@cindex negation normal form -These options can be used instead of the @samp{--formulageneratemode} option -to select the random formula generation mode. - -@item --globallypriority -@vindex --globallypriority -This option sets the priority for the temporal ``globally'' operator -(@samp{[]}). - -@item --implicationpriority -@vindex --implicationpriority -This option sets the priority for logical implication (the @samp{->} operator). - -@item --nextpriority -@vindex --nextpriority -This option sets the priority for the temporal ``next time'' operator -(@samp{X}). - -@item --notpriority -@vindex --notpriority -This option sets the priority for logical negation (the @samp{!} operator). - -@item --orpriority -@vindex --orpriority -This option sets the priority for logical disjunction (the @samp{\/} operator). - -@item --outputnnf -@itemx --nooutputnnf -@vindex --outputnnf -@vindex --nooutputnnf -@cindex random LTL formula, output modes -@cindex LTL formula, output modes -@cindex negation normal form -These options can be used instead of the @samp{--formulaoutputmode} option to -choose the format in which @command{lbtt} passes LTL formulas to LTL-to-B@"uchi -translators. - -@item --propositionpriority -@vindex --propositionpriority -This option sets the priority for atomic propositions. - -@item --releasepriority -@vindex --releasepriority -This option sets the priority for the temporal ``(weak) release'' operator -(@samp{V}). - -@item --strongreleasepriority -@vindex --strongreleasepriority -This option sets the priority for the temporal ``strong release'' operator -(@samp{M}). - -@item --truepriority -@vindex --truepriority -This option sets the priority for the Boolean constant -@iftex -@tex -\sc{True}. -@end tex -@end iftex -@ifnottex -@samp{true}. -@end ifnottex - -@item --untilpriority -@vindex --untilpriority -This option sets the priority for the temporal ``(strong) until'' operator -(@samp{U}). - -@item --weakuntilpriority -@vindex --weakuntilpriority -This option sets the priority for the temporal ``weak until'' operator -(@samp{W}). - -@item --xorpriority -@vindex --xorpriority -This option sets the priority for the logical ``exclusive or'' operator. - -@end table - -Note also the @samp{--formulafile=@var{FILE-NAME}} option -(@pxref{--formulafile,,@samp{--formulafile} option}), which can be used to -instruct @command{lbtt} to read LTL formulas from a file (or standard input) -instead of generating them randomly. - - - -@node State space options, , LTL formula options, Command line options -@subsection State space options - -The following command line options affect the way in which @command{lbtt} -generates state spaces that are then used in the model checking tests. They -correspond to options in the @samp{StateSpaceOptions} section of the -configuration file. See also @ref{Random state spaces}, for more information -about the graph generation modes. - -@cindex parameters for random state space generation algorithm -@cindex state space, generation parameters -@cindex random state space, generation parameters - -@table @samp -@item --edgeprobability=@var{PROBABILITY} -@vindex --edgeprobability -This option sets the approximate random edge probability for state spaces. (The -option has no effect if the generated state spaces are random or enumerated -paths.) - -@item --enumeratedpath -@vindex --enumeratedpath -@cindex state space, generation modes -@cindex enumerated path -This option instructs @command{lbtt} to enumerate all paths of a given size -as state spaces instead of generating random state spaces for model checking -tests. The option also enables @command{lbtt}'s internal model checking -algorithm. - -@item --randomconnectedgraph -@vindex --randomconnectedgraph -@cindex state space, generation modes -@cindex random connected graph -This option makes @command{lbtt} generate random connected graphs as state -spaces for model checking tests. - -@item --randomgraph -@vindex --randomgraph -@cindex state space, generation modes -@cindex random graph -This option makes @command{lbtt} generate random graphs as state spaces for -model checking tests. - -@item --randompath -@vindex --randompath -@cindex state space, generation modes -@cindex random path -This option forces @command{lbtt} to generate random paths as state spaces. -The option also enables @command{lbtt}'s internal model checking algorithm -in the model checking tests. - -@item --statespacechangeinterval=@var{NUMBER-OF-ROUNDS} -@vindex --statespacechangeinterval -This option sets the frequency (in test rounds) in which new state spaces -are generated. A value of 0 forces @command{lbtt} to use a fixed state space -for all tests. - -@item --statespacegeneratemode=randomconnectedgraph | randomgraph | randompath | enumeratedpath -@vindex --statespacegeneratemode -@cindex state space, generation modes -@cindex enumerated path -@cindex random connected graph -@cindex random graph -@cindex random path -This option can be used instead of one of the four options above to select -the state space generation mode. - -@item --statespacerandomseed=@var{INTEGER} -@vindex --statespacerandomseed -@cindex random state space, random seed for generation algorithm -This option gives a seed value for generating random numbers required by the -random state space generation algorithm. - -@item --statespacesize=@var{INTEGER} -@itemx --statespacesize=@var{MINIMUM-SIZE}-@var{MAXIMUM-SIZE} -@itemx --statespacesize=@var{MINIMUM-SIZE}...@var{MAXIMUM-SIZE} -@vindex --statespacesize -This option can be used to change the size of the generated state spaces. - -@item --truthprobability=@var{PROBABILITY} -@vindex --truthprobability -This option sets the probability that @command{lbtt} uses for choosing the -valuation for each atomic proposition in each state of the randomly generated -state spaces. (This option has no effect if using enumerated paths as state -spaces.) - -@end table - - - -@node Interpreting the output, Analyzing test results, Invocation, Top -@chapter Interpreting the output - -This chapter briefly introduces the most typical messages that -@command{lbtt} outputs during testing. Most of the examples in this section -illustrate the output when @command{lbtt} is running in its default output -verbosity mode (3). In lower verbosity modes some (or in verbosity mode 0, all) -of these messages will be suppressed; in higher verbosity modes, some -additional information about @command{lbtt}'s internal behavior is shown. - -@menu -* Configuration information:: The current configuration is shown - before starting tests. -* Test round messages:: Conventions for reporting test - results and test failures. -* Test statistics:: Shown at the end of testing. -@end menu - - -@node Configuration information, Test round messages, Interpreting the output, Interpreting the output -@section Configuration information - -@cindex configuration information - -Before starting tests, @command{lbtt} outputs (in verbosity modes 2 and above) -a summary of the current -program configuration as obtained by reading the program configuration file -and interpreting the command line parameters. The same summary can be -obtained without running any tests by using the -@samp{--showconfig} command line option -(@pxref{--showconfig,,@samp{--showconfig} option}). The information will be -written also to the error log file if one was specified in the command line -with the @samp{--logfile} option -(@pxref{--logfile,,@samp{--logfile} option}). -The summary consists of the following information: - -@itemize @bullet -@item -LTL-to-B@"uchi translator implementations enabled for testing. - -@item -List of enabled tests. - -@item -Random state space generation parameters. - -@item -Random LTL formula generation parameters (unless reading LTL formulas from -an external source; @pxref{--formulafile,,@samp{--formulafile} command line -option}). This includes information about all enabled formula operators and -their priorities. When using the command line option -@samp{--showoperatordistribution} -(@pxref{--showoperatordistribution,,@samp{--showoperatordistribution} option}), -@command{lbtt} shows also the expected number of occurrence of each -operator in each randomly generated formula. - -@end itemize - -@noindent -Example: - -@smallexample -Program configuration: ----------------------- - - 1000 test rounds. - Testing will be interrupted in case of an error. - Signalling a break will interrupt testing. - Using global model checking for tests. - Writing error log to `error.log'. - - Implementations: - 0: `Implementation 0' - 1: `Implementation 1' - - Timeout for translators is set to 30 seconds. - - Enabled tests: - Model checking result cross-comparison test - Model checking result consistency check - B@"uchi automata intersection emptiness check - - Random state spaces: - Random graphs (50 states, 5 atomic propositions) - New state space will be generated after every 5th round. - Random seed: 98 - Random edge probability: 0.10 - Propositional truth probability: 0.50 - - Random LTL formulas: - 5 parse tree nodes, 5 atomic propositions - New LTL formula will be generated after every round. - Random seed: 17991 - Atomic symbols in use (priority): - false (5); propositions (90); true (5) - Operators used for random LTL formula generation: - operator ! /\ U V X \/ - priority 10 10 20 20 10 20 - -@end smallexample - -@node Test round messages, Test statistics, Configuration information, Interpreting the output -@section Test round messages - -In verbosity modes 1 and 2, @command{lbtt} reports numeric statistics on the -generated automata in tabular form. Each row of this table contains the -following information (in this order): -@itemize -@item -number of the current test round (verbosity mode 1 only); -@item -numeric identifier of an implementation; -@item -formula identifier (@samp{+} or @samp{-}); -@item -time consumed when generating an automaton from the formula using the -implementation; -@item -number of states, transitions and acceptance conditions in the automaton; -@item -number of states and transitions in the product automaton -@item -number of accepting cycles in the state space (see below), and -@item -result of the consistency check (verbosity mode 2 only). -@end itemize - -The following example shows a fragment of the output that @command{lbtt} might -produce during a test round when running in the default verbosity mode 3. - -@cindex tests, output example - -@smallformat -1. @t{Round 6 of 10} - -2. @t{ Generating random state space} - -3. @t{ Random LTL formula:} -@r{ }@t{ formula: ((p1 <-> p0) U (p0 \/ ! p3))} -@r{ }@t{ negated formula: ! ((p1 <-> p0) U (p0 \/ ! p3))} - -@r{ }@t{ 0: `Implementation 0'} -@r{ }@t{ Positive formula:} -4. @t{ B@"uchi automaton:} -@r{ }@t{ number of states: 6} -@r{ }@t{ number of transitions: 15} -@r{ }@t{ acceptance sets: 1} -@r{ }@t{ computation time: 0.03 seconds (user time)} -5. @t{ Product automaton:} -@r{ }@t{ number of states: 582 [97.00% of worst case (600)]} -@r{ }@t{ number of transitions: 7188} -6. @t{ Accepting cycles:} -@r{ }@t{ cycle reachable from 0 states} -@r{ }@t{ not reachable from 100 states} -7. @t{ Negated formula:} -@r{ }@t{ B@"uchi automaton:} -@r{ }@t{ number of states: 4} -@r{ }@t{ number of transitions: 6} -@r{ }@t{ acceptance sets: 0} -@r{ }@t{ computation time: 0.04 seconds (user time)} -@r{ }@t{ Product automaton:} -@r{ }@t{ number of states: 363 [90.75% of worst case (400)]} -@r{ }@t{ number of transitions: 2581} -@r{ }@t{ Accepting cycles:} -@r{ }@t{ cycle reachable from 25 states} -@r{ }@t{ not reachable from 75 states} -8. @t{ Result consistency check:} -@r{ }@t{ result: failed [75 (75.00%) of 100 test cases]} -@end smallformat - -@noindent -The numbered parts of the output are: - -@enumerate -@item -Number of the test round. - -@item -@command{lbtt} generates a new random state space for model -checking tests. (In this case the size of the state spaces was fixed in the -configuration; if the state space size is allowed to vary in an interval, -@command{lbtt} would also show here the actual size of the generated state -space.) - -@item -@cindex operators, precedence in output messages -Information about a random LTL formula and its negation. To simplify the -notation, it is assumed that all unary formula operators have higher -precedence than binary operators. - -@item -Information about the B@"uchi automaton that `Implementation 0' generated -from the positive LTL formula (number of states, transitions and acceptance -conditions, and the amount of user time elapsed in generating the automaton). - -@item -Information about the synchronous product of the state space and the -B@"uchi automaton constructed from the positive formula. - -@item -Model checking result information. In this case, the automaton cannot reach -an ``accepting cycle'' regardless of the state of the state space in which -the automaton could begin its execution. In other words, the random state -space contains no states with an infinite path beginning from the state such -that the B@"uchi automaton accepts the temporal interpretation of the path -(the infinite sequence of state labels on the path). - -@item -The model checking process is repeated using the negated formula as -input for the LTL-to-B@"uchi translator `Implementation 0'. - -@item -@command{lbtt} performs the model checking result consistency check -(@pxref{Model checking result consistency check}) using the model checking -results computed for the positive and the negative formula. In this example, -the result consistency check fails in 75 states of the state space. This -implies that `Implementation 0' failed to translate one (or both) -of the formulas into a B@"uchi automaton correctly. - -@end enumerate - -The output of phases 4---8 will be repeated for each implementation included in -the tests. After this @command{lbtt} proceeds to the model checking result -cross-comparison test (@pxref{Model checking result cross-comparison test}) and -the B@"uchi automata intersection emptiness test -(@pxref{Automata intersection emptiness check}). - -The model checking result cross-comparison test might result in the following -output (shown in verbosity modes greater than 1): - -@smallformat -@t{ Model checking result cross-comparison:} -@t{ result:} -@t{ failed (+) 0: `Implementation 0', 1: `Implementation 1'} -@end smallformat - -@cindex tests, failure report format -Throughout all test failure reports, @command{lbtt} refers to the positive and -negated formulas with the symbols @samp{+} and @samp{-}, respectively. -Therefore, the above message indicates that the model checking results obtained -using `Implementation 0' and `Implementation 1' for the positive formula do not -agree. A similar line will be shown for all pairs of implementations for which -the test failed. - -@command{lbtt} also reports if the model checking result cross-comparison could -not be performed between a pair of implementations (for example, if one of the -implementations failed to generate an automaton); in this case, the result of -the test is @samp{N/A}. - -@cindex internal model checking algorithm -@cindex tests, against internal model checking algorithm -If using enumerated or randomly generated paths as state spaces, the model -checking results are also compared against those given by -@command{lbtt}'s internal model checking algorithm. - -A similar convention is used to report failures in the B@"uchi automata -intersection emptiness check. However, because this test is always performed -on B@"uchi automata constructed from two complementary LTL formulas, a test -failure report shows LTL formula information beside the name of the -implementation used for generating the B@"uchi automaton from that formula. -Note that the B@"uchi automata intersection emptiness check may fail on the -automata constructed by the same implementation; in the following example, -the check failed between the automata constructed by `Implementation 0', and -the automata constructed by `Implementation 0' and `Implementation 1' from -the positive and negative formulas, respectively. - -@smallformat -@t{ B@"uchi automata intersection emptiness check:} -@t{ result:} -@t{ failed 0: `Implementation 0'} -@t{ failed (+) 0: `Implementation 0', (-) 1: `Implementation 1'} -@end smallformat - -If using a log file (@pxref{--logfile,,@samp{--logfile} command line option}), -a summary of all testing errors will be written to the file using the output -format specified above. - - - - - -@node Test statistics, , Test round messages, Interpreting the output -@section Test statistics - -@cindex tests, statistics - -At the end of testing, @command{lbtt} outputs some simple statistics computed -over all tests in verbosity modes 2 and above. If using an error log file -(@pxref{--logfile,,@samp{--logfile} command line option}), the statistics -will be stored also in the log file. These statistics can be also accessed -during interactive testing by using the internal command @samp{statistics} -(@pxref{statistics,,@samp{statistics} command}). -In brief, the statistics include: - -@itemize @bullet -@item -Number of generated state spaces and the total number of states and -transitions in them. - -@item -@cindex operators, computing distribution for -Number of processed LTL formulas (not counting the negations of each -formula). If using random formulas, @command{lbtt} also shows the overall -distribution of each individual proposition, Boolean constant and logical -or temporal operator in the sample of randomly generated formulas. -Theoretically, in a large sample of random formulas, this distribution -should correspond to the one that can be computed before testing by using the -@samp{--showoperatordistribution} command line option -(@pxref{--showoperatordistribution,,@samp{--showoperatordistribution} command line option}). - -@item -Automata statistics for each implementation: - -@itemize @minus -@item -number of generated B@"uchi automata and product automata - -@item -total and average numbers of states, transitions and acceptance sets in the -generated B@"uchi/product automata, and - -@item -total and average time consumed in generating the B@"uchi automata. -@end itemize - -@item -Number of times that each implementation failed to generate an acceptable -automaton from an input formula. - -@item -Number of failures in the model checking result consistency check -(@pxref{Model checking result consistency check}) for each implementation. - -@item -Number of result inconsistencies detected in pairwise comparison of the -B@"uchi automata generated by different implementations. Depending on -the model checking mode and which correctness tests are enabled, the -output may include none, some or all of the following information: - -@itemize @minus -@item -Overall number of failures in the model checking result cross-comparison test -(@pxref{Model checking result cross-comparison test}) for each pair of -implementations. - -@item -Number of failures in the model checking result cross-comparison test in -a single fixed state of each generated state space (called the ``initial'' -state of the state space). - -@item -Number of failures in the B@"uchi automata intersection emptiness check -(@pxref{Automata intersection emptiness check}) for each pair of -implementations. -@end itemize - -Note that the pairwise inconsistency results form a symmetric matrix (possibly -shown in several parts), which means that -the same information is repeated on both sides of the matrix diagonal. - -@end itemize - -@noindent -Where applicable, the statistics are shown separately for positive, negative -and all LTL formulas used in the tests. - - - - -@node Analyzing test results, Interfacing with lbtt, Interpreting the output, Top -@chapter Analyzing test results - -This chapter documents how to use @command{lbtt}'s internal commands to -analyze test results. - -To use the internal commands, @command{lbtt} must be started in one of its -interactive modes (@pxref{Interactivity modes}). Depending on the mode, -@command{lbtt} may occasionally pause (for example, after each test round, or -when a test failure is detected) between test rounds to wait for user input by -showing a prompt of the form - -@smallexample - ** [Round 22 of 1000] >> -@end smallexample - -@menu -* Command conventions:: Conventions for entering commands. -* Getting help:: Use the @samp{help} command to access - on-line help. -* Test control commands:: Commands for continuing testing, - skipping tests or enabling or disabling - implementations. -* Data display commands:: Commands for displaying information - about B@"uchi automata, state spaces, - and LTL formulas. -* Failure analysis commands:: Commands for analyzing test failures. -@end menu - - - -@node Command conventions, Getting help, Analyzing test results, Analyzing test results -@section Command conventions - -@cindex commands, conventions for entering -@cindex conventions for entering commands - -Commands are entered by typing a command name followed by any parameters for -the command and then pressing @key{ENTER}. -The command names are case-sensitive. Each parameter should be separated from -the command name and other parameters with white space. - -@cindex commands, abbreviating -Command names can be abbreviated to the shortest prefix that identifies the -command unambiguously (for example, @samp{h} could be used in place of the -@samp{help} command). - -@cindex commands, entering lists of numbers -Some of the commands expect lists of implementation or state -identifiers as parameters. The lists can be specified as comma-separated -numbers (for example, @samp{8}) or intervals (for example, @samp{3-11}) -with no white space between the commas and the numbers or intervals that -belong to the same list. For example, assuming that the state space used in -the current test round has at least 23 states, the command -@samp{statespace -5,8,14-18,22-} would -display information about all state space states with an identifier less than -or equal to 5, together with information about state 8, states 14 to 18 -(inclusive) and all states with an identifier greater than or equal to 22. The -@samp{*} symbol can be used as a shorthand for all identifiers in the -available range. - -@command{lbtt} also recognizes the symbolic names of implementations (defined -in the configuration file) in implementation identifier lists. The names can be -used in place of the numeric identifiers. Quotes or the escape character -(@samp{\}) should be used to handle white space in identifiers. - -@cindex LTL formula, identifiers in commands -@cindex commands, LTL formula identifiers -Some of the commands require a formula identifier as a parameter for choosing -between a positive and a negative LTL formula. The formula identifier -(@samp{+} for positive formula, @samp{-} for negative formula) must follow -the command name as the first parameter for the command. If the formula -identifier is omitted, the positive formula is assumed. - -@cindex redirecting command output -@cindex commands, redirecting output -The output of most commands (excluding the test control commands, -@pxref{Test control commands}) can be redirected or appended to a file -by ending the command line with @samp{>filename} or @samp{>>filename}, -respectively. - -@cindex commands, invoking external programs -@cindex commands, writing output to a pipe -Optionally, the output can be handed over to an external program by ending the -command line with @samp{| @var{command}}, where @var{command} is the command -line used for invoking the external program. -For example, the output of the (@command{lbtt}'s internal) command can be piped -to a pager application if the entire output does not fit on the screen by -itself. Using the pipe construct without specifying any internal command -will simply invoke the external program. - - - -@node Getting help, Test control commands, Command conventions, Analyzing test results -@section Getting help - -@cindex commands, getting help -@kindex help -Use the @samp{help} command to access on-line help. Typing @samp{help} with -no parameters shows a list of all available commands, together with -general conventions for using the commands. The @samp{help} command can be -optionally given a command name as a parameter to access command-specific -help. - -In command-specific help, arguments in angle brackets (@r{<}, @r{>}) -denote obligatory command parameters, while arguments in square brackets -(@r{[}, @r{]}) are optional. A vertical bar (@r{|}) denotes -selection between several alternatives. Arguments in double quotes should -be entered literally (without the quotes themselves). - - - -@node Test control commands, Data display commands, Getting help, Analyzing test results -@section Test control commands - -@cindex commands, test control -@cindex tests, controlling with user commands -The following commands can be used to continue or abort testing, skip a number -of test rounds, enable or disable implementations for testing, and change the -verbosity of @command{lbtt}'s output messages. - -@table @samp -@item continue @r{[}@var{number-of-rounds}@r{]} -@kindex continue -Continue testing. If no argument is given, testing will be interrupted again -when mandated by the current interactivity mode -(@pxref{Interactivity modes}). The optional argument @var{number-of-rounds} -can be used to specify a number of rounds to run; testing is then interrupted -again after the given number of test rounds (or in case of a new -test failure if mandated by the current interactivity mode). - -@item disable @r{[}@var{implementation-id-list}@r{]} -@kindex disable -@cindex disabling LTL-to-B@"uchi translators -@cindex LTL-to-B@"uchi translators, disabling -Disable testing of a list of implementations (all implementations if -no list of implementations is specified). @command{lbtt} will not include these -implementations in the tests in subsequent test rounds. (See -@ref{Command conventions}, for the syntax used for the list of -implementations.) - -@item enable @r{[}@var{implementation-id-list}@r{]} -@kindex enable -@cindex enabling LTL-to-B@"uchi translators -@cindex LTL-to-B@"uchi translators, enabling -Enable testing of a list of implementations. - -@item quit -@kindex quit -@cindex quitting @command{lbtt} -Display test statistics (@pxref{Test statistics}) over the test rounds -performed and then abort testing. - -@item skip @r{[}@var{number-of-rounds}@r{]} -@kindex skip -@cindex tests, skipping test rounds -@cindex skipping test rounds -Skip a number of test rounds and then return to wait for further user input. -If not explicitly specified, the number of rounds to skip defaults to 1. -Use the @samp{--skip} command line option -(@pxref{--skip,,The @samp{--skip} command line option}) to begin -testing from another test round than 1. - -@item verbosity @r{[}@var{verbosity-level}@r{]} -@kindex verbosity -@cindex verbosity, changing -@cindex changing verbosity of output -Display or change the verbosity of @command{lbtt}'s output messages. If no -argument is given, show the current verbosity level, otherwise change the -verbosity setting to the given value. The argument must be an integer between -0 and 5 (inclusive). (The new value will take effect when testing is resumed.) - -@end table - - - -@node Data display commands, Failure analysis commands, Test control commands, Analyzing test results -@section Data display commands - -The following commands can be used to access test result information and to -inspect the LTL formulas, B@"uchi automata and the state space used in the -current test round. - -@table @samp -@item algorithms -@itemx implementations -@itemx translators -@kindex algorithms -@kindex implementations -@kindex translators -Show a list of implementations declared in the program configuration file and -tell whether they are currently enabled for testing. The list also shows the -numeric identifiers of the implementations. - -@item buchi @r{[``}+@r{''} @r{|} @r{``}-@r{'']} @r{<}@var{implementation-id}@r{>} @r{[}@var{state-id-list} | @r{``}dot@r{'']} -@kindex buchi -Display information about the structure of the B@"uchi automaton generated by -the implementation @var{implementation-id} from the positive (@samp{+}) or -negative (@samp{-}) LTL formula used in the current test round. The -implementation identifier may be optionally followed by a list of state -identifiers to display specific states of the automaton (see -@ref{Command conventions}, for details on how the list should be formatted), -or the keyword @samp{dot} to display the automaton in a format that can be -given as input for the @samp{dot} tool of the -@cindex GraphViz -GraphViz graph visualization package -@ifnottex -@ref{[GViz]} -@end ifnottex -@iftex -[GViz] -@end iftex -to obtain a graphical representation of the automaton. - -@item evaluate @r{[``}+@r{''} @r{|} @r{``}-@r{'']} @r{[}@var{implementation-id-list}@r{]} @r{[}@var{state-id-list}@r{]} -@kindex evaluate -Display the model checking results for the positive (@samp{+}) or the negative -(@samp{-}) formula computed using a given set of implementations for -constructing a B@"uchi automaton from the formula. If no implementation list -is specified, show the results for all implementations. The implementation -identifier list may optionally be followed by a list of (state space) state -identifiers to restrict the output to only a subset of all states. (See -@ref{Command conventions}, for more information about the format used for the -lists.) - -This command can be used to look for states in which the model checking result -cross-comparison test (@pxref{Model checking result cross-comparison test}) -failed for a pair of implementations. These state identifiers can then be used -as input for the @samp{resultanalysis} command -(@pxref{Failure analysis commands}). - -Note 1: Observe that the model checking results shown do not follow the -``universal'' semantics of LTL (common in model checking), by which a formula -is usually considered to -hold in a set of infinite paths beginning from a state only if @emph{all} -paths in the set are accepted by the B@"uchi automaton constructed from the -formula to be model checked. Instead, @command{lbtt} will mark the result -true if @emph{any} of these paths is accepted by the automaton. - -Note 2: If using random or enumerated paths as state spaces, @command{lbtt} -accepts also the identifier @samp{lbtt} in the implementation identifier list. -This identifier can be used for accessing the model checking results computed -using @command{lbtt}'s internal model checking algorithm for paths. - -@item formula @r{[``}+@r{''} @r{|} @r{``}-@r{'']} @r{[``}normal@r{''} @r{|} @r{``}nnf@r{'']} -@kindex formula -@cindex LTL formula, displaying with user command -Display the positive (@samp{+}) or the negative (@samp{-}) LTL formula used -for tests in the current test round either in the form in which it was -generated (@samp{normal} -- the default) or in negation normal form -(@samp{nnf}). - -@item inconsistencies @r{[}@var{implementation-id-list}@r{]} -@kindex inconsistencies -List the state space states in which the model checking result consistency -check (@pxref{Model checking result consistency check}) failed for each -implementation in the list (or all implementations if the list is omitted). -See @ref{Command conventions}, for information on formatting the list. -The state identifiers can then be used as input for the -@samp{consistencyanalysis} command (@pxref{Failure analysis commands}). - -@item results @r{[}@var{implementation-id-list}@r{]} -@kindex results -Display test results (in the current test round) for each implementation in the -list (or all -implementations if the list is omitted). -For more information about the output, see @ref{Test round messages}; see -@ref{Command conventions}, for information on how to specify the -implementations. - -@item statespace @r{[}@var{state-id-list} @r{|} @r{``}dot@r{'']} -@kindex statespace -@cindex state space, displaying with an user command -Display information about the structure of the state space used for model -checking tests in the current test round. The optional @var{state-id-list} -can be used to display only a part of the whole state space (see -@ref{Command conventions}, for information on formatting the state list). -Alternatively, the @samp{dot} keyword can be used to output the state space -description in a format recognized by the @samp{dot} tool of -@cindex GraphViz -the GraphViz graph visualization package -@ifnottex -@ref{[GViz]} -@end ifnottex -@iftex -[GViz] -@end iftex -that can be used to obtain a graphical representation of the state space. - -@item @anchor{statistics}statistics -@kindex statistics -Display statistics computed over all test rounds performed since the program -was started. This is the same information that @command{lbtt} normally outputs -at the end of testing; see @ref{Test statistics}, for more information about -the output that is displayed. - -@end table - - - -@node Failure analysis commands, , Data display commands, Analyzing test results -@section Failure analysis commands - -The first part of this section introduces the commands available for -identifying an LTL-to-B@"uchi translator that caused a failure in one of the -automata correctness tests. The second part describes the conventions that -@command{lbtt} uses for justifying the result of the analysis. - -@subsection Alphabetical list of failure analysis commands - -@table @samp -@item buchianalysis @r{<}@var{implementation-id}@r{>} @r{<}@var{implementation-id}@r{>} -@kindex buchianalysis -@cindex B@"uchi automata intersection emptiness check, failure analysis -@cindex tests, failure analysis -@cindex failure analysis, B@"uchi automata intersection check -@cindex analyzing test failures, B@"uchi automata intersection emptiness check -Analyze a failure in the B@"uchi automata intersection emptiness check -(@pxref{Automata intersection emptiness check}). -The two implementation identifiers select the B@"uchi automata for which -to perform the analysis. The B@"uchi automata intersection emptiness -check always involves automata constructed from the positive and the negative -formulas used in the current test round. The first implementation identifier -chooses an implementation that constructed an automaton from the positive -formula, and the second identifier selects an implementation used for -translating the negative formula into an automaton. (The identifiers can also -be equal if one of the tested implementations failed the check against itself.) - -@cindex witness -A failure in the B@"uchi automata intersection emptiness check implies that -there exists an input sequence over subsets of atomic propositions that is -accepted by both automata included in the analysis. @command{lbtt} examines the -intersection of the automata to find a witness of such an input, checks whether -this witness is a model of the positive formula, and tells which one of the -automata is likely to be incorrect according to the following rules: - -@itemize @bullet -@item -If the positive formula is found to hold in the witness, the automaton -constructed from the negative formula is likely to contain an error. - -@item -If the witness is not a model for the positive formula, then the automaton -constructed from the positive formula probably accepts the witness incorrectly. -@end itemize - -@item consistencyanalysis @r{<}@var{implementation-id}@r{>} @r{[}@var{state-id}@r{]} -@kindex consistencyanalysis -@cindex model checking result consistency check, failure analysis -@cindex tests, failure analysis -@cindex failure analysis, model checking result consistency check -@cindex analyzing test failures, model checking result consistency check -Analyze a failure in the model checking result consistency check -(@pxref{Model checking result consistency check}). The -@var{implementation-id} parameter chooses the implementation to analyze. -In addition, the optional @var{state-id} parameter can be used to specify a -state (in the state space) in which to perform the analysis (use the -@samp{inconsistencies} command, @ref{Data display commands}, to see a list -of all states in which the check failed). If the state identifier -is omitted, @command{lbtt} will try to find a state where -the check failed. - -@cindex witness -A failure in the model checking result consistency check implies the existence -of a witness (i.e., a path in the state space used for the tests in the -current test round) whose temporal interpretation is not accepted by either of -two automata constructed from two complementary LTL formulas. In the analysis, -@command{lbtt} finds such a witness, checks separately whether it is a model of -the positive formula, and then tells which one of the automata seems to reject -the witness incorrectly. - -@item resultanalysis @r{[``}+@r{''} @r{|} @r{``}-@r{'']} @r{<}@var{implementation-id}@r{>} @r{<}@var{implementation-id}@r{>} @r{[}@var{state-id}@r{]} -@kindex resultanalysis -@cindex model checking result cross-comparison test, failure analysis -@cindex tests, failure analysis -@cindex failure analysis, model checking result cross-comparison test -@cindex analyzing test failures, model checking result cross-comparison test -Analyze a failure in the model checking result cross-comparison test -(@pxref{Model checking result cross-comparison test}) between two -implementations on either the positive (@samp{+}) or the negative -(@samp{-}) LTL formula used in the current test round. The implementation -identifiers can be optionally followed by an identifier of a state in the -state space to specify a state in which the analysis should be performed. -(Suitable -state identifiers can be found by looking for inconsistencies in the model -checking results accessible with the @samp{evaluate} command, -@ref{Data display commands}; by omitting the state identifier, -@command{lbtt} will try to find a state in which the model -checking result comparison failed between the implementations.) - -If using randomly generated or enumerated paths as state spaces, @command{lbtt} -also accepts the identifier @samp{lbtt} in place of either of the -implementation identifiers. This instructs @command{lbtt} to perform the -analysis against @command{lbtt}'s internal model checking algorithm. - -@cindex witness -A failure in the model checking result cross-comparison test suggests that -the state space used in the current test round contains a path which is -accepted by one, but rejected by another automaton constructed from the same -LTL formula. To determine which one of these automata accepts or rejects the -input incorrectly, @command{lbtt} finds a witness path giving contradictory -model checking results, model checks the formula separately in the witness, -and tells which one of the automata seems to accept or reject the witness -incorrectly. - -@end table - -@subsection Witnesses, proofs and refutations - -@cindex witness -All of the above analysis commands use @command{lbtt}'s internal model -checking algorithm to determine which one of the two automata involved in -each test is incorrect by checking whether an LTL formula holds in a witness -path extracted from the state space used in the current test round or from the -intersection of two B@"uchi automata. The witness path is a sequence of -consecutive states that ends in a loop, and is represented in two parts as an -initial -``prefix'' (which may be empty) and a ``cycle'' that is considered to repeat -itself indefinitely. The witness might, for example, look as follows: - -@smallexample - Execution M: - prefix: - s3 @{p0,p2,p4@} --> s4 - cycle: - s4 @{p1,p3@} --> s5 - s5 @{p3@} --> s6 - s6 @{p1,p2,p3@} --> s7 - s7 @{p3,p4@} --> s8 - s8 @{p1@} --> s9 - s9 @{@} --> s2 - s2 @{@} --> s3 - s3 @{p0,p2,p4@} --> s4 -@end smallexample - -@noindent -In this case, the witness (or ``execution'' as displayed in the output) -@math{M} consists of a single-state prefix followed by a cycle of eight -states. The atomic propositions that hold in each state are also shown in -the output. - -(The witness can be considered a small state space -@iftex -@tex -$M = \langle S, \rho, {\cal L} \rangle$ -@end tex -@end iftex -@ifnottex -@math{M = } -@end ifnottex -following the definition in @ref{State spaces}; in the example above, -@iftex -@tex -$S = \{s_2, s_3, s_4, s_5, s_6, s_7, s_8, s_9\}$, -@end tex -@end iftex -@ifnottex -@math{S = @{s2, s3, s4, s5, s6, s7, s8, s9@}}, -@end ifnottex -@iftex -@tex -$\rho = \{(s_2, s_3), (s_3, s_4), (s_4, s_5), (s_5, s_6), (s_6, s_7), - (s_7, s_8), (s_8, s_9), (s_9, s_2)\}$, -@end tex -@end iftex -@ifnottex -@math{R = @{(s2, s3), (s3, s4), (s4, s5), (s5, s6), (s6, s7), (s7, s8), (s8, s9), (s9, s2)@}}, -@end ifnottex -@iftex -@tex -${\cal L}(s_2) = {\cal L}(s_9) = \emptyset$, -${\cal L}(s_3) = \{p_0, p_2, p_4\}$, -${\cal L}(s_4) = \{p_1, p_3\}$, -${\cal L}(s_5) = \{p_3\}$, -${\cal L}(s_6) = \{p_1, p_2, p_3\}$, -${\cal L}(s_7) = \{p_3, p_4\}$, and -${\cal L}(s_8) = \{p_1\}$.) -@end tex -@end iftex -@ifnottex -@math{L(s2) = L(s_9) = @{@}, L(s3) = @{p0, p2, p4@}, L(s4) = @{p1, p3@}, L(s5) = @{p3@}, L(s6) = @{p1, p2, p3@}, L(s7) = @{p3, p4@},} and @math{L(s8) = @{p1@}}.) -@end ifnottex - - -In the model checking result cross-comparison test and the model checking -result consistency check, the witness is an actual path extracted from the -state space used for the tests in the current test round. In this case, the -state identifiers correspond to the states of the state space, and can be -accessed with the @samp{statespace @r{[}@var{state-id}@r{]}} command -(@pxref{Data display commands}). - -@cindex proof for an LTL formula -@cindex refutation for an LTL formula -To justify the result of the analysis, @command{lbtt} also displays a proof -or a refutation for the LTL formula in the witness. The proof or refutation is -constructed by a recursive examination of the subformulas of the (positive or -negative) formula used in the current test round according to the semantics of -LTL and might look as follows: - -@smallexample - Analysis of the formula in the execution: - M, |/= ((X p0 U ! p4) <-> p0) : - +-> M, |/= (X p0 U ! p4) : - | +-> M, |/= X p0 : - | | +-> s3 --> s4 - | | +-> M, |/= p0 - | +-> M, |/= ! p4 : - | +-> M, |== p4 - +-> M, |== p0 -@end smallexample - -@noindent -The proof (or refutation) can be considered a tree of statements of the form -@samp{M, |== @var{subformula}} or -@samp{M, |/= @var{subformula}}. Here, the symbol @samp{|==} is used -to denote that the formula @var{subformula} holds in the (infinite) -subsequence beginning at state @samp{s} of the witness, and the relational -symbol @samp{|/=} denotes the opposite. The children of each proof tree node -give justification for the claim in their parent node; the children might be -further expanded if the claims in them do not directly follow from the -definition of -@iftex -@tex -${\cal L}$. -@end tex -@end iftex -@ifnottex -@math{L}. -@end ifnottex -In the presence of temporal operators, the proofs may -need to be based also on the structural properties of @math{M}. These are -shown as statements of the form @samp{sn --> sm} to indicate that @math{M} -contains a transition from the state @samp{sn} to the state @samp{sm} (and, -since the states in @math{M} are connected into a non-branching sequence, that -this is the @emph{only} transition originating from @samp{sn}). - -In the above example, @command{lbtt} claims that the formula -@samp{((X p0 U ! p4) <-> p0)} does not hold in the witness presented earlier -in this section, and that this follows (by the semantics of logical -equivalence) from the claims that the subformula @samp{(X p0 U ! p4)} does not -hold, but the subformula @samp{p0} holds in this witness. -@samp{(X p0 U ! p4)} does not hold in the witness, because neither -@samp{X p0} nor @samp{! p4} holds in the first state of the witness -@iftex -@tex -($p_4 \in {\cal L}(s_3)$, and $p_0 \notin {\cal L}(s_4)$, where $s_4$ is the -only successor of $s_3$). -@end tex -@end iftex -@ifnottex -(@math{p4} is included in @math{L(s3)}, and @math{p0} is not included in -@math{L(s4)}, where @math{s4} is the only successor of @math{s3}). -@end ifnottex -On the other hand, -@samp{p0} holds in the witness because of the fact that -@iftex -@tex -$p_0 \in {\cal L}(s_3)$. -@end tex -@end iftex -@ifnottex -@math{p0} is included in @math{L(s3)}. -@end ifnottex - - - -@node Interfacing with lbtt, References, Analyzing test results, Top -@chapter Interfacing with @command{lbtt} - -@cindex LTL-to-B@"uchi translators, interfacing with -@cindex interfacing LTL-to-B@"uchi translators with @command{lbtt} - -The output generated by @command{lbtt} consists of textual messages -and an optional error log file (@pxref{--logfile,,@samp{--logfile} command line -option}). The format of the output messages is determined by the verbosity -mode; -for more information, see @ref{Interpreting the output}. In addition, -@command{lbtt} returns one of the following three values as its exit -status upon normal termination: -@itemize -@item 0: -@command{lbtt} exited successfully; no errors were detected during testing. - -@item 1: -@command{lbtt} exited successfully; errors were detected during testing. - -@item 2: -An error was found when reading the program configuration or when processing -the command line options. - -@item 3: -@command{lbtt} exited due to an unrecoverable internal error. -@end itemize - -The rest of this chapter gives the details on how to use @command{lbtt} for -testing LTL-to-B@"uchi translation algorithm implementations that are not -supported by the basic distribution. (See -@ref{The lbtt-translate utility} -for information on how to connect several publicly available -LTL-to-B@"uchi translator implementations to @command{lbtt}.) - -@menu -* Translator interface:: @command{lbtt}'s requirements for an - LTL-to-B@"uchi translator. -* Format for LTL formulas:: How @command{lbtt} passes LTL formulas - to the translators. -* Format for automata:: How @command{lbtt} expects the translators - to present their output. -* The lbtt-translate utility:: An interface for two LTL-to-B@"uchi - translators. -@end menu - - - -@node Translator interface, Format for LTL formulas, , Interfacing with lbtt -@section Requirements for translator executables - -@cindex LTL-to-B@"uchi translators, interface requirements -@command{lbtt} assumes each tested LTL-to-B@"uchi translator to be -accessible by running an executable file which should read in an LTL -formula from a file, convert it into a B@"uchi automaton and then -write the automaton into another file. For this purpose, the executable -should support the following command line interface: - -@example -@var{path-to-program} @var{parameters} @var{input-file} @var{output-file} -@end example - -@noindent -where @var{path-to-program} is the full name (and location) of the -executable, @var{parameters} are any optional parameters that might be needed -for running the executable, and @var{input-file} and -@var{output-file} are two file names. -The translator executable should read its input (an LTL formula) from -@var{input-file} and write its output (a B@"uchi automaton) into -@var{output-file} (without removing the input file); see -@ifnottex -@ref{Format for LTL formulas} and @ref{Format for automata} -@end ifnottex -@iftex -the following two sections -@end iftex -for a description on how these files should be formatted. - -The translator executable should always create an output file and then return -with a zero exit status in case no errors occur during the translation. -@command{lbtt} interprets a missing output file or a nonzero exit status as -an error and will not in this case try to run any tests, even if -an automaton were successfully saved in an output file. - -To start testing the translator, add a new @samp{Translator} section for it -into -@command{lbtt}'s configuration file (@pxref{Configuration file}), for example - -@smallexample -Translator -@{ - Name = "LTL-to-B@"uchi translator" - Path = /home/lbtt-user/bin/ltl-to-buchi-translator - Parameters = "-x -y -z" - Enabled = Yes -@} -@end smallexample - - - -@node Format for LTL formulas, Format for automata, Translator interface, Interfacing with lbtt -@section Input file format for LTL formulas - -@cindex LTL-to-B@"uchi translators, LTL formula input file format -@cindex LTL formula, LTL-to-B@"uchi translator input file format -@cindex file formats, LTL-to-B@"uchi translator input file -@command{lbtt} passes each LTL formula to each LTL-to-B@"uchi translator -in a file containing an LTL formula in a prefix notation followed by a -single newline. The precise grammar for the LTL formulas (in a BNF-style -notation) is as follows: - -@smallexample -@var{formula} @r{::=} `t' - @r{// ``true''} - @r{|} `f' - @r{// ``false''} - @r{|} `p'@r{[}0@r{---}9@r{]+} - @r{// atomic proposition with} - @r{// a nonnegative integer} - @r{// identifier} - @r{|} `!' @var{sp} @var{formula} - @r{// negation} - @r{|} `X' @var{sp} @var{formula} - @r{// ``next time''} - @r{|} `F' @var{sp} @var{formula} - @r{// ``finally''} - @r{|} `G' @var{sp} @var{formula} - @r{// ``globally''} - @r{|} `&' @var{sp} @var{formula} @var{sp} @var{formula} - @r{// conjunction} - @r{|} `|' @var{sp} @var{formula} @var{sp} @var{formula} - @r{// disjunction} - @r{|} `i' @var{sp} @var{formula} @var{sp} @var{formula} - @r{// implication} - @r{|} `e' @var{sp} @var{formula} @var{sp} @var{formula} - @r{// equivalence} - @r{|} `^' @var{sp} @var{formula} @var{sp} @var{formula} - @r{// exclusive or} - @r{|} `U' @var{sp} @var{formula} @var{sp} @var{formula} - @r{// ``(strong) until''} - @r{|} `V' @var{sp} @var{formula} @var{sp} @var{formula} - @r{// ``(weak) release''} - @r{|} `W' @var{sp} @var{formula} @var{sp} @var{formula} - @r{// ``weak until''} - @r{|} `M' @var{sp} @var{formula} @var{sp} @var{formula} - @r{// ``strong release''} - @r{|} `B' @var{sp} @var{formula} @var{sp} @var{formula} - @r{// ``before''} - -@end smallexample -@noindent -(The quoted characters denote the characters themselves; @var{sp} denotes -any nonempty string of white space. Lines containing a // are comments and -are not part of the grammar. All atomic propositions in the formula have a -nonnegative numeric identifier.) - -@noindent -For example, the LTL formula -@iftex -@tex -$(p_0\;{\bf U}\;p_1)\rightarrow({\bf F}\;{\bf G}(\neg p_2\leftrightarrow p_3))$ -@end tex -@end iftex -@ifnottex -(in @command{lbtt}'s infix syntax) -@example -(p0 U p1) -> (<> [] (! p2 <-> p3)) -@end example -@end ifnottex -@noindent -would be expressed in the form -@example -i U p0 p1 F G e ! p2 p3 -@end example -@noindent -in an output file. - -If your translator does not support all of the above operators, edit -the configuration file (@pxref{Configuration file}) or use the command -line options (@pxref{Command line options}) to prevent -@command{lbtt} from generating random LTL formulas with these operators. - - - -@node Format for automata, The lbtt-translate utility, Format for LTL formulas, Interfacing with lbtt -@section Output file format for automata - -@cindex file formats, LTL-to-B@"uchi translator output file -@cindex LTL-to-B@"uchi translators, automaton output file format -@cindex B@"uchi automata, LTL-to-B@"uchi translator output file format -@cindex generalized B@"uchi automata, LTL-to-B@"uchi translator output file format -@command{lbtt} expects the B@"uchi automata generated by each LTL-to-B@"uchi -translator implementation to be in the format specified below. The format -encodes a generalized B@"uchi automaton (a B@"uchi automaton with zero or -more acceptance conditions) with a single initial state and labels (guards) on -transitions. For the full formal definition and examples on how -to reduce other definitions into the one used by @command{lbtt}, see -@ref{Definitions}. - -The output file generated by the translator should contain an @var{automaton} -described using the following grammar -(as before, quoted characters denote the characters themselves, @var{sp} -denotes any nonempty string of white space, lines containing a // are -comments that are not part of the grammar, and @samp{\n} corresponds to the -newline character). - -@smallexample -@var{automaton} @r{::=} @var{num-states} @var{sp} @var{cond-specifier} @var{state-list} - -@var{num-states} @r{::=} @r{[}0@r{---}9@r{]+} - -@var{cond-specifier} @r{::=} @r{[}0@r{---}9@r{]+}@r{[}st@r{]}* - -@var{state-list} @r{::=} @var{state-list} @var{sp} @var{state} - @r{|} @r{// empty} -@end smallexample - -@noindent -The automaton description begins with a nonnegative number that gives the -number of states in the automaton. If the number of -states is 0, the automaton will not accept any input. If the number is -positive, it should be followed by a @var{cond-specifier} that determines the -number -and placement of acceptance conditions in the automaton. If the number of -acceptance conditions is 0, the automaton accepts an input word if and only if -it has a run on that word according to the definition given in the -Appendix (@pxref{Definitions}). - -The placement of acceptance conditions is specified by concatenating a -string formed from the symbols @samp{s} and @samp{t} to the number of -acceptance conditions (with no white space in between). The interpretation of -this string is as follows: -@itemize -@item -If the string is empty or does not include the symbol @samp{t}, the acceptance -conditions of the automaton are placed exclusively on its states. (This -alternative corresponds to the definition supported by @command{lbtt} 1.0.x.) - -@item -If the string is nonempty but does not include the symbol @samp{s}, the -automaton has acceptance conditions exclusively on its transitions. - -@item -Otherwise, the automaton has acceptance conditions on both states and -transitions. -@end itemize - -The @var{cond-specifier} is followed by a list of the descriptions of states in -the automaton. The format of this list is affected by the choice of the -placement of the acceptance conditions. -More precisely, the choice affects the interpretation of the -@var{cond-list} nonterminal symbol in the following fragment of the grammar: we -indicate this by prefixing the nonterminal with either ``'' or -``'' to denote that the list (together with its terminating @samp{-1}) -should be -omitted in automata that do not associate acceptance conditions with states or -transitions, respectively. - -@smallexample -@var{state} @r{::=} @var{state-id} @var{sp} @var{initial?} @r{}@var{cond-list} @var{transition-list} - -@var{state-id} @r{::=} @r{[}0@r{---}9@r{]+} - -@var{initial?} @r{::=} `0' @r{|} `1' - -@var{cond-list} @r{::=} @var{sp} @var{acceptance-condition-id} @var{cond-list} - @r{|} @var{sp} `-1' - -@var{acceptance-condition-id} @r{::=} @r{[}0@r{---}9@r{]+} - -@var{transition-list} @r{::=} @var{sp} @var{transition} @var{transition-list} - @r{|} @var{sp} `-1' - -@var{transition} @r{::=} @var{state-id} @r{}@var{cond-list} @var{sp} @var{guard-formula} `\n' - -@var{guard-formula} @r{::=} `t' - @r{// ``true''} - @r{|} `f' - @r{// ``false''} - @r{|} `p'@r{[}0@r{---}9@r{]+} - @r{// atomic proposition} - @r{|} `!' @var{sp} @var{guard-formula} - @r{// negation} - @r{|} `&' @var{sp} @var{guard-formula} @var{sp} @var{guard-formula} - @r{// conjunction} - @r{|} `|' @var{sp} @var{guard-formula} @var{sp} @var{guard-formula} - @r{// disjunction} - @r{|} `i' @var{sp} @var{guard-formula} @var{sp} @var{guard-formula} - @r{// implication} - @r{|} `e' @var{sp} @var{guard-formula} @var{sp} @var{guard-formula} - @r{// equivalence} - @r{|} `^' @var{sp} @var{guard-formula} @var{sp} @var{guard-formula} - @r{// exclusive or} -@end smallexample -@noindent - -The description of each state begins with a numeric state identifier, which can -be any nonnegative integer. The state identifier should be followed by a number -telling whether the state is initial (@samp{1} if yes). The automaton should -have exactly one initial state. If the automaton has acceptance conditions -associated with its states, this number should then be followed by a list of -acceptance condition identifiers separated by white space. This list should be -terminated with @samp{-1}. - -The state description should be followed by the list of transitions starting -from the state (terminated again by @samp{-1}). Each transition consists of a -state identifier (the target state of the transition), a list of acceptance -condition identifiers (if the automaton has acceptance conditions on -transitions), and a propositional formula @footnote{Although not described -formally in the grammar, the guard formulas can be specified in any -of the formats @command{lbtt} supports in its formula input files -(@pxref{--formulafile,,@samp{--formulafile} command line option}). Note that -the formula always needs to be terminated with a newline, though.} that encodes -the symbols of the alphabet -@iftex -@tex -$2^{AP}$ -@end tex -@end iftex -@ifnottex -@math{2^AP} -@end ifnottex -(where @var{AP} is a finite set of atomic propositions) on which the -automaton is allowed to take the transition. The propositional formula should -be terminated with a newline. - -The state and acceptance condition identifiers need not be successive, and the -states or acceptance conditions can be listed in any order. The only -restrictions are that the identifiers of different states and acceptance -conditions should be unique and that the total number of different identifiers -should equal @var{num-states} or @var{num-conds}, -respectively. (The same identifiers can be shared between states and acceptance -conditions, however.) - - -Note that the output file should always contain a valid automaton description -if the LTL-to-B@"uchi translation was successful, even in the case that the -resulting automaton is empty (@command{lbtt} interprets a missing automaton -description file as an error). - -The following examples illustrate the file format. The first example -gives the description of an automaton with acceptance conditions on -states. Note that in this case the @samp{s} is optional for describing the -placement of acceptance conditions; therefore, the automaton files used with -@command{lbtt} 1.0.x are upwards compatible with newer versions of the tool -(provided that each guard of a transition is terminated by a newline). - -@smallexample -6 2s @r{// an automaton with six states and two acc.@ conditions on states} -0 1 -1 @r{// state 0: initial state, no acceptance conditions} -2 p1 @r{// transition to state 2, guard} @samp{p1} -5 p2 @r{// transition to state 5, guard} @samp{p2} -15 p3 @r{// transition to state 15, guard} @samp{p3} --1 @r{// end of state 0} -2 0 1 -1 @r{// state 2: non-initial state, acceptance condition 1} -2 p1 @r{// transition to state 2, guard} @samp{p1} -5 p2 @r{// transition to state 5, guard} @samp{p2} -15 p3 @r{// transition to state 15, guard} @samp{p3} --1 @r{// end of state 2} -5 0 0 -1 @r{// state 5: non-initial state, acceptance condition 0} -5 p2 @r{// transition to state 5, guard} @samp{p2} -8 & p1 p2 @r{// transition to state 8, guard} @samp{p1 /\ p2} -12 & p1 p3 @r{// transition to state 12, guard} @samp{p1 /\ p3} -15 p3 @r{// transition to state 15, guard} @samp{p3} --1 @r{// end of state 5} -8 0 0 -1 @r{// state 8: non-initial state, acceptance condition 0} -5 p2 @r{// transition to state 5, guard} @samp{p2} -8 & p1 p2 @r{// transition to state 8, guard} @samp{p1 /\ p2} -12 & p1 p3 @r{// transition to state 12, guard} @samp{p1 /\ p3} -15 p3 @r{// transition to state 15, guard} @samp{p3} --1 @r{// end of state 8} -15 0 1 0 -1 @r{// state 15: non-initial state, acceptance conditions 1 and 0} -2 p1 @r{// transition to state 2, guard} @samp{p1} -5 p2 @r{// transition to state 5, guard} @samp{p2} -15 p3 @r{// transition to state 15, guard} @samp{p3} --1 @r{// end of state 15} -12 0 1 0 -1 @r{// state 12: non-initial state, acceptance conditions 1 and 0} -2 p1 @r{// transition to state 2, guard} @samp{p1} -5 p2 @r{// transition to state 5, guard} @samp{p2} -15 p3 @r{// transition to state 15, guard} @samp{p3} --1 @r{// end of state 12} -@end smallexample - -@noindent -The following example illustrates an automaton in which acceptance conditions -are placed on transitions. - -@smallexample -4 3t @r{// four states, three acceptance conditions on transitions} -5 0 @r{// state 5: non-initial state} -84 0 -1 p1 @r{// transition to state 84, condition 0, guard} @samp{p1} -27 0 -1 & p1 ! p2 @r{// tr. to state 27, condition 0, guard} @samp{p1 /\ ! p2} -5 -1 t @r{// transition to state 5, no conditions, guard} @samp{true} --1 @r{// end of state 5} -84 1 @r{// state 84: initial state} -5 1 -1 t @r{// transition to state 5, condition 1, guard} @samp{true} -27 0 -1 p1 @r{// transition to state 27, condition 0, guard} @samp{p1} --1 @r{// end of state 84} -49 0 @r{// state 49: non-initial state} -5 -1 t @r{// transition to state 5, no conditions, guard} @samp{true} -49 1 4 -1 & p1 ! p2 @r{// tr.@ to state 49, conds.@ 1 and 4, guard} @samp{p1 /\ ! p2} -84 -1 p1 @r{// transition to state 84, no conditions, guard} @samp{p1} --1 @r{// end of state 49} -27 0 @r{// state 27: non-initial state} -49 -1 & p1 p3 @r{// transition to state 49, no conds., guard} @samp{p1 /\ p3} --1 @r{// end of state 27} -@end smallexample - -@noindent -Automata with acceptance conditions on both states and transitions can be -specified using a combination of the above two formats, that is, by using -@samp{st} as the acceptance condition placement specifier and including a list -of acceptance conditions both after the value determining the initialness of a -state, and after the identifier of the target state of each transition. - -@node The lbtt-translate utility, , Format for automata, Interfacing with lbtt -@section The @command{lbtt-translate} utility - -@cindex @command{lbtt-translate} (executable file) -@cindex LTL-to-B@"uchi translators, interfacing with -@cindex interfacing LTL-to-B@"uchi translators with @command{lbtt} -The @command{lbtt} source distribution includes a small utility which can be -used as a common interface for the following publicly available LTL-to-B@"uchi -translator algorithm implementations: - -@itemize @bullet -@item -@cindex @command{lbt} -@command{lbt} --- an LTL-to-B@"uchi translation algorithm implementation -based on the algorithm described in -@ifnottex -@ref{[GPVW95]}. -@end ifnottex -@iftex -[GPVW95]. -@end iftex -See -@ifinfo -@url{http://www.tcs.hut.fi/Software/maria/tools/lbt/} -@end ifinfo -@ifnotinfo -<@uref{http://www.tcs.hut.fi/Software/maria/tools/lbt/}> -@end ifnotinfo -for more information, including the source code of the implementation. - -@item -@cindex SPIN -@ifnottex -SPIN @ref{[Hol97]} -@end ifnottex -@iftex -@tex -\sc{Spin} -@end tex -[Hol97] -@end iftex ---- a model checking tool -that includes a module for translating LTL formulas into B@"uchi automata -originally based on the algorithm presented in -@ifnottex -@ref{[GPVW95]}. -@end ifnottex -@iftex -[GPVW95]. -@end iftex -See -@ifinfo -@url{http://spinroot.com/spin/whatispin.html} -@end ifinfo -@ifnotinfo -<@uref{http://spinroot.com/spin/whatispin.html}> -@end ifnotinfo -for more information. - -@item -@cindex Spot -@ifnottex -Spot @ref{[DP04]} -@end ifnottex -@iftex -Spot [DP04] -@end iftex ---- a model checking library that includes a module for translating LTL -formulas into B@"uchi automata incorporating optimization techniques from -several different sources. See -@ifinfo -@url{http://spot.lip6.fr/} -@end ifinfo -@ifnotinfo -<@uref{http://spot.lip6.fr/}> -@end ifnotinfo -for more information. -@end itemize - -To use @command{lbtt} for testing the LTL-to-B@"uchi translators included in -these tools, you should first install the tool normally by following its -installation instructions. Then add the following @samp{Translator} section in -@command{lbtt}'s configuration file: - -@smallexample -Translator -@{ - Name = "@r{[@var{name for the implementation}]}" - Path = "@r{[@var{path to @command{lbtt-translate}}]}" - Parameters = "@r{[@var{implementation selector}]} @r{[@var{path to executable}]}" - Enabled = Yes -@} -@end smallexample - -@noindent -where [@var{path to @command{lbtt-translate}}] contains the complete path and -file name of the @command{lbtt-translate} tool executable, -[@var{implementation selector}] is either of the options @samp{--lbt} or -@samp{--spin}, and [@var{path to executable}] is the full path -of the tool executable. The names of these executables are usually (assuming -a normal installation) @command{lbt} and @command{spin}, respectively. - -Note: These implementations may not have built-in support for all of the -LTL formula operators available for generating random LTL formulas with -@command{lbtt}. See the documentation of each translator for information -about which operators are supported, and then change the parameters in -@command{lbtt}'s configuration file accordingly to disable the unsupported -operators (or instruct @command{lbtt} to read the formulas from an external -source by invoking @command{lbtt} with the -@ref{--formulafile,,@samp{--formulafile} command line option}). - -The @command{lbtt-translate} utility can also be invoked directly from the -shell to translate an LTL formula into a B@"uchi automaton using either of the -above translators. Use the command @command{lbtt-translate --help} to -see a short summary of available options. - - - -@node References, Definitions, Interfacing with lbtt, Top -@unnumbered References - -@table @asis -@item @anchor{[CGP99]} [CGP99] -E.@: Clarke Jr., O.@: Grumberg and D.@: Peled. Model checking. The MIT Press, -1999. - -@item @anchor{[Cou99]} [Cou99] -J.-M.@: Couvreur. On-the-fly verification of linear temporal logic. In -@i{Proceedings of the World Congress on Formal Methods in the Development of -Computing Systems (FM'99), volume I}, volume 1708 of -@i{Lecture Notes in Computer Science}, pages 253---271. Springer-Verlag, 1999. - -@item @anchor{[DGV99]} [DGV99] -M.@: Daniele, F.@: Giunchiglia and M.@: Y.@: Vardi. Improved automata -generation for linear temporal logic. In @i{Proceedings of the 11th -International Conference on Computer Aided Verification (CAV'99)}, volume 1633 -of @i{Lecture Notes in Computer Science}, pages 249---260. Springer-Verlag, -1999. - -@item @anchor{[DP04]} [DP04] -A.@: Duret-Lutz and D.@: Poitrenaud. SPOT: An Extensible Model Checking Library -Using Transition-Based Generalized B@"uchi Automata. In -@i{Proceedings of the 12th IEEE/ACM International Symposium on Modeling, -Analysis, and Simulation of Computer and Telecommunication Systems -(MASCOTS 2004)}, pages 76--83. IEEE Computer Society Press, 2004. - -@item @anchor{[EH00]} [EH00] -K.@: Etessami and G.@: Holzmann. Optimizing B@"uchi automata. In -@i{Proceedings of the 11th International Conference on Concurrency Theory -(CONCUR 2000)}, volume 1877 of @i{Lecture Notes in Computer Science}, -pages 153---167. Springer-Verlag, 2000. - -@item @anchor{[Ete99]} [Ete99] -K.@: Etessami. Stutter-invariant languages, omega-automata, and temporal -logic. In @i{Proceedings of the 11th International Conference on Computer Aided -Verification (CAV'99)}, volume 1633 of @i{Lecture Notes in Computer Science}, -pages 236---248. Springer-Verlag, 1999. - -@item @anchor{[Ete02]} [Ete02] -K.@: Etessami. A hierarchy of polynomial-time computable simulations for -automata. In @i{Proceedings of the 13th International Conference on -Concurrency Theory (CONCUR 2002)}, volume 2421 of -@i{Lecture Notes in Computer Science}, pages 131---144. Springer-Verlag, 2002. - -@item @anchor{[EWS01]} [EWS01] -K.@: Etessami, Th.@: Wilke and R.@: Schuller. Fair simulation relations, -parity games, and state space reduction for B@"uchi automata. In -@i{Proceedings of the 28th International Colloquium on Automata, Languages and -Programming (ICALP 2001)}, volume 2076 of -@i{Lecture Notes in Computer Science}, pages 694---707. Springer-Verlag, 2001. - -@item @anchor{[Fri03]} [Fri03] -C.@: Fritz. Constructing B@"uchi automata from linear temporal logic using -simulation relations for alternating B@"uchi automata. In -@i{Proceedings of the 8th International Conference on Implementation and -Application of Automata (CIAA 2003)}, volume 2759 of -@i{Lecture Notes in Computer Science}, pages 35---48. Springer-Verlag, 2003. - -@item @anchor{[GO01]} [GO01] -P.@: Gastin and D.@: Oddoux. Fast LTL to B@"uchi automata translation. -In @i{Proceedings of the 13th International Conference on Computer -Aided Verification (CAV 2001)}, volume 2102 of @i{Lecture Notes in Computer -Science}, pages 53---65. Springer-Verlag, 2001. - -@item @anchor{[GO03]} [GO03] -P.@: Gastin and D.@: Oddoux. LTL with past and two-way weak alternating -automata. In @i{Proceedings of the 28th International Symposium on Mathematical -Foundations of Computer Science (MFCS 2003)}, volume 2747 of -@i{Lecture Notes in Computer Science}, pages 439---448. Springer-Verlag, 2003. - -@item @anchor{[Gei01]} [Gei01] -M.@: C.@: W.@: Geilen. On the construction of monitors for temporal logic -properties. @i{Electronic Notes for Theoretical Computer Science}, 55(2), 2001. - -@item @anchor{[GPVW95]} [GPVW95] -R.@: Gerth, D.@: Peled, M.@: Y.@: Vardi and P.@: Wolper. Simple on-the-fly -automatic verification of linear temporal logic. In -@i{Proceedings of 15th IFIP WG6.1 International Symposium on Protocol -Specification, Testing, and Verification (PSTV'95)}, pages 3---18. -Chapman & Hall, 1995. - -@item @anchor{[GL02]} [GL02] -D.@: Giannakopoulou and F.@: Lerda. From states to transitions: Improving -translation of LTL formulae to B@"uchi automata. In -@i{Proceedings of the 22nd IFIP WG6.1 International Conference on Formal -Techniques for Networked and Distributed Systems (FORTE 2002)}, volume 2529 of -@i{Lecture Notes in Computer Science}, pages 308---326. Springer-Verlag, 2002. - -@item @anchor{[GSB02]} [GSB02] -S.@: Gurumurthy, F.@: Somenzi and R.@: Bloem. Fair simulation minimization. -In @i{Proceedings of the 14th International Conference on Computer Aided -Verification (CAV 2002)}, volume 2404 of @i{Lecture Notes in Computer Science}, -pages 610---624. Springer-Verlag, 2002. - -@item @anchor{[GViz]} [GViz] -GraphViz - open source graph drawing software. See -@ifinfo -@url{http://www.research.att.com/sw/tools/graphviz/}. -@end ifinfo -@ifnotinfo -<@uref{http://www.research.att.com/sw/tools/graphviz/}>. -@end ifnotinfo - -@item @anchor{[Hol97]} [Hol97] -G.@: J.@: Holzmann. The model checker -@ifnottex -SPIN. -@end ifnottex -@iftex -@tex -\sc{Spin}. -@end tex -@end iftex -@i{IEEE Transactions on Software Engineering}, 23(5):279---295, 1997. - -@item @anchor{[Isl94]} [Isl94] -A.@: Isli. Mapping an LPTL formula into a B@"uchi alternating automaton -accepting its models. In @i{Temporal Logic: Proceedings of the ICTL Workshop}, -pages 85---90. Research Report MPI-I-94-230, Max-Planck-Institut f@"ur -Informatik, 1994. - -@item @anchor{[Lat03]} [Lat03] -T.@: Latvala. Efficient model checking of safety properties. In -@i{Proceedings of the 10th Spin Workshop on Model Checking of Software -(SPIN 2003)}, volume 2648 of @i{Lecture Notes in Computer Science}, pages -74---88. Springer-Verlag, 2003. - -@item @anchor{[Sch01]} [Sch01] -K.@: Schneider. Improving automata generation for linear temporal logic by -considering the automaton hierarchy. In @i{Proceedings of the 8th International -Conference on Logic for Programming, Artificial Intelligence and Reasoning -(LPAR 2001)}, volume 2250 of @i{Lecture Notes in Computer Science}, pages -39---54. Springer-Verlag, 2001. - -@item @anchor{[ST03]} [ST03] -R.@: Sebastiani and S.@: Tonetta. ``More deterministic'' vs.@: ``smaller'' -B@"uchi automata for efficient LTL model checking. In -@i{Proceedings of the 12th Advanced Research Working Conference on Correct -Hardware Design and Verification Methods (CHARME 2003)}, volume 2860 of -@i{Lecture Notes in Computer Science}, pages 126---140. Springer-Verlag, 2003. - -@item @anchor{[SB00]} [SB00] -F.@: Somenzi and R.@: Bloem. Efficient B@"uchi automata from LTL formulae. -In @i{Proceedings of the 12th International Conference on Computer Aided -Verification (CAV 2000)}, volume 1855 of @i{Lecture Notes in Computer Science}, -pages 247---263. Springer-Verlag, 2000. - -@item @anchor{[Tau00]} [Tau00] -H.@: Tauriainen. Automated testing of B@"uchi automata translators -for linear temporal logic. Research report A66, Laboratory for Theoretical -Computer Science, Helsinki University of Technology, Espoo, Finland, -2000. Available on the WWW at -@ifinfo -@url{http://www.tcs.hut.fi/Publications/info/bibdb.HUT-TCS-A66.shtml} -@end ifinfo -@ifhtml -<@uref{http://www.tcs.hut.fi/Publications/info/bibdb.HUT-TCS-A66.shtml}>. -@end ifhtml -@iftex -<@url{http://www.tcs.hut.fi/Publications/info/ bibdb.HUT-TCS-A66.shtml}>. -@end iftex - -@item @anchor{[TH02]} [TH02] -H.@: Tauriainen and K.@: Heljanko. Testing LTL formula translation into B@"uchi -automata. -@i{International Journal on Software Tools for Technology Transfer (STTT)} -4(1):57---70, 2002. - -@item @anchor{[Thi02]} [Thi02] -X.@: Thirioux. Simple and efficient translation from LTL formulas to B"uchi -automata. @i{Electronic Notes in Theoretical Computer Science}, 66(2), 2002. - -@item @anchor{[Var96]} [Var96] -M.@: Y.@: Vardi. An automata-theoretic approach to linear temporal logic. -In @i{Logics for Concurrency: Structure versus Automata}, volume 1043 of -@i{Lecture Notes in Computer Science}, pages 238---265. Springer-Verlag, -1996. - -@item @anchor{[VW86]} [VW86] -M.@: Y.@: Vardi and P.@: Wolper. An automata-theoretic approach to -automatic program verification. In @i{Proceedings of the First IEEE -Symposium on Logic in Computer Science (LICS'86)}, pages 332---344. IEEE -Computer Society Press, 1986. - -@item @anchor{[Wol01]} [Wol01] -P.@: Wolper. Constructing automata from temporal logic formulas: A tutorial. -In @i{Lectures on Formal Methods and Performance Analysis: First EEF/Euro -Summer School on Trends in Computer Science, Revised Lectures}, volume 2090 -of @i{Lecture Notes in Computer Science}, pages 261---277. Springer-Verlag, -2001. - -@end table - - - -@node Definitions, Configuration file option index, References, Top -@appendix Definitions - -This appendix reviews the formal definitions of the objects that @command{lbtt} -manipulates. - -@menu -* LTL formulas:: @command{lbtt} uses traditional semantics - for propositional linear temporal - logic. -* Generalized automata:: The B@"uchi automata used by @command{lbtt} - have one initial state, labels on - transitions and zero or more - acceptance conditions. -* State spaces:: State spaces are Kripke structures - with a total transition relation. -@end menu - - -@node LTL formulas, Generalized automata, Definitions, Definitions -@appendixsec LTL formulas - -@command{lbtt} uses the traditional definition for propositional linear -temporal logic. Let @math{AP} be a finite set of atomic propositions. -The set of propositional linear temporal logic formulas is defined inductively -as follows: - -@itemize @bullet -@item -@cindex @samp{t} (Boolean constant semantics in LTL) -@cindex true (Boolean constant semantics in LTL) -All atomic propositions in @math{AP} and the Boolean constant -@iftex -@tex -\sc{True} -@end tex -@end iftex -@ifnottex -@samp{true} -@end ifnottex -are LTL formulas. - -@item -If -@iftex -@tex -$\varphi$ and $\psi$ -@end tex -@end iftex -@ifnottex -@samp{f1} and @samp{f2} -@end ifnottex -are LTL formulas, then -@iftex -@tex -$\neg\varphi, {\bf X}\varphi, (\varphi\vee\psi)$ and $(\varphi\;{\bf U}\;\psi)$ -@end tex -@end iftex -@ifnottex -@samp{! f1}, @samp{X f1}, @samp{(f1 \/ f2)} and @samp{(f1 U f2)} -@end ifnottex -are LTL formulas. - -@end itemize - -The semantics of linear temporal logic -(i.e., a satisfiability -@iftex -relation, denoted by -@tex -$\models$) -@end tex -@end iftex -@ifnottex -relation) -@end ifnottex -is defined over infinite sequences -@iftex -@tex -$\xi = \langle y_0, y_1, y_2, \ldots \rangle \in (2^{AP})^\omega$ -@end tex -@end iftex -@ifnottex -@math{x = } -@end ifnottex -over subsets of @math{AP} as follows: - -@itemize @bullet -@item -@iftex -@tex -$\xi \models$ \sc{True} for all sequences $\xi$. -@end tex -@end iftex -@ifnottex -@math{x} satisfies @samp{true} for all sequences @math{x}. -@end ifnottex - -@item -@iftex -@tex -$\xi \models p \in {\it AP}$ -@end tex -@end iftex -@ifnottex -@math{x} satisfies an atomic proposition @samp{p} -@end ifnottex -if and only if -@iftex -@tex -$p \in y_0$, -@end tex -@end iftex -@ifnottex -@samp{p} belongs to @math{y(0)}, -@end ifnottex -the first element of the sequence -@iftex -@tex -$\xi$. -@end tex -@end iftex -@ifnottex -@math{x}. -@end ifnottex - -@item -@cindex @samp{!} (operator semantics in LTL) -@cindex negation (operator semantics in LTL) -@iftex -@tex -$\xi \models \neg\varphi$ -@end tex -@end iftex -@ifnottex -@math{x} satisfies @samp{! f} -@end ifnottex -if and only if it is not the case that -@iftex -@tex -$\xi \models \varphi$. -@end tex -@end iftex -@ifnottex -@math{x} satisfies @samp{f}. -@end ifnottex - -@item -@cindex @samp{\/} (operator semantics in LTL) -@cindex @emph{or} (operator semantics in LTL) -@cindex disjunction (operator semantics in LTL) -@iftex -@tex -$\xi \models \varphi\vee\psi$ -@end tex -@end iftex -@ifnottex -@math{x} satisfies @samp{f1 \/ f2} -@end ifnottex -if and only if -@iftex -@tex -$\xi \models \varphi$ -@end tex -@end iftex -@ifnottex -@math{x} satisfies @samp{f1} -@end ifnottex -or -@iftex -@tex -$\xi \models \psi$. -@end tex -@end iftex -@ifnottex -@math{x} satisfies @samp{f2}. -@end ifnottex - -@item -@cindex @samp{X} (operator semantics in LTL) -@cindex next time (operator semantics in LTL) -@iftex -@tex -$\xi \models {\bf X}\varphi$ -@end tex -@end iftex -@ifnottex -@math{x} satisfies @samp{X f} -@end ifnottex -if and only if -@iftex -@tex -$\langle y_1, y_2, y_3, \ldots\rangle \models \varphi$. -@end tex -@end iftex -@ifnottex -@math{} satisfies @samp{f}. -@end ifnottex - -@item -@cindex @samp{U} (operator semantics in LTL) -@cindex strong until (operator semantics in LTL) -@cindex until (operator semantics in LTL) -@iftex -@tex -$\xi \models \varphi\;{\bf U}\;\psi$ -@end tex -@end iftex -@ifnottex -@math{x} satisfies @samp{f1 U f2} -@end ifnottex -if and only if there exists an -@iftex -@tex -$i \geq 0$ -@end tex -@end iftex -@ifnottex -@math{i >= 0} -@end ifnottex -such that -@iftex -@tex -$\langle y_i, y_{i+1},$ $y_{i+2}, \ldots\rangle \models \psi$ -@end tex -@end iftex -@ifnottex -@math{} satisfies @samp{f2} -@end ifnottex -and for all -@iftex -@tex -$0 \leq j < i, \langle y_j, y_{j+1}, y_{j+2}, \ldots \rangle \models \varphi$. -@end tex -@end iftex -@ifnottex -@math{0 <= j < i}, @math{} satisfies @samp{f1}. -@end ifnottex - -@end itemize - -@command{lbtt} also supports the following operators and Boolean constants, -the definitions of which can be given in terms of the previously defined -operators: - -@itemize @bullet -@item -@cindex @samp{f} (Boolean constant semantics in LTL) -@cindex false (Boolean constant semantics in LTL) -``false'': -@iftex -@tex -\sc{False} $\equiv_{\rm def} \neg\!$ \sc{True} -@end tex -@end iftex -@ifnottex -@samp{false} := @samp{! true} -@end ifnottex - -@item -@cindex @samp{/\} (operator semantics in LTL) -@cindex @emph{and} (operator semantics in LTL) -@cindex conjunction (operator semantics in LTL) -logical conjunction: -@iftex -@tex -$(\varphi \wedge \psi) \equiv_{\rm def} \neg(\neg\varphi \vee \neg\psi)$ -@end tex -@end iftex -@ifnottex -@samp{(f1 /\ f2)} := @samp{! (! f1 \/ ! f2)} -@end ifnottex - -@item -@cindex @samp{->} (operator semantics in LTL) -@cindex implication (operator semantics in LTL) -logical implication: -@iftex -@tex -$(\varphi \rightarrow \psi) \equiv_{\rm def} (\neg\varphi \vee \psi)$ -@end tex -@end iftex -@ifnottex -@samp{(f1 -> f2)} := @samp{(! f1 \/ f2)} -@end ifnottex - -@item -@cindex @samp{<->} (operator semantics in LTL) -@cindex equivalence (operator semantics in LTL) -logical equivalence: -@iftex -@tex -$(\varphi \leftrightarrow \psi) \equiv_{\rm def} ((\varphi \rightarrow \psi) \wedge (\psi \rightarrow \varphi))$ -@end tex -@end iftex -@ifnottex -@samp{(f1 <-> f2)} := @samp{((f1 -> f2) /\ (f2 -> f1))} -@end ifnottex - -@item -@cindex @samp{xor} (operator semantics in LTL) -@cindex exclusive or (operator semantics in LTL) -logical ``exclusive or'': -@iftex -@tex -$(\varphi \oplus \psi) \equiv_{\rm def} \neg(\varphi \leftrightarrow \psi)$ -@end tex -@end iftex -@ifnottex -@samp{(f1 xor f2)} := @samp{! (f1 <-> f2)} -@end ifnottex - -@item -@cindex @samp{F} (operator semantics in LTL) -@cindex finally (operator semantics in LTL) -@cindex eventually (operator semantics in LTL) -temporal ``finally'': -@iftex -@tex -${\bf F} \varphi \equiv_{\rm def} ($\sc{True}$\;{\bf U}\;\varphi)$ -@end tex -@end iftex -@ifnottex -@samp{<> f} := @samp{(true U f)} -@end ifnottex - -@item -@cindex @samp{G} (operator semantics in LTL) -@cindex globally (operator semantics in LTL) -@cindex always (operator semantics in LTL) -@cindex henceforth (operator semantics in LTL) -temporal ``globally'': -@iftex -@tex -${\bf G} \varphi \equiv_{\rm def} \neg{\bf F}\neg\varphi$ -@end tex -@end iftex -@ifnottex -@samp{[] f} := @samp{! <> ! f} -@end ifnottex - -@item -@cindex @samp{V} (operator semantics in LTL) -@cindex weak release (operator semantics in LTL) -@cindex release (operator semantics in LTL) -temporal ``(weak) release'': -@iftex -@tex -$(\varphi\;{\bf V}\;\psi) \equiv_{\rm def} \neg(\neg\varphi\;{\bf U}\;\neg\psi)$ -@end tex -@end iftex -@ifnottex -@samp{(f1 V f2)} := @samp{! (! f1 U ! f2)} -@end ifnottex - -@item -@cindex @samp{W} (operator semantics in LTL) -@cindex weak until (operator semantics in LTL) -@cindex unless (operator semantics in LTL) -temporal ``weak until'': -@iftex -@tex -$(\varphi\;{\bf W}\;\psi) \equiv_{\rm def} \big((\varphi\;{\bf U}\;\psi) \vee {\bf G}\varphi\big)$ -@end tex -@end iftex -@ifnottex -@samp{(f1 W f2)} := @samp{((f1 U f2) \/ [] f1)} -@end ifnottex - -@item -@cindex @samp{M} (operator semantics in LTL) -@cindex strong release (operator semantics in LTL) -temporal ``strong release'': -@iftex -@tex -$(\varphi\;{\bf M}\;\psi) \equiv_{\rm def} \big((\varphi\;{\bf V}\;\psi) \wedge {\bf F}\varphi\big)$ -@end tex -@end iftex -@ifnottex -@samp{(f1 M f2)} := @samp{((f1 V f2) /\ <> f1)} -@end ifnottex - -@item -@cindex @samp{B} (operator semantics in LTL) -@cindex before (operator semantics in LTL) -temporal ``before'': -@iftex -@tex -$(\varphi\;{\bf B}\;\psi) \equiv_{\rm def} \neg(\neg\varphi\;\bf{U}\;\psi)$ -@end tex -@end iftex -@ifnottex -@samp{(f1 B f2)} := @samp{! (! f1 U f2)} -@end ifnottex - -@end itemize - - - -@node Generalized automata, State spaces, LTL formulas, Definitions -@appendixsec Generalized automata - -@cindex B@"uchi automata, formal definition -@cindex generalized B@"uchi automata, formal definition - -@command{lbtt} uses internally finite-state automata on infinite words -(B@"uchi automata) over the alphabet -@iftex -@tex -$2^{AP}$ -@end tex -@end iftex -@ifnottex -@math{2^AP} -@end ifnottex -(where @math{AP} is a finite set of atomic propositions) -with one initial state, labels on transitions and zero or more acceptance -conditions. - -@appendixsubsec Formal definition of generalized automata - -Formally, a generalized B@"uchi automaton can be represented as a -tuple@footnote{This definition differs from those commonly found in -the literature by specifying the acceptance conditions in terms of a separate -set that is independent of the other components of the automaton, together with -an -explicit labeling function for the states. This is to allow the definition to -correspond more accurately to the automata that can be described in -input files.} -@iftex -@tex -$\langle \Sigma, Q, \Delta, q_I, \cal{F}, \lambda\rangle$, -@end tex -@end iftex -@ifnottex -@math{}, -@end ifnottex -where - -@itemize @bullet -@item -@iftex -@tex -$\Sigma$ -@end tex -@end iftex -@ifnottex -@math{S} -@end ifnottex -is the finite @emph{alphabet} -@iftex -@tex -($\Sigma = 2^{AP}$ in this case), -@end tex -@end iftex -@ifnottex -(@math{S = 2^AP} in this case), -@end ifnottex - -@item -@math{Q} is the finite set of @emph{states}, - -@item -@iftex -@tex -$\Delta \subseteq Q \times 2^\Sigma \times 2^{\cal{F}} \times Q$ -@end tex -@end iftex -@ifnottex -@math{R} (a subset of @math{Q x 2^S x 2^F x Q}) -@end ifnottex -is the set of @emph{transitions} (each of which consists of four components -called the @emph{start state}, the @emph{guard}, the -@emph{acceptance component}, and the @emph{target state}, respectively), - -@item -@iftex -@tex -$q_I$ -@end tex -@end iftex -@ifnottex -@math{q} -@end ifnottex -is the @emph{initial state}, - -@item -@iftex -@tex -${\cal F} = \{f_1,f_2,\ldots,f_n\}$ (for some finite $n$) -@end tex -@end iftex -@ifnottex -@math{F = @{f1, f2, ..., fn@} (for some finite @math{n})} -@end ifnottex -is the set of @emph{acceptance conditions} (a ``nongeneralized'' -B@"uchi automaton has exactly one acceptance condition), and - -@item -@iftex -@tex -$\lambda: Q \rightarrow 2^{\cal F}$ -@end tex -@end iftex -@ifnottex -@math{L: Q -> 2^F} -@end ifnottex -is a @emph{labeling function} that associates each state of the automaton -with a set of acceptance conditions. - -@end itemize - -A @emph{run} of a B@"uchi automaton on an infinite sequence -@iftex -@tex -$\langle x_0, x_1, x_2, \ldots \rangle \in (2^{AP})^\omega$ -@end tex -@end iftex -@ifnottex -@math{} -@end ifnottex -over the alphabet -@iftex -@tex -$2^{AP}$ -@end tex -@end iftex -@ifnottex -@math{2^AP} -@end ifnottex -is an infinite sequence of pairs of states and transitions -@iftex -@tex -$\langle (q_0, t_0), (q_1, t_1), (q_2, t_2), \ldots \rangle \in -(Q\times\Delta)^\omega$ -@end tex -@end iftex -@ifnottex -@math{<(q(0),t(0)), (q(1),t(1)), (q(2),t(2)) ...>} -(where each @math{q(i)} is a state in @math{Q} and each @math{t(i)} is a -transition in @math{R}) -@end ifnottex -such that -@iftex -@tex -$q_0 = q_I$ -@end tex -@end iftex -@ifnottex -@math{q(0) = q} -@end ifnottex -and for all -@iftex -@tex -$i \geq 0$, -@end tex -@end iftex -@ifnottex -@math{i >= 0}, -@end ifnottex -@iftex -@tex -$t_i = \langle q_i, X_i, Y_i, q_{i+1}\rangle \in \Delta$ -@end tex -@end iftex -@ifnottex -@math{t(i) = } in @math{R} -@end ifnottex -such that -@iftex -@tex -$x_i \in X_i$. -@end tex -@end iftex -@ifnottex -@math{x(i)} belongs to @math{X(i)}. -@end ifnottex -(Because the relation -@iftex -@tex -$\Delta$ -@end tex -@end iftex -@ifnottex -@math{R} -@end ifnottex -is not necessarily a function from -@iftex -@tex -$Q \times 2^\Sigma \times 2^{\cal{F}}$ -@end tex -@end iftex -@ifnottex -@math{Q x 2^S x 2^F} -@end ifnottex -to -@iftex -@tex -$Q$, -@end tex -@end iftex -@ifnottex -@math{Q}, -@end ifnottex -the automaton may have many runs on the same input.) - -A run -@iftex -@tex -$\langle (q_0,t_0), (q_1,t_1), (q_2,t_2), \ldots\rangle$ -@end tex -@end iftex -@ifnottex -@math{<(q(0),t(0)), (q(1),t(1)), (q(2),t(2)), ...>} -@end ifnottex -(where -@iftex -@tex -$t_i = \langle q_i,X_i,Y_i,q_{i+1}\rangle\in\Delta$ for all $i$) -@end tex -@end iftex -@ifnottex -@math{t(i) = < q(i), X(i), Y(i), q(i+1) >} for all @math{i}) -@end ifnottex -is @emph{accepting} if and only if additionally, for each acceptance condition -@iftex -@tex -$f \in {@cal F}$, -@end tex -@end iftex -@ifnottex -@math{f} in @math{F}, -@end ifnottex -@iftex -@tex -$f \in \lambda(q_i)$ -@end tex -@end iftex -@ifnottex -@math{f} is in @math{L(q(i))} -@end ifnottex -or -@iftex -@tex -$f \in Y_i$ -@end tex -@end iftex -@ifnottex -@math{f} is in @math{Y(i)} -@end ifnottex -for infinitely many -@iftex -@tex -$i$. -@end tex -@end iftex -@ifnottex -@math{i}. -@end ifnottex - -The automaton @emph{accepts} an infinite sequence -@iftex -@tex -$\langle x_0, x_1, x_2, \ldots\rangle \in 2^{AP}$ -@end tex -@end iftex -@ifnottex -@math{} over the alphabet @math{2^AP} -@end ifnottex -if and only if the automaton has at least one accepting run on this sequence. - -@appendixsubsec Transition label encoding - -When working with automata on words over the alphabet -@iftex -@tex -$2^{AP}$, -@end tex -@end iftex -@ifnottex -@math{2^AP}, -@end ifnottex -the guards of transitions can be expressed as propositional formulas by -identifying a set of symbols from this alphabet with the set of models of a -propositional formula. A transition can then be seen as a rule ``if in state -@iftex -@tex -$q_i$ -@end tex -@end iftex -@ifnottex -@math{q(i)} -@end ifnottex -and the next input symbol -@iftex -@tex -$x_i$ -@end tex -@end iftex -@ifnottex -@math{x(i)} -@end ifnottex -is a model of the propositional formula guarding the transition, the automaton -can move to state -@iftex -@tex -$q_{i+1}$''. -@end tex -@end iftex -@ifnottex -@math{q(i+1)}''. -@end ifnottex -In the context of B@"uchi automata constructed from LTL formulas, this -often allows for a compact representation for the transitions. - -@appendixsubsec Converting between equivalent definitions - -Many LTL-to-B@"uchi translation algorithms presented in the literature -(for example, -@ifnottex -@ref{[GPVW95]}) -@end ifnottex -@iftex -[GPVW95]) -@end iftex -are based on a slightly different definition for generalized B@"uchi automata, -where the automata can have several initial states, acceptance is determined -using a family of sets of states, and the guards of transitions are replaced -with an additional state labeling that associates a set of LTL -formulas with each state. These automata can easily be described using the -above definition through the following steps: - -@enumerate -@item -Add a new state (associated with an empty set of LTL formulas) into the -automaton and add transitions from it to each initial state of the original -automaton. Make the new state the (only) initial state of the automaton. - -@item -For each state of the (modified) automaton, construct a conjunction of all -propositional constraints (all formulas with no temporal operators) -associated with the state and make the conjunction the guard of each transition -coming into the state (the acceptance component of each transition remains -empty). Then remove the association between states and sets of formulas. - -@item -If -@iftex -@tex -$Q_1,Q_2,\ldots,Q_k \in 2^Q$ -@end tex -@end iftex -@ifnottex -@math{Q1, Q2, ..., Qk} (subsets of @math{Q}) -@end ifnottex -are the sets of states determining acceptance in the original automaton, -let -@iftex -@tex -$f_i = Q_i$ -@end tex -@end iftex -@ifnottex -@math{fi = Qi} -@end ifnottex -for all -@iftex -@tex -$1 \leq i \leq k$, -@end tex -@end iftex -@ifnottex -@math{1 <= 1 <= k}, -@end ifnottex -and let -@iftex -@tex -$\lambda(q) = \{f_i\mid q \in f_i\}$ -@end tex -@end iftex -@ifnottex -@math{L(q) = @{fi | q is a member of fi@}} -@end ifnottex -for all states -@iftex -@tex -$q$. -@end tex -@end iftex -@ifnottex -@math{q}. -@end ifnottex -@end enumerate - - - -@node State spaces, , Generalized automata, Definitions -@appendixsec State spaces - -@cindex state space, formal definition -@command{lbtt} uses randomly generated state spaces in the -model checking result cross-comparison test -(@pxref{Model checking result cross-comparison test}) and -the model checking result consistency check -(@pxref{Model checking result consistency check}). Formally, -the state spaces are (finite) Kripke structures with a total transition -relation, i.e., directed graphs with a set of atomic propositions -attached to each state, with each state having at least one -immediate successor (which may be the state itself). The precise -definition is as follows (as before, let @math{AP} be a -finite set of atomic propositions). - -A state space can be represented as a tuple -@iftex -@tex -$\langle S, \rho, {\cal L}\rangle$, -@end tex -@end iftex -@ifnottex -@math{}, -@end ifnottex -where - -@itemize @bullet - -@item -@math{S} is the finite set of @emph{states}, - -@item -@iftex -@tex -$\rho \subseteq S \times S$ -@end tex -@end iftex -@ifnottex -@math{R} (a subset of @math{S x S}) -@end ifnottex -is the @emph{transition relation}, and - -@item -@iftex -@tex -${\cal L}: S \rightarrow 2^{AP}$ -@end tex -@end iftex -@ifnottex -@math{L: S -> 2^AP} -@end ifnottex -is the @emph{labeling function} which maps each state to a set of atomic -propositions that hold in the state. - -@end itemize - - - -@node Configuration file option index, Command line option index, Definitions, Top -@unnumbered Configuration file option index - -@printindex fn - - - -@node Command line option index, User command index, Configuration file option index, Top -@unnumbered Command line option index - -@printindex vr - - - -@node User command index, Concept index, Command line option index, Top -@unnumbered User command index - -@printindex ky - - -@node Concept index, , User command index, Top -@unnumbered Concept index - -@printindex cp - -@bye diff --git a/lbtt/doc/testprocedure.eps b/lbtt/doc/testprocedure.eps deleted file mode 100644 index 0d86fb4fc..000000000 --- a/lbtt/doc/testprocedure.eps +++ /dev/null @@ -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 diff --git a/lbtt/doc/testprocedure.png b/lbtt/doc/testprocedure.png deleted file mode 100644 index b141929d167625519bdee8fbb159341b07d287fd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14430 zcmeAS@N?(olHy`uVBq!ia0y~yVDe#LV7kM>#K6EXE1}{#0|NtRfk$L90|SpQ2s2(f zx7Lq=fkC#!HKHUqKdq!Zu_%?n-7i$ZJtM!kq&T@Kv!F!5RL{_$ak}3G1_lKNPZ!6K ziaBrZ-oExoLC7I-&eiw-Pn~PMEIEroQRelA{j2lpdzSEbVaC^YvtqtQcW(CIF|WA($y;Oj`$~WQracMz ztQGyPf|J3a`?~qOEAIbOY>ofrKlT5bK5bk5Uu(^f^|wBJQ|+I)P>HEQX8m++@68(v zr|!JcHT}4K_h*Z#Pd+I!WPDlv*tF1d#s8+L$6KD=3UN2y)Nik6cJIFS%wwe?rq2o( z6wc1Su=`xu)k#%zv+q|tE?&oPv&DQzGW*I1hJ*tb?oREWns79A)%N-49|uV??D#rA z;Kz>WYm2;tzk4Tr{k}`e=El4?*86gK7#!AIH{MyXV?F<0+17_uo|&9mQfE(%D&6VN z{{H=s8#8|Y4&r8Xm~!s?$)j5HZM^dsPTpH7FO`?4W4a*Zq?Y^%?WqSooMVIe<5!j#tRBBz2(0fr@skU+O&Xo$Q6QqcX> zi=iP>C!C4lOp=;8@9KRF3TN%@XI1Uz-1l_iJ8`x9v6V}Bi>3J)1fCxC>C5C|aF{NB z{fSh4AsYjO;tn--27_);E%jf7aOL%isL(#F;ze-j9Ss&)5HMhVmDD{K`Ie z!HI(++ifK?p09dVyYGJf>tK8Rc|0;7U++@U3V66`_8-f;3<+xLf5jvouA03e#&YKB zQU)C-F~-dSPZ$`|HX;caOm5cH`NG&AQ!3mg!*D=nn)dYF^9}EcFSa_jN-BKIBVG9z zmff=qSMx6Ajf#D-TE<!g><%G4c=&Z%j#%vP*)>UDe@&h?akb%0 z?Yj$Wl{pn{ll;HUdau?Sv2Mzudx6J|Lr-)3(6F;K-5jhN_3EI~Z}wAH?>_vfyQTQH z@4Fc%eYYvipY#01+@B3L?-o2?FJH9#alYUR`K~z}moFRIT|K+*TgrW_xceSr-jk31 z4gX)8^YF;s>st%1KeQ5?Y8Bp}`|`zJA2<&z~&Pc=K5E%I^y`X~G3de(nwiJsqo{POFcC+iRYK7Fgu_+5Tf<<+Zl z=fkDEo@;+>zIo$bf2_=WFbNY=IU)uNG)3>dEB(SBVeZp%& zp7wTN(((Nm{-)-P?%`>{R#WjBVH)DY>uFFz4pA6B7 z{Psm4x{7FEoC`&seDp^JMS z&ysQJ)>kNeW$>=fv~Pu!gZavYokEK)ma4Ccf7BFLGMTGO#wT&7M8y+OM&e{J=$7_R z=$bq^IH6^A-XWhnqwsju2G%8y3 zi{s|jOa6;xmv7v|y4#bxTB9h!BV_LHiNSBDOf$C;n(=L3;1fRM`;te>e!Mwvo}cmj z<0C7-XN;_yG>Rhpa_0W7-1D(kOgh;7WP1?bL(BJEuJ2Ur?>czTkKZyQbMYQle@Sj* zjiTcf()wGj?3^EY^_)-T;pkmL_YAsZzFoZWcK7PJdp|9EcSCl$;lsBJPt1L2_VsJo z?{CtfZ>Da4V3E8~R-Vni!DCjZgVA2&$a_r-AD6ORwCd{q+r@5tLsH? zb8n}gxqh)CBPD3obF+fSC+%1^xCExKNqWLP1j{S*FMt4NJ?i4-wqMh!}s2Cqvlw~+Mrqxzt=T-?*E18wWPN$-qyvx5C z%)H&B#NJuP$6|CkI>~u!@{_x5R@;SL^AtZ-9BFHGaIN&#*%jCt(;8YMQ6qZD^yngk zES-GO$NS%8sflz6e6yW#(s9en&z8wg-=?P+PF^UsE%3>-gaRfLRcpTC@g~pDO_Qx7U0*Q~zivpk5 zxv(~#pRwPG&;LlTx-G|1m+pN9mwp-sZTuaw+e(x@&@QcL{lv=6I)Cj_&p$sDRW`@F z{6>RPJM*_cF%8eHmUCa#>t>nPr1YK7(md(Ez_WrG0ekn~S<&=Tqv*!N2l{(=t}0IZ zHbpwLE++N8lE_Z+6WjQN>P}oa>5*6}A9>~oM^}vYYULAFLZ@yY^_;u;Z2DH^Que?n z2J=^ZD%)rqA#rc3b^g_JWv|w`P1Npk&oWvw@yw^PjaCse?yMBMmlskPbmjS?6Se|& zS*I7O2AI8yvAH36V{V~bUPvdm<*mRcvkdw|GBoq2uQrg7;5~W9y1IMjloFKVj$-00 z;VGxWjNU%g74hqpG_?t+dg=G|(BVRnojuidC*QMOj&LsOVH#*J?cx{lot>qSjrwcH;FmUS zzpsA(9a^~K@nwBcUb6*4ud3=JyB7cFa@9MW$QQcn_4oC2-`;%x@kuPlXLhIQ!Asxm z<7gD>x??Z0Hq3X*-o*2sx!tk9wF}-nxE6Mj@0z8}t=jUX2Ocsz##$B-RqzRR3IwBxoh{P zr?0PCuWRi7<#hGNn)Asa`z9uy+U?;y?@R8T=y@KWXKe5Hoc*`s&_U+yCYjEr#__6a z7bso-SFLw)dhn6|Q@<@XxcTkRzu7hK4F0V@e}0L1(LD9Wkc%q~pK5vD-Z#;9i^|%4 zPft~qq}_eD=gYR2zs<8_W*UB6ySFypGs%D6nY$rMzj<{o2Oq7R*Wq+&U+r|UrnI8R zU%p-4@wDo@6Zcg?wa}WN+BN6Z)^1YTuI}(r(*0$1wfZ)dpM~=;<^L`DvuN>z)ZV|_ z-hQ$To%ZiZwD+nB>Ry$8w@y7?YQI$-WOME#$&aEJ-lXhtu4$R{IAqs_sH)eO=KomK zl{@K&{;A0qCTKn3lsf5o>w{f>{MHFd-`A9!`d}t%H}MUdw!V*%THWhQWfq3_du$r5 zj!!l#dHQzsTkYs|B9Cr=Eq#14X7@+2#lNKuwK5&&In15wDZTB<+T%*$_AUA69e$;I{0FXtZgxDmFgrc5l^AHS?#Rew=VS7dL-@ ze2?u_p@%0XpQ=~9c5{#IJazBSVeS*HXEQEcy-9hwuf4)Go8EIhV#GK zRGW*h6YkCPy|qC#KRze#RQ3K_|6Pi5H-EXVx%$#|H?P^XqT8oUOPN2d_WSSVle(Ta z|4)-rE0(!3NqwQrw|8%Cwk?^Yb?=kQEX~U3{o=_-f0UVJ9{#+Isgrhx(3>EC(cipB61WrkM%vP8S4AX&(}TG3rO0!Ew)75 za-(f!(&2T9+;?rBcy_pHznW8K)Iax3nC+$5Ck!mpHZ>X@z5b+bx#-9I=s&xvK4pt9 zLxX(|{ znVlG&nzC9YR5e+8{jF>Bw<*OwzReeQr)fcj+VrolrX(Kz>H5+|EiV3%$)ApI8@NwS z{x;3SqV`zKBDZZjUsn14Sa&w)Nt}fJjitIJ`IWyEk62V!I<*?-#O^A~uQ|0LY<^N% z@cx*eE0RA|AKmru(96qNGAU~Qc6VAH9oSX!_V$mCtM60yoG4v?TjhGbTAn1+%#*_B zcG*NsU#BcBzvZ25ulP>E{_u?3hF>Jq)cq|!9#Xb^8D(hRt}DLtUGfE^x%qcOzTL|C zRyZd~(|^+Q;M+B9_)G ziW~GocJOKxEem+gpu3`=I^YRIg1OcmGZD+|8D}irnNGO3-tJUN7dR}#@F(C&&Z2XS zMuxq&dz8|}O8F+Vac!4(J!kYvMuA=Q9Y@!k!Yh^zOj>s|MJx|Uoy%FW@Q|#_#LfMR z{1zQtLsJ?AdvyV1<0&f*qbI7F^>mS$OEA`^3Zl1D-S7 zaGrShf8g_mGM~pG3r;+gzhb$7Rn(8WOD5=wrLo17?tq6P3r{FE9~9JBc<80mMCOLD z5Q|ccq7%tR>?$h?qynD=xXfignBoj|DJs^m^QN{MeyYVDZ&r z@?_y!?-|+-%35n<6^q!M`0}&nkad|LR1~iZN=J9eT-z0N|L2FUV3xYsixQcd-|RZU zX(Oj5m_Fy|qNeopy4DBfd7{f>zvZm{vgMcZ?|6&tyxKW8{{FgL$DMjoT+`E{EFv-N zmWf?ZeblCD8+4z0zu$3aqTu>359XO|vCl1^n0z+Nn5l2>iS2VOGP6HE()L-J0Kh$JuXIZF%2+{_fvP%R*RcoZ};2dHfE29(}rA zd#!C!(gEwT{i(s#OnN0djiOK9zRI8VM{Mc;yb57WV?C=j-O1{}A)emGFD- zKS8*_QC?BP^OyTw!T)vpYuAfT`na?~zqhPFrr`OUC$lG{1e?!k6J``I_tmpB6S~&= zO~+0q@{xeV+XSlz=O*TteAr<7VAH+@mOo#=+Pq)vR{J5Z)2wdRFZg$G-A|3b?6dFf zk~|Aubtb*1vtpK>=G9YuZ}O?{?&%WQFqi5NTYuj#Og}Jp^Thn-{N;O_U%$Gm$hBjN z()Y01|MKsZXMNJsz89#&)Hm1V>FoBD)h$Vn-pOGDERo-6QXD|1EYx4KzsSVsaw;3kg)|+v1`>D0Ha#j_m z-?2|*d_MhPukr)!fG1kBd7s?YbJ^W`?WtF_RylJrD>(U`UDt4W*KVQ9f(0qMyADpO zx!swuUEsT=<@OWT&vIClDcv{Q&2+9vmEnL6c&x(ler%^GSiDT>mhKGDD7eta!~zz( zPn+&uDA$O1$(>f_VrTUuE&RYtkmMs}mY{;J>xoZ(Pv)?Qll-$u@6%fU@*C@)YwH#D zYU`d1U%EEu;=}iAq8F;3uvVV4C;yXc<%hKBcN25mcm15Q;k{nbWA4lA%PfAso!@=p z4O=Z^{{8N`g8TO88k6N5mR0zD z|CeEPO?RL8sp~>dzHzkQi?}QN{zr%MDt(?w8}vVB)&D;A-4(RPvr@fQEHD4O zwD!)$=TE!>z28aw%Dn&P>yz#JTb8RHTBv5&mEOG*IC1yn0)`yr zLlsZWbzV| z_QtFw+>HNcS`v@B+woVsobm*q;!xPQkv`wI>^9LUwUJKOwUEX$%x{!aURIk$eWh+o&R`VWWW zW8GCJV?(E2@2lZ)c*ZDqU1;(*4)eSX8xxN&)?LUeJooP0GZJl>mdVd5Ew zeVSfo%oq2q;oiMCyGU5`727m}hX>45ZVPH3I#-n1FDlx%b>dk!ro8p~H*PCuzIZS@ zmeKq->sjxKD;X9rx%zQ&Jx^niv7VSeJC^bJEYKMByLBdg4aw@Ca@7~zee|Iy^;=TT zX>~F0{*wI#UeeFZ>R4y)zW?{o&fEhfzpHzvU5PzXbH~bT>+TbVYjUzOdCr{Uz>TMavOP37Y9Y#144xK3n75Dj(lhW2aw zbh>2jJv7=K%5%-26J@r+IpXEi9wd==@f}+)nN7Q!!0*cE&=tgP{3Eqsfv3^C{NJTZ zY#;6Y{daccZ|%)>#~3dgPG+8!a$KLy)WHIrGrMFMmMt;pR%#E6DJp19{wwx<*(sNa z%u%Y3_iZ#v$SH4-hbn9MpJ>Ehtx?2az&`yc%c2vE`Z2|_YPJnrB9rOJR4hY%uz(evFs9h=M%6EEWiSm)hjSoBy z%5}-OZM_qB@Wo12_be{G(RkIc1@DlDxpvMV(U zrEP+yZr9$M{PgFBmYFhQRewY(pYH$o_@l$OzuGR&w@qIit@rvTz5Ug`o4-NzTy%(v zlzosgTw8QVTS25BN0&^QgnW!wyxcU~%jf@zhRe$i3G1L+{KC&3&63GFwqMp%(xJ7c{Ovsbsn@<Sdt>X>hM|#!1H22E~_}lv5>)Eg2#@P8X#I zJ~3GJ*(}w*@H6S+-l(Fd)@ae8K3w1F^cmfcgQ-V%FSYN=MojMoTKuG zrRIydoyq-J%|91Zj`d$zGi^#i1J@!Oq)|*G^-#%`C@&W3l>7Jbg--Dx@H z8#r9~I3C^)I{U=Is81wr;fcg4OV`)U|J`ViTpSa)OnznL?5ZPs)n^y_@^KtIKIgzO zyIVK7bDSqKhb3BE10{mfQyCaGYZU#k-?!+3nI0?W!PK2|Bi0>R@oRlYYevpq`ybyX z{?(szyMkeM;1h=BQChzede`T?3jUG$;h>pMrj1VJMw_K2y55YW$h~*#t$9xQ+A`oOh!?vWe z4AwXI?-pWMAW|OA#1N3O|3qPMj55>L4uM|fHp4|58~-Y`i>+~GHt5VQVqjPZnl*M1 zbme16nD$rc_|m&#E-M8ar5wM!>o}POn%3t4*~-ub9$>*w{M%DyCV!5dAwQ&^_e8hS z_3iU({JokQeB3=c59qiUd6z~+tZS*d|9-kDn~$U3&CPpGOf=zSYI^CRrL)xP;Ea>9 z3#^h;l$N+8h$+onYOZ75HRs+72f<4`n(%kukPzhsm{_wXS~2CDW7?v@QBqt+*Rrd;h24BEI>OyEjkR<1aAbC5NWqj8>1d zw>;eYdH9xC$R5*qGKq0__nm)B1m`Vgub%kf#0mxDHlem>k9h;UT<@r;L|CU4J%4#h zLKLb~lk0S&(sB)}3*9D%b*zg!_so5F#wV}%(woY~g6>Aqt|={(We#sXy!6Qlj^(N) zQLi@sed;CJ{*dGI#G98n&$e%D-aF%s%mqAR1&vXWWJjD zQKE`dQ(W89BWgG1U*?Ta<@^3M|GDySTeWpepI*0gms$3$UA=;B`rqtKz1SA&6jxV^MOyJ6ViUV7X6x+HFL{U4wbi&u25Y60JmwNlS zpZT6{8PAa8)5A)Z&Rn#NtGr+3`p)JnEW(D9lO6n1n3aqhMGEB(%=KKlVm;>)ld2?l zT|rm9>Ht-j=TlrG=jDWD#=qL8zA7mpHsX-C;U1 z^Wv^FZQc_i^S;~exc_(Oi-qNvqV!guV69}d>T6gd;9h!a=ahAapZxjsB<6DQ$%gme ztyLx0_4efW#!Tdn+wIl*S+G*@x#NRZ2VCZuq{P0pkN&MHw$ni0>el8bMz7CsY}~0B zTHeso<7l?R`d76FNB0FK@nvrAP79XL*v-`N!CWfO{pZWmUh~$TP-Skk-N#+j9U~wh z+t_ikWR9O^?luP(qwEjejcki|{a&3>GS?{o_q0OMkdlO0Mc&PeU)6jMS6E`$dr`o4 zGBZQMk(v4#&%WronJk+ue`$l!s&nP_tWHvwMR~zh8O~gNuBPRI`o4!-OZ>A=7t7s$ z^s)8&Zkau%Wu+z}tw~DH155Y)))u&wW2~iXDc3vMc;}Dm&vNz;H-3rmdQt7PNKsKl z*s_1s=ezNZ6OM(rIDaWxx~{)_otsHmfn4bG-TRpodp$ea7AQ^UZJ!`K?Qh31u5&PV z&%9_+>HF@}H|tfC)$cb)+`9EZbf4`rx5b+@MK8{H8XEFebq2`TI;qJrypF~@KfLF= zVtwiR`roVV=KFsO-}Fd4Y@7b^1QV@=99)YHPbY`uszcQaOYmyC>h1QP+Bc>4&&Q{4 zpL3`C_Pd>CJL;A^?VG|39|MrP{+g(nNhwX!et(NU#m0Bto%~#uammA#%}$MXG$)~tycp@<$|Cl8A}CC(@yp} zA0wtH1uBw2?w)YW#nm}!BDeq3U2+FceQkc?zo^f}wcNz3K1jAVQY-N5gal9w{mS(5 zGf5HMd39 z>z(HQ&3+mBP;Be#^&d??|BiI{vnt2Z%l1ajfkecFV}0(VpGcyrXIN83V*nmQxa?b*I>>C5o6FS))& zyHxrsKu&VLwZqX8R7-cidA~f#S0UcL!vxd)n{}l ziT}I1`pv(T)m1M;YojMGzV|Qa@mja!uAQ9Ub~t82-1}zvA!jYigJt*EO@1>wqWYGn z$+F^mA+bnl7V5_;uDMvXBMFnR-d=VU3yn<+l}N2SV_`Sx3;w6 z=gdmQ=zGsj=&k6u{n1S>-$9x4?UV~`?q9arb(bwn-hAds!_0m6*RMM&lVBC-dMkNi zvcxN8`@BWF#CQ}I^L&VSvSsn(gKR&S`@T@fZ77O*@*?(w&n*KL;lND?GbeIi*{L_F z`Pc*&8TAd)zjTWZC{6NbT_PyGdUNyE8yhm7>^d>gQ#OUo_rXu)2fb(VUhF!-XyNxD zbMl#kQ5G8=KgT^`DKq%VF)J&HT{(gEy(=FZhs;(>{tMm-RwvahGej(pEtX^96`tr9 z(XO<-=ZUeJgY~a)_J@v(PqZHBOc7Uf6ux(GiDJx$Hl^?OPHi~{)H!7*7&q{JYId9G zY|qI&If8{<`NaH4jiUeVVJnsY>j*_n@Rki>=~Zf1oFkbaR^%xzDykRoM5x4AVp(d) zt^N}dZW9l$2u^4F#IAO3X2R4z_sSQZSSm52A-M00o$F&$tAHmag14nDjT!z3SPP^E zJ~5Km^z`!8vnmQnA3Bw$yU(re?nvx9+v)PQ-aGb)M$rMMD|IExmCF{K5S^HqpW8iS zSFz^_7p1*R4Uim6PY4)D*e8Om)O!)=#}b( zUsHKJWlo}Z=C+-O45cUU5(tzMBlZ0o@)%gzFV`% zwP=%;;PV?}s7fV#O?zEoYYS`ln2E*cJ4mUFo~S zA;+l~*uFfx;kh_fN`1pbrrB4Tl)n31StxpSMwjUFhf!_nGdX1AJb$gf_h;b=(~H#& zg?A1akN2DWT!Zf%=@!5&Uh}c%AdRZ!ph|3zqI{?M0S?fx!)~bZ|(Hn@`r2n z@2$oYoMzADoPO~Ax;x*p^`-B*9-1BZYf{{saI@c*O~3D#ynARj+ezqL#@c0P=Ov%= z;cF-~^549n{ou?y{Fb&CA6VXfF!RSH!7iJb-iP+2vwlihH@EVT4_`xx^7i=#y~TY> z?Xq+3E3-ck*?fAc__1q($Nd|(&uyEmuH5(B^W>L5ivDggCxz3BZnT_~ahqWOBDr4e zyYe@mV4eBQT$P{1Dx1XEKex=3`BqtNbWWF9!ttL%z!QdygI%gt0Z%rFJ{I|wAk{A4 zCDW2Lfyv<9>0Wi!rIAOw9$vj9UfnP7J9k>??Vwhhl^H&AjrU7WPAKYntyI4B@l@3{ zOBB099JxQaDC|Ey^}1(3jog+mb2KW~b6K^mSb6VRh@wB+Trate&Rw5v3ZtHAxyPQn zku_t{ZGR8Z%oH{LN~LM9pPrgzp*i`E?>~|6+f}AM7FWv_zqz#M$-y5pZ!WhrQ@A7M z|L*q6Jz~0EtAoC$XvnUdW^>YRt*!qnUXGn67iMcMy2hZ_{Yk}yNAtVQ%KWo&^DO3` z{JSM)A7A}-mPyVPOV9oFKgoS~e`Q#`-<@qgK5pkd@$coW`%mQEFKsNc(<_*>YWwm@ z>IB+zQ7fm@gfn}at?6T)4Z>xvL{jgY~ zadxu&H0}5mK6bCxzpC?ld1c?be}8^`^Z)tkkIuoxrIkTdw_e%2ykQ~t_Wa}vQ?+h= zZc*BPM8DSidEVReJLg&M&Fwa`JC|}(JM&EAx8-Xy?(KSeKGmZ5*|U?6 zl>b+5EIGA$-B~Z|=RzwCL&KhX{>|+Er1HXZ>SNuIiRy_8p1XcFR9~3uu`_|ubAfhRWD`OZnMJ@-dB6h zKiRV~rqJfK_NO$<^GB9>^=z^9tD9#qx!9%7%85gFrBkc5w=0-mq~x```G92~Q`CwR z!f8beAzpcZm^Wz@S-k&ulAU2jlM=gw`MKTz$BE54JP{cOpGKQ3I`PoJO`G9$z!L?& z$(C2{`uCiWoD%RPY-fGz+&OC<`987eE|ZV6U+FaQu;#fQ{PQJ6*^O> zy|Soqwt;Nrr5`eHBi3D6vTp<5pBtxz=a*(PSFbE`pE&zLUEz*TPcD6Za%}BQk5l2v z(`ITHum7ZCv$U(-=3{31yeV;coUVB%OoP(j%dFhJ|H;*BJnBnrl`D(tr*5~YwC=rJ z9aduC-_#j$a?y$2F5{Q;oNr!Uamw3j+q1@diLWn}r+BYd@?UdnrutOgs6)N#!YTfJ zlh|MXuia|;R$To~T>Q%ulP|4~+Loq#f^T!G^E{UBl|hGm_^c#moJo}4#46q;!>~}s z@3DcbD_?XkPxPF5%oW{A><)_#X38vg`LXbXqp+JE!}@?H8~CS3T<8cns3T&jaX5vq z*F%)We*R?T>ld4BK&7ByTG5S^M@%B=FSczA>+F1U{>cm7499shO#V(UKOtN?{eobV6dz(qFt%I z^&3yzoF&W}3r{dwWZpLEo2)orqi93JM{Wl(SH9H+3t9U;gx0uCY!>u+_Mtj&=V9vIGf#f_@XNlE`iwZI}$h-1=p1b#&(Eie* zbLS51l5gcr4}6jkX|&4d!8=8pbHR0PqEP`)9(ZIvR9W~D)5Ox@9ob?v8!i&istZfnaG?rDe}XUEiNKqI<^Z=Fs`1XTOnem z5b(r+JN-zhG}pY7w-Xy2MJyAxce3`syrmGPb9V6wM)lGfqsBvQTNa;4WIETn+=DCb z<#t<6(+hp^Z0stFCgmQ^Z@sOSrzV~*ecEW!-#)(SCeN}?R{lDw6z(-Yk0a>jt_u}Q zRQUYAZ`Nw;W%>T;tWnSwjf%$-1y4@t!OA2~(S=wl!Vv*zGqZ>wHS5tDdLzuBBWu%j6qZX8&_ZkME$?Jbh1U@l1b)ezKk3jp|sR>IS ze2nyb^F`}si`dT98JCMUTrr)M-k!NVd_$b*p8LXE$|KZ@!#H(|E;zkk5GHjo$N#$3 z9^HznX1BSUhSK!DuZ_gSBKM(Zgb7ZeJ*x==S|F~TEeeqgfK86NCaL2KI{mG59T0|p+C-?8` z7kyVdev&kD zE`C35`R4bjt~*noUUz(yXLW%2m))<7sC9eJIX=295WZYxbI!kqTMi!V*vRwcZ=}q( zT2t3`|DvZ`M>8d;|FUz_h+e1DS^W3&&zSv_=KY;}e@XI@`m^g=_Pp}=?mBfE+Y$TM z^S11Kdh)B;eP*FN@6Y{?6;~%c$vk;GG^zUk<-boId@Am*-=0`{pa1EMA1{Arr4`xt z@0L2QTKD94_|x?d#jfSpuiXFpZ>TP>N8F6NelJf>l|9L}w|-zylUSdH~sjE*psvNKKS|SQSrC^T5WHB|MSZ)Gn@B)>%Z-Z?YXOd z|6AQVCu#Tl)tW^M_Y_5Rp4eNxMaQM2<;T8*Ki)0&Vs?v}Ep?`IS~pj5xX>hxsk0dW zWW4#UoBP7;e*MS3*~@R=w5h(@b}CTw?*HJO`WnBNzx&;>sax(XuSd|g=zk1nYlEl0 z4Vf2n|NgWz_2?7FR(&ed4P2FP^E*zNv(2^U+uvi`eBb~6?x=7()b>klt?N1CLti^s zgu9)Mn+j~TRA(%E>czkSs;Qwp-%tM%3t}TCveztnU!IJ*!^-=JspY;`OdmS;^ - * - * 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 -#ifdef HAVE_SSTREAM -#include -#else -#include -#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(bits), static_cast(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; - } - } -} diff --git a/lbtt/src/BitArray.h b/lbtt/src/BitArray.h deleted file mode 100644 index 68ee05285..000000000 --- a/lbtt/src/BitArray.h +++ /dev/null @@ -1,432 +0,0 @@ -/* - * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 - * Heikki Tauriainen - * - * 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 -#include -#include -#include - -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(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(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 */ diff --git a/lbtt/src/Bitset.h b/lbtt/src/Bitset.h deleted file mode 100644 index a7536d5ad..000000000 --- a/lbtt/src/Bitset.h +++ /dev/null @@ -1,626 +0,0 @@ -/* - * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 - * Heikki Tauriainen - * - * 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 -#include -#include -#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(bits.bits), - static_cast(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(bits.bits), - static_cast(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(bits.bits), - static_cast(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 */ diff --git a/lbtt/src/BuchiAutomaton.cc b/lbtt/src/BuchiAutomaton.cc deleted file mode 100644 index ab5d206ed..000000000 --- a/lbtt/src/BuchiAutomaton.cc +++ /dev/null @@ -1,880 +0,0 @@ -/* -*- coding: utf-8 -*- - * - * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 - * Heikki Tauriainen - * - * 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 -#include -#include -#include -#include -#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(), - 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(*transition)->targetNode(), - static_cast(*transition)->guard(), - static_cast(*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(*transition)->targetNode(), - static_cast(*transition)->guard(), - static_cast(*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::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 state_number_map; - pair state_mapping(0, 0); - - pair::const_iterator, bool> state_finder; - - /* - * Also the acceptance set numbers will be mapped to the interval - * [0...(number of acceptance sets - 1)]. - */ - - map acceptance_set_map; - pair acceptance_set_mapping(0, 0); - - pair::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 statistics = stats(); - pair 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(*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 (edges()[i]))->guard(), - (static_cast (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::const_iterator node; - for (node = nodes.begin(); node != nodes.end(); ++node) - if (!(static_cast(*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::const_iterator node; - for (node = nodes.begin(); node != nodes.end(); ++node) - if (!(static_cast(*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(*edge) - ->print(stream, indent, fmt, number_of_acceptance_sets); - - } else - estream << string(indent, ' ') + "No transitions to other states.\n"; - - estream.flush(); -} - -} diff --git a/lbtt/src/BuchiAutomaton.h b/lbtt/src/BuchiAutomaton.h deleted file mode 100644 index c025f33ee..000000000 --- a/lbtt/src/BuchiAutomaton.h +++ /dev/null @@ -1,925 +0,0 @@ -/* - * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 - * Heikki Tauriainen - * - * 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 -#include -#include -#include -#include -#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 -{ -public: - /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - - class BuchiTransition; /* A class for representing - * the transitions between - * the states of the - * automaton. - */ - - /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - - class BuchiState : /* A class for */ - public Graph::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::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 */ - - /* `empty' inherited from Graph */ - - 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 */ - - /* `connected' inherited from Graph */ - - /* `stats' inherited from Graph */ - - /* `subgraphStats' inherited from Graph */ - - 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::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::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::Edge& /* for sorting */ - transition) const; /* transitions in an STL - * container. - */ - - bool operator< /* `Less than' relation. */ - (const Graph::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(*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(Graph::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::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' - * 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(transition) - .guard_formula) - && !(static_cast(transition).guard_formula - < guard_formula)); -} - -/* ========================================================================= */ -inline bool BuchiAutomaton::BuchiTransition::operator< - (const Graph::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' 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(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::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 */ diff --git a/lbtt/src/BuchiProduct.cc b/lbtt/src/BuchiProduct.cc deleted file mode 100644 index d3a6157b6..000000000 --- a/lbtt/src/BuchiProduct.cc +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 - * Heikki Tauriainen - * - * 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::Edge& transition_1, - const Graph::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 - (transition_1).guard(); - LtlFormula* guard_2 = &static_cast - (transition_2).guard(); - - if (guard_2 > guard_1) - { - LtlFormula* swap_guard = guard_2; - guard_2 = guard_1; - guard_1 = swap_guard; - } - - map::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; -} - -} diff --git a/lbtt/src/BuchiProduct.h b/lbtt/src/BuchiProduct.h deleted file mode 100644 index c431d8d36..000000000 --- a/lbtt/src/BuchiProduct.h +++ /dev/null @@ -1,510 +0,0 @@ -/* - * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 - * Heikki Tauriainen - * - * 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 -#include -#include -#include -#include -#include -#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& a1, - const Graph& 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::size_type /* intersection state */ - state_id) const; /* identifier and states */ - const BuchiAutomaton::BuchiState& secondComponent /* of the underlying */ - (const Graph::size_type /* automata. */ - state_id) const; - - void mergeAcceptanceInformation /* Merges the acceptance */ - (const Graph::Node& state1, /* sets associated with */ - const Graph::Node& state2, /* a pair of states into */ - BitArray& acceptance_sets) const; /* a collection of sets. */ - - void mergeAcceptanceInformation /* Merges the acceptance */ - (const Graph::Edge& /* sets associated with */ - transition1, /* a pair of */ - const Graph::Edge& /* transitions into a */ - transition2, /* collection of sets. */ - BitArray& acceptance_sets) const; - - void validateEdgeIterators /* Ensures that a pair */ - (const Graph::Node& /* of transition */ - state_1, /* iterators points to a */ - const Graph::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::Node& /* transition iterators */ - state_1, /* to make them point to */ - const Graph::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::Edge& /* of transitions of two */ - transition_1, /* Büchi automata is */ - const Graph::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& a1, const Graph& a2) : - automaton_1(static_cast(a1)), - automaton_2(static_cast(a2)), - number_of_acceptance_sets(static_cast(a1) - .numberOfAcceptanceSets() - + static_cast(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 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::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::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::Node& state1, - const Graph::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(state1).acceptanceSets(), - static_cast(state2).acceptanceSets(), - acceptance_sets); -} - -/* ========================================================================= */ -inline void BuchiProduct::mergeAcceptanceInformation - (const Graph::Edge& transition1, - const Graph::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(transition1) - .acceptanceSets(), - static_cast(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::Node& state_1, - const Graph::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::Node& state_1, - const Graph::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 */ diff --git a/lbtt/src/Config-lex.ll b/lbtt/src/Config-lex.ll deleted file mode 100644 index ea0af40f9..000000000 --- a/lbtt/src/Config-lex.ll +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 - * Heikki Tauriainen - * - * 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 -#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. */ } - -"\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; } - -enabled { BEGIN(EQ); return CFG_ENABLED; } -name { BEGIN(EQ); return CFG_NAME; } -parameters { BEGIN(EQ); return CFG_PARAMETERS; } -path { BEGIN(EQ); return CFG_PROGRAMPATH; } - -comparisoncheck { BEGIN(EQ); return CFG_COMPARISONTEST; } -comparisontest { BEGIN(EQ); return CFG_COMPARISONTEST; } -consistencycheck { BEGIN(EQ); return CFG_CONSISTENCYTEST; } -consistencytest { BEGIN(EQ); return CFG_CONSISTENCYTEST; } -interactive { BEGIN(EQ); return CFG_INTERACTIVE; } -intersectioncheck { BEGIN(EQ); return CFG_INTERSECTIONTEST; } -intersectiontest { BEGIN(EQ); return CFG_INTERSECTIONTEST; } -modelcheck { BEGIN(EQ); return CFG_MODELCHECK; } -rounds { BEGIN(EQ); return CFG_ROUNDS; } -translatortimeout { BEGIN(EQ); return CFG_TRANSLATORTIMEOUT; } -verbosity { BEGIN(EQ); return CFG_VERBOSITY; } - -edgeprobability { BEGIN(EQ); return CFG_EDGEPROBABILITY; } -propositions { BEGIN(EQ); return CFG_PROPOSITIONS; } -size { BEGIN(EQ); return CFG_SIZE; } -truthprobability { BEGIN(EQ); return CFG_TRUTHPROBABILITY; } -changeinterval { BEGIN(EQ); return CFG_CHANGEINTERVAL; } -randomseed { BEGIN(EQ); return CFG_RANDOMSEED; } - -abbreviatedoperators { BEGIN(EQ); return CFG_ABBREVIATEDOPERATORS; } -andpriority { BEGIN(EQ); return CFG_ANDPRIORITY; } -beforepriority { BEGIN(EQ); return CFG_BEFOREPRIORITY; } -defaultoperatorpriority { - BEGIN(EQ); return CFG_DEFAULTOPERATORPRIORITY; - } -equivalencepriority { BEGIN(EQ); return CFG_EQUIVALENCEPRIORITY; } -falsepriority { BEGIN(EQ); return CFG_FALSEPRIORITY; } -finallypriority { BEGIN(EQ); return CFG_FINALLYPRIORITY; } -generatemode { BEGIN(EQ); return CFG_GENERATEMODE; } -globallypriority { BEGIN(EQ); return CFG_GLOBALLYPRIORITY; } -implicationpriority { BEGIN(EQ); return CFG_IMPLICATIONPRIORITY; } -nextpriority { BEGIN(EQ); return CFG_NEXTPRIORITY; } -notpriority { BEGIN(EQ); return CFG_NOTPRIORITY; } -orpriority { BEGIN(EQ); return CFG_ORPRIORITY; } -outputmode { BEGIN(EQ); return CFG_OUTPUTMODE; } -propositionpriority { BEGIN(EQ); return CFG_PROPOSITIONPRIORITY; } -releasepriority { BEGIN(EQ); return CFG_RELEASEPRIORITY; } -strongreleasepriority { BEGIN(EQ); return CFG_STRONGRELEASEPRIORITY; } -truepriority { BEGIN(EQ); return CFG_TRUEPRIORITY; } -untilpriority { BEGIN(EQ); return CFG_UNTILPRIORITY; } -weakuntilpriority { BEGIN(EQ); return CFG_WEAKUNTILPRIORITY; } -xorpriority { BEGIN(EQ); return CFG_XORPRIORITY; } - -"}" { BEGIN(INITIAL); return CFG_RBRACE; } - -"="?[^= \t\n]* { return CFG_UNKNOWN; } - -"=" { BEGIN(VAL); return CFG_EQUALS; } - -. { return CFG_UNKNOWN; } - -\\|{OKVAL}+(\\)? { - yylval.value = yytext; - BEGIN(ATTR); - return CFG_VALUE; - } - -{OKVAL}*(\'{SQSTR}|\"{DQSTR})(\\)? { - throw Configuration::ConfigurationException - (config_file_line_number, - "unmatched quotes"); - } - -"\n" { return CFG_UNKNOWN; } - -%% diff --git a/lbtt/src/Config-parse.y b/lbtt/src/Config-parse.y deleted file mode 100644 index 24646a9fe..000000000 --- a/lbtt/src/Config-parse.y +++ /dev/null @@ -1,663 +0,0 @@ -/* - * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2009 - * Heikki Tauriainen - * - * 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 -#include -#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 CFG_VALUE -%type 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(); -} diff --git a/lbtt/src/Config-parse_.cc b/lbtt/src/Config-parse_.cc deleted file mode 100644 index 1e567fde8..000000000 --- a/lbtt/src/Config-parse_.cc +++ /dev/null @@ -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" diff --git a/lbtt/src/Configuration.cc b/lbtt/src/Configuration.cc deleted file mode 100644 index b01687f3f..000000000 --- a/lbtt/src/Configuration.cc +++ /dev/null @@ -1,2192 +0,0 @@ -/* -*- coding: utf-8 -*- - * - * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 - * Heikki Tauriainen - * - * 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 -#include -#include -#include -#include "Configuration.h" -#include "IntervalList.h" -#ifdef HAVE_GETOPT_LONG -#include -#define OPTIONSTRUCT struct option -#else -#include "gnu-getopt.h" -#define optarg gnu_optarg -#define optind gnu_optind -#define opterr gnu_opterr -#define OPTIONSTRUCT struct gnu_option -#define getopt_long gnu_getopt_long -#endif /* HAVE_GETOPT_LONG */ - -/****************************************************************************** - * - * Definitions for ranges of certain integer-valued configuration options. - * - *****************************************************************************/ - -const struct Configuration::IntegerRange Configuration::DEFAULT_RANGE - = {0, ULONG_MAX, "value out of range"}; - -const struct Configuration::IntegerRange Configuration::VERBOSITY_RANGE - = {0, 5, "verbosity must be between 0 and 5 (inclusive)"}; - -const struct Configuration::IntegerRange Configuration::ROUND_COUNT_RANGE - = {1, ULONG_MAX, "number of rounds must be positive"}; - -const struct Configuration::IntegerRange Configuration::RANDOM_SEED_RANGE - = {0, UINT_MAX, "random seed out of range"}; - -const struct Configuration::IntegerRange Configuration::ATOMIC_PRIORITY_RANGE - = {0, INT_MAX / 3, "priority out of range"}; - -const struct Configuration::IntegerRange Configuration::OPERATOR_PRIORITY_RANGE - = {0, INT_MAX / 14, "priority out of range"}; - - - -/****************************************************************************** - * - * Function definitions for class Configuration. - * - *****************************************************************************/ - -/* ========================================================================= */ -Configuration::Configuration() -/* ---------------------------------------------------------------------------- - * - * Description: Constructor for class Configuration. Creates a new data - * structure for storing program configuration and initializes - * the configuration parameters to their default values. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - reset(); -} - -/* ========================================================================= */ -Configuration::~Configuration() -/* ---------------------------------------------------------------------------- - * - * Description: Destructor for class Configuration. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - for (vector::const_iterator it = algorithms.begin(); - it != algorithms.end(); ++it) - { - for (vector::size_type p = 0; p <= it->num_parameters; ++p) - delete[] it->parameters[p]; - delete[] it->parameters; - } -} - -/* ========================================================================= */ -void Configuration::read(int argc, char* argv[]) -/* ---------------------------------------------------------------------------- - * - * Description: Parses the command line parameters passed to the program and - * reads the configuration file. - * - * Arguments: argc -- (Number of command line parameters) + 1. - * argv -- Array of C-style strings storing the parameters. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - using namespace ::StringUtil; - - reset(); - - /* Command line option declarations. */ - - static OPTIONSTRUCT command_line_options[] = - { - {"comparisontest", optional_argument, 0, OPT_COMPARISONTEST}, - {"comparisoncheck", optional_argument, 0, OPT_COMPARISONTEST}, - {"configfile", required_argument, 0, OPT_CONFIGFILE}, - {"consistencytest", optional_argument, 0, OPT_CONSISTENCYTEST}, - {"consistencycheck", optional_argument, 0, OPT_CONSISTENCYTEST}, - {"disable", required_argument, 0, OPT_DISABLE}, - {"enable", required_argument, 0, OPT_ENABLE}, - {"formulachangeinterval", required_argument, 0, OPT_FORMULACHANGEINTERVAL}, - {"formulafile", required_argument, 0, OPT_FORMULAFILE}, - {"formularandomseed", required_argument, 0, OPT_FORMULARANDOMSEED}, - {"globalmodelcheck", no_argument, 0, OPT_GLOBALPRODUCT}, - {"help", no_argument, 0, OPT_HELP}, - {"interactive", optional_argument, 0, OPT_INTERACTIVE}, - {"intersectiontest", optional_argument, 0, OPT_INTERSECTIONTEST}, - {"intersectioncheck", optional_argument, 0, OPT_INTERSECTIONTEST}, - {"localmodelcheck", no_argument, 0, OPT_LOCALPRODUCT}, - {"logfile", required_argument, 0, OPT_LOGFILE}, - {"modelcheck", required_argument, 0, OPT_MODELCHECK}, - {"nocomparisontest", no_argument, 0, OPT_COMPARISONTEST}, - {"nocomparisoncheck", no_argument, 0, OPT_COMPARISONTEST}, - {"noconsistencytest", no_argument, 0, OPT_CONSISTENCYTEST}, - {"noconsistencycheck", no_argument, 0, OPT_CONSISTENCYTEST}, - {"nointersectiontest", no_argument, 0, OPT_INTERSECTIONTEST}, - {"nointersectioncheck", no_argument, 0, OPT_INTERSECTIONTEST}, - {"pause", optional_argument, 0, OPT_INTERACTIVE}, - {"profile", no_argument, 0, OPT_PROFILE}, - {"quiet", no_argument, 0, OPT_QUIET}, - {"rounds", required_argument, 0, OPT_ROUNDS}, - {"showconfig", no_argument, 0, OPT_SHOWCONFIG}, - {"showoperatordistribution", no_argument, 0, OPT_SHOWOPERATORDISTRIBUTION}, - {"silent", no_argument, 0, OPT_QUIET}, - {"skip", required_argument, 0, OPT_SKIP}, - {"statespacechangeinterval", required_argument, 0, - OPT_STATESPACECHANGEINTERVAL}, - {"statespacerandomseed", required_argument, 0, OPT_STATESPACERANDOMSEED}, - {"translatortimeout", required_argument, 0 ,OPT_TRANSLATORTIMEOUT}, - {"verbosity", required_argument, 0, OPT_VERBOSITY}, - {"version", no_argument, 0, OPT_VERSION}, - - {"abbreviatedoperators", optional_argument, 0, OPT_ABBREVIATEDOPERATORS}, - {"andpriority", required_argument, 0, OPT_ANDPRIORITY}, - {"beforepriority", required_argument, 0, OPT_BEFOREPRIORITY}, - {"defaultoperatorpriority", required_argument, 0, - OPT_DEFAULTOPERATORPRIORITY}, - {"equivalencepriority", required_argument, 0, OPT_EQUIVALENCEPRIORITY}, - {"falsepriority", required_argument, 0, OPT_FALSEPRIORITY}, - {"finallypriority", required_argument, 0, OPT_FINALLYPRIORITY}, - {"formulageneratemode", required_argument, 0, OPT_FORMULAGENERATEMODE}, - {"formulaoutputmode", required_argument, 0, OPT_FORMULAOUTPUTMODE}, - {"formulapropositions", required_argument, 0, OPT_FORMULAPROPOSITIONS}, - {"formulasize", required_argument, 0, OPT_FORMULASIZE}, - {"generatennf", no_argument, 0, OPT_GENERATENNF}, - {"globallypriority", required_argument, 0, OPT_GLOBALLYPRIORITY}, - {"implicationpriority", required_argument, 0, OPT_IMPLICATIONPRIORITY}, - {"nextpriority", required_argument, 0, OPT_NEXTPRIORITY}, - {"noabbreviatedoperators", no_argument, 0, OPT_ABBREVIATEDOPERATORS}, - {"nogeneratennf", no_argument, 0, OPT_NOGENERATENNF}, - {"nooutputnnf", no_argument, 0, OPT_NOOUTPUTNNF}, - {"notpriority", required_argument, 0, OPT_NOTPRIORITY}, - {"orpriority", required_argument, 0, OPT_ORPRIORITY}, - {"outputnnf", no_argument, 0, OPT_OUTPUTNNF}, - {"propositionpriority", required_argument, 0, OPT_PROPOSITIONPRIORITY}, - {"releasepriority", required_argument, 0, OPT_RELEASEPRIORITY}, - {"strongreleasepriority", required_argument, 0, OPT_STRONGRELEASEPRIORITY}, - {"truepriority", required_argument, 0, OPT_TRUEPRIORITY}, - {"untilpriority", required_argument, 0, OPT_UNTILPRIORITY}, - {"weakuntilpriority", required_argument, 0, OPT_WEAKUNTILPRIORITY}, - {"xorpriority", required_argument, 0, OPT_XORPRIORITY}, - - {"edgeprobability", required_argument, 0, OPT_EDGEPROBABILITY}, - {"enumeratedpath", no_argument, 0, OPT_ENUMERATEDPATH}, - {"randomconnectedgraph", no_argument, 0, OPT_RANDOMCONNECTEDGRAPH}, - {"randomgraph", no_argument, 0, OPT_RANDOMGRAPH}, - {"randompath", no_argument, 0, OPT_RANDOMPATH}, - {"statespacegeneratemode", required_argument, 0, - OPT_STATESPACEGENERATEMODE}, - {"statespacepropositions", required_argument, 0, - OPT_STATESPACEPROPOSITIONS}, - {"statespacesize", required_argument, 0, OPT_STATESPACESIZE}, - {"truthprobability", required_argument, 0, OPT_TRUTHPROBABILITY}, - - {0, 0, 0, 0} - }; - - opterr = 1; /* enable error messages from getopt_long */ - - const char* false_value = "false", *true_value = "true", - *always_value = "always"; - - int opttype; - int option_index; - bool print_config = false, print_operator_distribution = false; - config_file_line_number = -1; - - typedef pair Parameter; - vector parameters; - - /* - * Preprocess the command line parameters. At this point only those special - * options that do not override settings in the configuration file are - * processed completely; all other options are stored in the vector - * `parameters' to be handled only after reading the configuration file. - * The arguments of all parameters taking optional parameters are - * adjusted here. - */ - - do - { - option_index = 0; - opttype = getopt_long(argc, argv, "hV", command_line_options, - &option_index); - - switch (opttype) - { - case OPT_CONFIGFILE : - global_options.cfg_filename = optarg; - break; - - case OPT_FORMULAFILE : - global_options.formula_input_filename = optarg; - break; - - case OPT_HELP : - showCommandLineHelp(argv[0]); - exit(0); - - case OPT_LOGFILE : - global_options.transcript_filename = optarg; - break; - - case OPT_SHOWCONFIG : - print_config = true; - break; - - case OPT_SHOWOPERATORDISTRIBUTION : - print_operator_distribution = true; - break; - - case OPT_SKIP : - readInteger(global_options.init_skip, optarg); - break; - - case OPT_VERSION : - cout << "lbtt " PACKAGE_VERSION "\n" - "lbtt is free software; you may change and " - "redistribute it under the terms of\n" - "the GNU General Public License. lbtt comes with " - "NO WARRANTY. See the file\n" - "COPYING for details.\n"; - exit(0); - break; - - case '?' : - case ':' : - exit(2); - - case -1 : - break; - - case OPT_CONSISTENCYTEST : - case OPT_COMPARISONTEST : - case OPT_INTERSECTIONTEST : - case OPT_ABBREVIATEDOPERATORS : - { - const char* val; - if (command_line_options[option_index].name[0] == 'n') - val = false_value; - else if (optarg == 0) - val = true_value; - else - val = optarg; - parameters.push_back(make_pair(&command_line_options[option_index], - val)); - break; - } - - case OPT_INTERACTIVE : - { - const char* val; - if (optarg == 0) - val = always_value; - else - val = optarg; - parameters.push_back(make_pair(&command_line_options[option_index], - val)); - break; - } - - default : - parameters.push_back(make_pair(&command_line_options[option_index], - optarg)); - break; - } - } - while (opttype != -1); - - /* Read the configuration file. */ - - FILE* configuration_file = fopen(global_options.cfg_filename.c_str(), "r"); - if (configuration_file == NULL) - throw ConfigurationException - (-1, "error opening configuration file `" - + global_options.cfg_filename + "'"); - - try - { - parseConfiguration(configuration_file, *this); - fclose(configuration_file); - } - catch (const ConfigurationException&) - { - fclose(configuration_file); - throw; - } - - config_file_line_number = -1; /* Suppress configuration file line number in - * any future error messages */ - - /* - * Process the command line parameters that override settings made in the - * configuration file. - */ - - vector::const_iterator parameter; - - try - { - for (parameter = parameters.begin(); parameter != parameters.end(); - ++parameter) - { - switch (parameter->first->val) - { - /* Remaining special options (excluding "--enable" and "--disable"). */ - - case OPT_ENABLE : case OPT_DISABLE : /* These options can be */ - break; /* processed only after - * determining whether the - * internal model checking - * algorithm might be - * included in the tests. - */ - - case OPT_PROFILE : - global_options.do_comp_test - = global_options.do_cons_test - = global_options.do_intr_test - = false; - break; - - case OPT_QUIET : - global_options.verbosity = 0; - global_options.interactive = NEVER; - break; - - /* - * Options corresponding to the GlobalOptions section in the - * configuration file. - */ - - case OPT_COMPARISONTEST : - readTruthValue(global_options.do_comp_test, parameter->second); - break; - - case OPT_CONSISTENCYTEST : - readTruthValue(global_options.do_cons_test, parameter->second); - break; - - case OPT_GLOBALPRODUCT : - readProductType("global"); - break; - - case OPT_INTERACTIVE : - readInteractivity(parameter->second); - break; - - case OPT_INTERSECTIONTEST : - readTruthValue(global_options.do_intr_test, parameter->second); - break; - - case OPT_LOCALPRODUCT : - readProductType("local"); - break; - - case OPT_MODELCHECK : - readProductType(parameter->second); - break; - - case OPT_ROUNDS : - readInteger(global_options.number_of_rounds, parameter->second, - ROUND_COUNT_RANGE); - break; - - case OPT_TRANSLATORTIMEOUT : - readTranslatorTimeout(parameter->second); - break; - - case OPT_VERBOSITY : - readInteger(global_options.verbosity, parameter->second, - VERBOSITY_RANGE); - break; - - /* - * Options corresponding to the StatespaceOptions section in the - * configuration file. - */ - - case OPT_EDGEPROBABILITY : - readProbability(statespace_generator.edge_probability, - parameter->second); - break; - - case OPT_ENUMERATEDPATH : - readStateSpaceMode("enumeratedpath"); - break; - - case OPT_RANDOMCONNECTEDGRAPH : - readStateSpaceMode("randomconnectedgraph"); - break; - - case OPT_RANDOMGRAPH : - readStateSpaceMode("randomgraph"); - break; - - case OPT_RANDOMPATH : - readStateSpaceMode("randompath"); - break; - - case OPT_STATESPACECHANGEINTERVAL : - readInteger(global_options.statespace_change_interval, - parameter->second); - break; - - case OPT_STATESPACEGENERATEMODE : - readStateSpaceMode(parameter->second); - break; - - case OPT_STATESPACEPROPOSITIONS : - readInteger(statespace_generator.atoms_per_state, parameter->second); - break; - - case OPT_STATESPACERANDOMSEED : - readInteger(global_options.statespace_random_seed, - parameter->second, RANDOM_SEED_RANGE); - break; - - case OPT_STATESPACESIZE : - readSize(parameter->first->val, parameter->second); - break; - - case OPT_TRUTHPROBABILITY : - readProbability(statespace_generator.truth_probability, - parameter->second); - break; - - /* - * Options corresponding to the FormulaOptions section in the - * configuration file. - */ - - case OPT_ABBREVIATEDOPERATORS : - readTruthValue(formula_options.allow_abbreviated_operators, - parameter->second); - break; - - case OPT_ANDPRIORITY : - readInteger(formula_options.symbol_priority[::Ltl::LTL_CONJUNCTION], - parameter->second, OPERATOR_PRIORITY_RANGE); - break; - - case OPT_BEFOREPRIORITY : - readInteger(formula_options.symbol_priority[::Ltl::LTL_BEFORE], - parameter->second, OPERATOR_PRIORITY_RANGE); - break; - - case OPT_DEFAULTOPERATORPRIORITY : - readInteger(formula_options.default_operator_priority, - parameter->second, OPERATOR_PRIORITY_RANGE); - break; - - case OPT_EQUIVALENCEPRIORITY : - readInteger(formula_options.symbol_priority[::Ltl::LTL_EQUIVALENCE], - parameter->second, OPERATOR_PRIORITY_RANGE); - break; - - case OPT_FALSEPRIORITY : - readInteger(formula_options.symbol_priority[::Ltl::LTL_FALSE], - parameter->second, ATOMIC_PRIORITY_RANGE); - break; - - case OPT_FINALLYPRIORITY : - readInteger(formula_options.symbol_priority[::Ltl::LTL_FINALLY], - parameter->second, OPERATOR_PRIORITY_RANGE); - break; - - case OPT_FORMULACHANGEINTERVAL : - readInteger(global_options.formula_change_interval, - parameter->second); - break; - - case OPT_FORMULAGENERATEMODE : - readFormulaMode(formula_options.generate_mode, parameter->second); - break; - - case OPT_FORMULAOUTPUTMODE : - readFormulaMode(formula_options.output_mode, parameter->second); - break; - - case OPT_FORMULAPROPOSITIONS : - readInteger(formula_options.formula_generator. - number_of_available_variables, - parameter->second); - break; - - case OPT_FORMULARANDOMSEED : - readInteger(global_options.formula_random_seed, parameter->second, - RANDOM_SEED_RANGE); - break; - - case OPT_FORMULASIZE : - readSize(parameter->first->val, parameter->second); - break; - - case OPT_GENERATENNF : - readFormulaMode(formula_options.generate_mode, "nnf"); - break; - - case OPT_GLOBALLYPRIORITY : - readInteger(formula_options.symbol_priority[::Ltl::LTL_GLOBALLY], - parameter->second, OPERATOR_PRIORITY_RANGE); - break; - - case OPT_IMPLICATIONPRIORITY : - readInteger(formula_options.symbol_priority[::Ltl::LTL_IMPLICATION], - parameter->second, OPERATOR_PRIORITY_RANGE); - break; - - case OPT_NEXTPRIORITY : - readInteger(formula_options.symbol_priority[::Ltl::LTL_NEXT], - parameter->second, OPERATOR_PRIORITY_RANGE); - break; - - case OPT_NOGENERATENNF : - readFormulaMode(formula_options.generate_mode, "normal"); - break; - - case OPT_NOOUTPUTNNF : - readFormulaMode(formula_options.output_mode, "normal"); - break; - - case OPT_NOTPRIORITY : - readInteger(formula_options.symbol_priority[::Ltl::LTL_NEGATION], - parameter->second, OPERATOR_PRIORITY_RANGE); - break; - - case OPT_ORPRIORITY : - readInteger(formula_options.symbol_priority[::Ltl::LTL_DISJUNCTION], - parameter->second, OPERATOR_PRIORITY_RANGE); - break; - - case OPT_OUTPUTNNF : - readFormulaMode(formula_options.output_mode, "nnf"); - break; - - case OPT_PROPOSITIONPRIORITY : - readInteger(formula_options.symbol_priority[::Ltl::LTL_ATOM], - parameter->second, ATOMIC_PRIORITY_RANGE); - break; - - case OPT_RELEASEPRIORITY : - readInteger(formula_options.symbol_priority[::Ltl::LTL_V], - parameter->second, OPERATOR_PRIORITY_RANGE); - break; - - case OPT_STRONGRELEASEPRIORITY : - readInteger(formula_options.symbol_priority - [::Ltl::LTL_STRONG_RELEASE], - parameter->second, OPERATOR_PRIORITY_RANGE); - break; - - case OPT_TRUEPRIORITY : - readInteger(formula_options.symbol_priority[::Ltl::LTL_TRUE], - parameter->second, ATOMIC_PRIORITY_RANGE); - break; - - case OPT_UNTILPRIORITY : - readInteger(formula_options.symbol_priority[::Ltl::LTL_UNTIL], - parameter->second, OPERATOR_PRIORITY_RANGE); - break; - - case OPT_WEAKUNTILPRIORITY : - readInteger(formula_options.symbol_priority[::Ltl::LTL_WEAK_UNTIL], - parameter->second, OPERATOR_PRIORITY_RANGE); - break; - - case OPT_XORPRIORITY : - readInteger(formula_options.symbol_priority[::Ltl::LTL_XOR], - parameter->second, OPERATOR_PRIORITY_RANGE); - break; - } - } - - /* - * If using paths as state spaces, include the internal model checking - * algorithm in the set of algorithms. - */ - - if (global_options.statespace_generation_mode & Configuration::PATH) - { - AlgorithmInformation lbtt_info = {"lbtt", new char*[1], 0, true}; - lbtt_info.parameters[0] = new char[1]; - - algorithm_names["lbtt"] = algorithms.size(); - algorithms.push_back(lbtt_info); - } - - /* Process "--enable" and "--disable" options. */ - - for (parameter = parameters.begin(); parameter != parameters.end(); - ++parameter) - { - switch (parameter->first->val) - { - case OPT_DISABLE : - case OPT_ENABLE : - try - { - IntervalList algorithm_ids; - vector nonnumeric_algorithm_ids; - string id_string - = substituteInQuotedString(parameter->second, ",", "\n", - INSIDE_QUOTES); - - parseIntervalList(id_string, algorithm_ids, 0, - algorithms.size() - 1, - &nonnumeric_algorithm_ids); - - for (vector::iterator - id = nonnumeric_algorithm_ids.begin(); - id != nonnumeric_algorithm_ids.end(); - ++id) - { - *id = unquoteString(substituteInQuotedString(*id, "\n", ",")); - map::const_iterator id_finder - = algorithm_names.find(*id); - if (id_finder == algorithm_names.end()) - throw ConfigurationException - (-1, - string("unknown implementation identifier (`") - + *id - + "')"); - algorithm_ids.merge(id_finder->second); - } - - for (IntervalList::const_iterator id = algorithm_ids.begin(); - id != algorithm_ids.end(); - ++id) - algorithms[*id].enabled = (parameter->first->val == OPT_ENABLE); - } - catch (const IntervalRangeException& e) - { - throw ConfigurationException - (-1, - string("invalid implementation identifier (") - + toString(e.getNumber()) - + ")"); - } - - break; - - default : - break; - } - } - } - catch (ConfigurationException& e) - { - e.changeMessage(string("[--") + parameter->first->name + "]: " + e.what()); - throw e; - } - - /* - * Check that the values for configuration options are within acceptable - * limits. Initialize also the values of unspecified options to their - * default values. - */ - - /* - * Check that the number of rounds to run is greater than the number of - * rounds to skip. - */ - - if (global_options.number_of_rounds <= global_options.init_skip) - throw ConfigurationException - (-1, "[--skip]: number of rounds is less than skip count"); - - /* - * Check that there is at least one algorithm available for use. - */ - - if (algorithms.empty()) - throw ConfigurationException - (-1, "no implementations defined in the configuration file"); - - /* - * The case where the number of available variables for propositional - * formulae is zero is equivalent to the case where propositional atoms are - * disallowed in the formulae altogether. - */ - - if (formula_options.formula_generator.number_of_available_variables == 0) - formula_options.symbol_priority[::Ltl::LTL_ATOM] = 0; - - /* - * Verify that at least one propositional symbol class (a Boolean constant - * or a propositional atom) has a nonzero priority. - */ - - if (formula_options.symbol_priority[::Ltl::LTL_ATOM] == 0 - && formula_options.symbol_priority[::Ltl::LTL_TRUE] == 0 - && formula_options.symbol_priority[::Ltl::LTL_FALSE] == 0) - throw ConfigurationException(-1, "at least one atomic symbol should have " - "a nonzero priority"); - - /* - * If the operators ->, <->, xor, <>, [], W and M are disallowed, set their - * priorities to zero. - */ - - if (!formula_options.allow_abbreviated_operators) - { - formula_options.symbol_priority[::Ltl::LTL_IMPLICATION] = 0; - formula_options.symbol_priority[::Ltl::LTL_EQUIVALENCE] = 0; - formula_options.symbol_priority[::Ltl::LTL_XOR] = 0; - formula_options.symbol_priority[::Ltl::LTL_FINALLY] = 0; - formula_options.symbol_priority[::Ltl::LTL_GLOBALLY] = 0; - formula_options.symbol_priority[::Ltl::LTL_WEAK_UNTIL] = 0; - formula_options.symbol_priority[::Ltl::LTL_STRONG_RELEASE] = 0; - formula_options.symbol_priority[::Ltl::LTL_BEFORE] = 0; - } - - /* - * Check that at least one unary operator has a nonzero priority. - * Initialize the priority of the operators whose priority has not yet been - * specified to the default priority. - */ - - bool unary_operator_allowed = false; - - for (map::iterator it = formula_options.symbol_priority.begin(); - it != formula_options.symbol_priority.end(); ++it) - { - if (it->second == -1) - it->second = formula_options.default_operator_priority; - - if (it->second > 0 && !unary_operator_allowed) - unary_operator_allowed = - (it->first == ::Ltl::LTL_NEGATION || it->first == ::Ltl::LTL_NEXT - || it->first == ::Ltl::LTL_FINALLY - || it->first == ::Ltl::LTL_GLOBALLY); - } - - if (!unary_operator_allowed) - throw ConfigurationException(-1, "at least one unary operator should have " - "a nonzero priority"); - - /* - * Initialize the random formula generator with priorities for the LTL - * formula symbols. - */ - - int total_short_unary_priority = 0; - int total_long_unary_priority = 0; - int total_binary_priority = 0; - - for (map::const_iterator - it = formula_options.symbol_priority.begin(); - it != formula_options.symbol_priority.end(); ++it) - { - if (it->second != 0) - { - switch (it->first) - { - case ::Ltl::LTL_ATOM : - case ::Ltl::LTL_TRUE : - case ::Ltl::LTL_FALSE : - formula_options.formula_generator.useSymbol(it->first, it->second); - break; - - case ::Ltl::LTL_NEGATION : - formula_options.formula_generator.useShortOperator - (it->first, it->second); - total_short_unary_priority += it->second; - if (formula_options.generate_mode != NNF) - { - formula_options.formula_generator.useLongOperator - (it->first, it->second); - total_long_unary_priority += it->second; - } - break; - - case ::Ltl::LTL_NEXT : - case ::Ltl::LTL_FINALLY : - case ::Ltl::LTL_GLOBALLY : - formula_options.formula_generator.useShortOperator - (it->first, it->second); - total_short_unary_priority += it->second; - formula_options.formula_generator.useLongOperator - (it->first, it->second); - total_long_unary_priority += it->second; - break; - - case ::Ltl::LTL_CONJUNCTION : - case ::Ltl::LTL_DISJUNCTION : - case ::Ltl::LTL_IMPLICATION : - case ::Ltl::LTL_EQUIVALENCE : - case ::Ltl::LTL_XOR : - case ::Ltl::LTL_UNTIL : - case ::Ltl::LTL_V : - case ::Ltl::LTL_WEAK_UNTIL : - case ::Ltl::LTL_STRONG_RELEASE : - case ::Ltl::LTL_BEFORE : - formula_options.formula_generator.useLongOperator - (it->first, it->second); - total_binary_priority += it->second; - break; - } - } - } - - if (print_operator_distribution - && global_options.formula_input_filename.empty()) - { - /* - * Compute the probability distribution for the operators used in random - * LTL formula generation. - */ - - ProbabilityMap result_cache; - - for (unsigned long int k = 1; - k <= formula_options.formula_generator.max_size; - k++) - { - for (map::const_iterator - op = formula_options.symbol_priority.begin(); - op != formula_options.symbol_priority.end(); - ++op) - { - if (op->second > 0) - { - switch (op->first) - { - case ::Ltl::LTL_ATOM : - case ::Ltl::LTL_TRUE : - case ::Ltl::LTL_FALSE : - break; - - default : - { - double probability = 0.0; - for (unsigned long int s - = formula_options.formula_generator.size; - s <= formula_options.formula_generator.max_size; - s++) - { - if (k >= s) - continue; - probability += operatorProbability - (op->first, k, s, - total_short_unary_priority, - total_long_unary_priority, - total_binary_priority, - result_cache); - } - probability /= static_cast - (formula_options.formula_generator.max_size - - formula_options.formula_generator.size - + 1); - - formula_options.symbol_distribution[op->first] - += k * probability; - - break; - } - } - } - } - } - } - - if (print_config) - { - print(cout); - exit(0); - } -} - -/* ========================================================================= */ -void Configuration::print(ostream& stream, int indent) const -/* ---------------------------------------------------------------------------- - * - * Description: Writes information about the program configuration into a - * stream. - * - * Argument: stream -- A reference to an output stream. - * indent -- Number of spaces to leave to the left of output. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - using namespace ::StringUtil; - - Exceptional_ostream estream(&stream, ios::badbit | ios::failbit); - - estream << string(indent, ' ') + "Program configuration:\n" - + string(indent, ' ') + string(22, '-') + "\n\n" - + string(indent + 2, ' ') - + toString(global_options.number_of_rounds) - + " test round" - + (global_options.number_of_rounds > 1 ? "s" : ""); - - if (global_options.init_skip > 0) - estream << " (of which the first " - + (global_options.init_skip > 1 - ? toString(global_options.init_skip) + " rounds " - : string("")) - + "will be skipped)"; - - estream << ".\n" + string(indent + 2, ' '); - - if (global_options.interactive == ALWAYS) - estream << "Pausing after every test round.\n"; - else if (global_options.interactive == ONERROR) - estream << "Testing will be interrupted in case of an error.\n"; - else - estream << "Running in batch mode.\n"; - estream << string(indent + 2, ' ') - + "Signalling a break will " - + (global_options.handle_breaks ? "interrupt" : "abort") - + " testing.\n"; - - estream << string(indent + 2, ' ') - + "Using " - + (global_options.product_mode == GLOBAL - ? "global" : "local") - + " model checking for tests.\n"; - - if (!global_options.transcript_filename.empty()) - estream << string(indent + 2, ' ') + "Writing error log to `" - + global_options.transcript_filename + "'.\n"; - - estream << '\n' + string(indent + 2, ' ') + "Implementations:\n"; - - vector::size_type algorithm_number = 0; - - for (vector::const_iterator a = algorithms.begin(); - a != algorithms.end(); - ++a) - { - estream << string(indent + 4, ' ') + algorithmString(algorithm_number); - - if (!a->enabled) - estream << " (disabled)"; - - estream << '\n'; - - algorithm_number++; - } - - estream << '\n' + string(indent + 2, ' '); - if (global_options.translator_timeout > 0) - { - estream << "Timeout for translators is set to " - + toString(global_options.translator_timeout) - + " seconds"; - if (global_options.translator_timeout >= 60) - { - bool first_printed = false; - estream << " ("; - if (global_options.translator_timeout >= 3600) - { - first_printed = true; - estream << toString(global_options.translator_timeout / 3600) + " h"; - } - if (global_options.translator_timeout % 3600 > 60) - { - if (first_printed) - estream << ' '; - else - first_printed = true; - estream << toString((global_options.translator_timeout % 3600) / 60) - + " min"; - } - if (global_options.translator_timeout % 60 != 0) - { - if (first_printed) - estream << ' '; - estream << toString(global_options.translator_timeout % 60) + " s"; - } - estream << ')'; - } - estream << ".\n"; - } - else - estream << "Translators are allowed to run until their termination.\n"; - - estream << '\n' + string(indent + 2, ' '); - - if (global_options.do_comp_test || global_options.do_cons_test - || global_options.do_intr_test) - { - estream << "Enabled tests:\n"; - if (global_options.do_comp_test) - estream << string(indent + 4, ' ') + - "Model checking result cross-comparison test\n"; - if (global_options.do_cons_test) - estream << string(indent + 4, ' ') + - "Model checking result consistency check\n"; - if (global_options.do_intr_test) - estream << string(indent + 4, ' ') + - "Büchi automata intersection emptiness check\n"; - } - else - estream << "All automata correctness tests disabled.\n"; - - estream << '\n' + string(indent + 2, ' ') + "Random state spaces:\n" - + string(indent + 4, ' '); - - switch (global_options.statespace_generation_mode) - { - case RANDOMGRAPH : - estream << "Random graphs "; - break; - case RANDOMCONNECTEDGRAPH : - estream << "Random connected graphs "; - break; - case RANDOMPATH : - estream << "Random paths "; - break; - case ENUMERATEDPATH : - estream << "Enumerated paths "; - break; - default : - break; - } - - estream << '(' + toString(statespace_generator.min_size); - - if (statespace_generator.max_size != statespace_generator.min_size - && global_options.statespace_generation_mode != ENUMERATEDPATH) - estream << "..." + toString(statespace_generator.max_size); - - estream << string(" state") - + (statespace_generator.max_size == 1 ? "" : "s") + ", " - + toString(statespace_generator.atoms_per_state) - + " atomic proposition" - + (statespace_generator.atoms_per_state == 1 ? "" : "s") - + ")\n" + string(indent + 4, ' '); - - if (global_options.statespace_change_interval == 0 - || global_options.statespace_change_interval - >= global_options.number_of_rounds) - estream << "Using a fixed state space.\n" + string(indent + 4, ' '); - else - { - estream << "New state space will be generated after every "; - if (global_options.statespace_change_interval > 1) - { - estream << global_options.statespace_change_interval; - - if (global_options.statespace_change_interval % 100 < 10 - || global_options.statespace_change_interval % 100 >= 20) - { - switch (global_options.statespace_change_interval % 10) - { - case 1 : estream << "st"; break; - case 2 : estream << "nd"; break; - case 3 : estream << "rd"; break; - default : estream << "th"; break; - } - } - else - estream << "th"; - - estream << ' '; - } - - estream << "round.\n" + string(indent + 4, ' '); - } - - if (global_options.statespace_generation_mode != ENUMERATEDPATH) - { - estream << "Random seed: " - + toString(global_options.statespace_random_seed) - + '\n' + string(indent + 4, ' '); - - if (global_options.statespace_generation_mode & GRAPH) - estream << "Random edge probability: " - + toString(statespace_generator.edge_probability) - + '\n' + string(indent + 4, ' '); - - estream << "Propositional truth probability: " - + toString(statespace_generator.truth_probability) - + "\n"; - } - - estream << "\n" + string(indent + 2, ' '); - - if (global_options.formula_input_filename.empty()) - { - estream << "Random LTL formulas:\n" + string(indent + 4, ' ') - + toString(formula_options.formula_generator.size); - - if (formula_options.formula_generator.max_size - != formula_options.formula_generator.size) - estream << "..." - + toString(formula_options.formula_generator.max_size); - - estream << string(" parse tree node") - + (formula_options.formula_generator.max_size == 1 ? "" : "s") - + ", " - + toString(formula_options.formula_generator. - number_of_available_variables) - + " atomic proposition" - + (formula_options.formula_generator. - number_of_available_variables == 1 ? "" : "s"); - } - else - { - estream << "Reading LTL formulas from "; - if (global_options.formula_input_filename == "-") - estream << "standard input."; - else - estream << "`" + global_options.formula_input_filename + "'."; - } - - estream << '\n' + string(indent + 4, ' '); - - if (global_options.formula_change_interval == 0 - || global_options.formula_change_interval - >= global_options.number_of_rounds) - estream << "Using a fixed LTL formula."; - else - { - estream << "New LTL formula will be " - << (global_options.formula_input_filename.empty() - ? "generate" - : "rea") - << "d after every "; - if (global_options.formula_change_interval > 1) - { - estream << global_options.formula_change_interval; - - if (global_options.formula_change_interval % 100 < 10 - || global_options.formula_change_interval % 100 >= 20) - { - switch (global_options.formula_change_interval % 10) - { - case 1 : estream << "st"; break; - case 2 : estream << "nd"; break; - case 3 : estream << "rd"; break; - default : estream << "th"; break; - } - } - else - estream << "th"; - - estream << ' '; - } - - estream << "round."; - } - - estream << '\n'; - - if (global_options.formula_input_filename.empty() - && formula_options.generate_mode == NNF) - estream << string(indent + 4, ' ') - + "Formulas will be generated into negation normal form.\n"; - else if (formula_options.output_mode == NNF) - estream << string(indent + 4, ' ') - + "Formulas will be converted into negation normal form.\n"; - - if (global_options.formula_input_filename.empty()) - { - estream << string(indent + 4, ' ') + "Random seed: " - + toString(global_options.formula_random_seed) - + '\n' + string(indent + 4, ' ') - + "Atomic symbols in use (priority):\n" - + string(indent + 6, ' '); - - bool first_printed = false; - - for (map::const_iterator - op = formula_options.symbol_priority.begin(); - op != formula_options.symbol_priority.end(); - ++op) - { - if ((op->first != ::Ltl::LTL_ATOM && op->first != ::Ltl::LTL_TRUE - && op->first != ::Ltl::LTL_FALSE) - || op->second == 0) - continue; - - if (first_printed) - estream << "; "; - - first_printed = true; - - switch (op->first) - { - case ::Ltl::LTL_ATOM : - estream << "propositions"; - break; - case ::Ltl::LTL_TRUE : case ::Ltl::LTL_FALSE : - estream << ::Ltl::infixSymbol(op->first); - break; - default : - break; - } - - estream << " (" << op->second << ')'; - } - - estream << '\n' - << string(indent + 4, ' ') - + "Operators used for random LTL formula generation:"; - - string operator_name_string; - string operator_priority_string; - string operator_distribution_string; - int number_of_operators_printed = 0; - int max_operators_per_line - = (formula_options.symbol_distribution.empty() ? 7 : 6); - - for (map::const_iterator op - = formula_options.symbol_priority.begin(); - op != formula_options.symbol_priority.end(); - ++op) - { - if (op->first == ::Ltl::LTL_ATOM || op->first == ::Ltl::LTL_TRUE - || op->first == ::Ltl::LTL_FALSE || op->second == 0) - continue; - - if (number_of_operators_printed % max_operators_per_line == 0) - { - operator_name_string = string(indent + 6, ' ') + "operator "; - operator_priority_string = string(indent + 6, ' ') + "priority "; - - if (!formula_options.symbol_distribution.empty()) - { - operator_name_string = string(11, ' ') + operator_name_string; - operator_priority_string = string(11, ' ') - + operator_priority_string; - operator_distribution_string - = string(indent + 6, ' ') + "occurrences/formula "; - } - } - - string symbol_string = ::Ltl::infixSymbol(op->first); - operator_name_string += symbol_string; - - string priority_string = ::StringUtil::toString(op->second); - operator_priority_string += priority_string; - - string distribution_string; - if (!formula_options.symbol_distribution.empty()) - { - distribution_string - = ::StringUtil::toString(formula_options.symbol_distribution. - find(op->first)->second, 3); - - operator_distribution_string += distribution_string; - } - - if (number_of_operators_printed % max_operators_per_line - == max_operators_per_line - 1) - { - estream << '\n' + operator_name_string + '\n' - + operator_priority_string + '\n'; - - if (!formula_options.symbol_distribution.empty()) - estream << operator_distribution_string + '\n'; - } - else - { - operator_name_string += string(9 - symbol_string.length(), ' '); - operator_priority_string += string(9 - priority_string.length(), ' '); - if (!formula_options.symbol_distribution.empty()) - operator_distribution_string - += string(9 - distribution_string.length(), ' '); - } - - number_of_operators_printed++; - } - - if (number_of_operators_printed % max_operators_per_line != 0) - { - estream << '\n' + operator_name_string + '\n' + operator_priority_string - + '\n'; - - if (!formula_options.symbol_distribution.empty()) - estream << operator_distribution_string + '\n'; - } - } - - estream << '\n'; - estream.flush(); -} - -/* ========================================================================= */ -string Configuration::algorithmString - (vector::size_type algorithm_id) const -/* ---------------------------------------------------------------------------- - * - * Description: Constructs a string with an algorithm identifer and the name - * of the algorithm in the form ": `'". - * - * Arguments: algorithm_id -- Numeric identifier for the algorithm. - * - * Returns: A string with the algorithm's id and name. - * - * ------------------------------------------------------------------------- */ -{ - using ::StringUtil::toString; - return toString(algorithm_id) + ": `" + algorithms[algorithm_id].name + '\''; -} - -/* ========================================================================= */ -void Configuration::showCommandLineHelp(const char* program_name) -/* ---------------------------------------------------------------------------- - * - * Description: Prints the list of command line options. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - cout << string("Usage: ") + program_name - + " [OPTION]...\n\nGeneral options:\n" - " --comparisontest[=VALUE], --nocomparisontest\n" - " Enable or disable the model " - "checking result\n" - " cross-comparison test\n" - " --configfile=FILE Read configuration from FILE\n" - " --consistencytest[=VALUE], --noconsistencytest\n" - " Enable or disable the model " - "checking result\n" - " consistency test\n" - " --disable=IMPLEMENTATION-ID[,IMPLEMENTATION-ID...]\n" - " Exclude implementation(s) from " - "tests\n" - " --enable=IMPLEMENTATION-ID[,IMPLEMENTATION-ID,...]\n" - " Include implementation(s) into " - "tests\n" - " --formulafile=FILE Read LTL formulas from FILE " - "(- = standard input)\n" - " --globalmodelcheck Use global model checking in " - "tests\n" - " (equivalent to " - "`--modelcheck=global')\n" - " -h, --help Show this help and exit\n" - " --interactive[=MODE[,MODE]], --pause[=MODE[,MODE]]\n" - " Set the interactivity mode " - "(`always', `onerror', \n" - " `never', `onbreak')\n" - " --intersectiontest[=VALUE], --nointersectiontest\n" - " Enable or disable the Büchi " - "automata\n" - " intersection emptiness test\n" - " --localmodelcheck Use local model checking in tests" - "\n" - " (equivalent to " - "`--modelcheck=local')\n" - " --logfile=FILE Write error log to FILE\n" - " --modelcheck=MODE Set model checking mode " - "(`global' or `local')\n" - " --profile Disable all automata correctness " - "tests\n" - " --quiet, --silent Run all tests silently without " - "pausing\n" - " --rounds=NUMBER-OF-ROUNDS Set number of test rounds (1-)\n" - " --showconfig Display current configuration and " - "exit\n" - " --showoperatordistribution Display probability distribution " - "for LTL formula\n" - " operators\n" - " --skip=NUMBER-OF-ROUNDS Set number of test rounds to skip " - "before\n" - " starting tests\n" - " --translatortimeout=TIME Set timeout for translators\n" - " --verbosity=INTEGER Set the verbosity of output (0-5)\n" - " -V,--version Display program version and exit" - "\n\n" - "LTL formula generation options:\n" - " --abbreviatedoperators[=VALUE], --noabbreviatedoperators\n" - " Allow or disallow operators ->, " - "<->, xor, <>, [],\n" - " W, M, and B in the generated " - "formulas\n" - " --andpriority=INTEGER Set priority for the /\\ operator\n" - " --beforepriority=INTEGER Set priority for the Before " - "operator\n" - " --defaultoperatorpriority=INTEGER\n" - " Set default priority for operators" - "\n" - " --equivalencepriority=INTEGER\n" - " Set priority for the <-> operator\n" - " --falsepriority=INTEGER Set priority for the constant " - "`false'\n" - " --finallypriority=INTEGER Set priority for the <> operator\n" - " --formulachangeinterval=NUMBER-OF-ROUNDS\n" - " Set formula generation interval in " - "test rounds\n" - " (0-)\n" - " --formulageneratemode=MODE Set formula generation mode " - "(`normal', `nnf')\n" - " --formulaoutputmode=MODE Set formula output mode (`normal', " - "`nnf')\n" - " --formulapropositions=NUMBER-OF-PROPOSITIONS\n" - " Set maximum number of atomic " - "propositions in\n" - " generated formulas (0-)\n" - " --formularandomseed=INTEGER Set random seed for the formula " - "generation\n" - " algorithm\n" - " --formulasize=SIZE,\n" - " --formulasize=MIN-SIZE...MAX-SIZE\n" - " Set size of random LTL formulas " - "(1-)\n" - " --[no]generatennf Force or prevent generating LTL " - "formulas in\n" - " negation normal form\n" - " --globallypriority=INTEGER Set priority for the [] operator\n" - " --implicationpriority=INTEGER\n" - " Set priority for the -> operator\n" - " --nextpriority=INTEGER Set priority for the Next operator" - "\n" - " --notpriority=INTEGER Set priority for the negation " - "operator\n" - " --orpriority=INTEGER Set priority for the \\/ operator\n" - " --[no]outputnnf Enable or disable formula " - "translation to\n" - " negation normal form before " - "invoking the\n" - " translators\n" - " --propositionpriority=INTEGER\n" - " Set priority for atomic " - "propositions\n" - " --releasepriority=INTEGER Set priority for the (Weak) Release" - " operator\n" - " --strongreleasepriority=INTEGER\n" - " Set priority for the Strong " - "Release operator\n" - " --truepriority=INTEGER Set priority for the constant " - "`true'\n" - " --untilpriority=INTEGER Set priority for the (Strong) Until" - " operator\n" - " --weakuntilpriority=INTEGER\n" - " Set priority for the Weak Until " - "operator\n" - " --xorpriority=INTEGER Set priority for the xor " - "operator\n\n" - "State space generation options:\n" - " --edgeprobability=PROBABILITY\n" - " Set random edge probability for " - "state spaces\n" - " (0.0--1.0)\n" - " --enumeratedpath Enumerate all paths of a given " - "size and a given\n" - " number of propositions per state " - "(equivalent to\n" - " `--statespacegeneratemode=" - "enumeratedpath')\n" - " --randomconnectedgraph Generate connected graphs as state " - "spaces\n" - " (equivalent to\n" - " `--statespacegeneratemode=" - "randomconnectedgraph')\n" - " --randomgraph Generate random graphs as state " - "spaces\n" - " (equivalent to\n" - " `--statespacegeneratemode=" - "randomgraph')\n" - " --randompath Generate random paths as state " - "spaces\n" - " (equivalent to\n" - " `--statespacegeneratemode=" - "randompath')\n" - " --statespacechangeinterval=NUMBER-OF-ROUNDS\n" - " Set state space generation " - "interval in test\n" - " rounds (0-)\n" - " --statespacegeneratemode=MODE\n" - " Set state space generation mode\n" - " (`randomconnectedgraph', " - "`randomgraph',\n" - " `randompath', `enumeratedpath')\n" - " --statespacepropositions=NUMBER-OF-PROPOSITIONS\n" - " Set number of propositions per " - "state (0-)\n" - " --statespacerandomseed=INTEGER\n" - " Set random seed for the state " - "space generation\n" - " algorithm\n" - " --statespacesize=SIZE,\n" - " --statespacesize=MIN-SIZE...MAX-SIZE\n" - " Set size of generated state spaces " - "(1-)\n" - " --truthprobability=PROBABILITY\n" - " Set truth probability of " - "propositions (0.0--1.0)\n\n" - "Report bugs to <" PACKAGE_BUGREPORT ">.\n"; -} - -/* ========================================================================= */ -void Configuration::reset() -/* ---------------------------------------------------------------------------- - * - * Description: Resets the program configuration to the default - * configuration. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - global_options.verbosity = 3; - global_options.interactive = ALWAYS; - global_options.handle_breaks = false; - global_options.number_of_rounds = 10; - global_options.init_skip = 0; - global_options.statespace_change_interval = 1; - global_options.statespace_generation_mode = RANDOMCONNECTEDGRAPH; - global_options.formula_change_interval = 1; - global_options.product_mode = GLOBAL; - global_options.cfg_filename = "config"; - global_options.transcript_filename = ""; - global_options.formula_input_filename = ""; - global_options.do_comp_test = true; - global_options.do_cons_test = true; - global_options.do_intr_test = true; - global_options.statespace_random_seed = 1; - global_options.formula_random_seed = 1; - global_options.translator_timeout = 0; - - formula_options.default_operator_priority = 0; - formula_options.symbol_priority.clear(); - formula_options.symbol_priority[::Ltl::LTL_ATOM] = 90; - formula_options.symbol_priority[::Ltl::LTL_TRUE] = 5; - formula_options.symbol_priority[::Ltl::LTL_FALSE] = 5; - formula_options.symbol_priority[::Ltl::LTL_CONJUNCTION] = -1; - formula_options.symbol_priority[::Ltl::LTL_DISJUNCTION] = -1; - formula_options.symbol_priority[::Ltl::LTL_UNTIL] = -1; - formula_options.symbol_priority[::Ltl::LTL_V] = -1; - formula_options.symbol_priority[::Ltl::LTL_WEAK_UNTIL] = -1; - formula_options.symbol_priority[::Ltl::LTL_STRONG_RELEASE] = -1; - formula_options.symbol_priority[::Ltl::LTL_BEFORE] = -1; - formula_options.symbol_priority[::Ltl::LTL_IMPLICATION] = -1; - formula_options.symbol_priority[::Ltl::LTL_EQUIVALENCE] = -1; - formula_options.symbol_priority[::Ltl::LTL_XOR] = -1; - formula_options.symbol_priority[::Ltl::LTL_NEGATION] = -1; - formula_options.symbol_priority[::Ltl::LTL_NEXT] = -1; - formula_options.symbol_priority[::Ltl::LTL_FINALLY] = -1; - formula_options.symbol_priority[::Ltl::LTL_GLOBALLY] = -1; - - formula_options.symbol_distribution.clear(); - - formula_options.allow_abbreviated_operators = true; - formula_options.output_mode = NORMAL; - formula_options.generate_mode = NORMAL; - - formula_options.formula_generator.reset(); - - statespace_generator.reset(); -} - -/* ========================================================================= */ -void Configuration::registerAlgorithm - (const string& name, const string& path, const string& parameters, - bool enabled, const int block_begin_line) -/* ---------------------------------------------------------------------------- - * - * Description: Adds a new implementation to the configuration. - * - * Arguments: name -- Name of the implementation. If empty, - * the implementation will be given the - * name `Algorithm n', where n is the - * number of previously registered - * algorithms. The name "lbtt" is - * reserved and cannot be used as a name - * for an implementation. In addition, - * `name' should be unique among the set - * of the names of previously registered - * implementations. - * path -- Path to the executable file used for - * invoking the implementation. This - * string should not be empty. - * parameters -- Parameters for the implementation. - * Parameters containing white space - * should be quoted. - * enabled -- Whether the implementation is initially - * enabled. - * block_begin_line -- Number of the first line of the most - * recently encountered Algorithm block in - * the configuration file. - * - * Returns: Nothing. The function throws a ConfigurationException if - * `name' or `path' fails to satisfy one of the above - * requirements. - * - * ------------------------------------------------------------------------- */ -{ - using namespace ::StringUtil; - string error; - - AlgorithmInformation algorithm_information; - - if (!name.empty()) - algorithm_information.name = name; - else - algorithm_information.name = "Algorithm " + toString(algorithms.size()); - - if (algorithm_information.name == "lbtt") - error = "`lbtt' is a reserved name for an implementation"; - else if (algorithm_names.find(algorithm_information.name) - != algorithm_names.end()) - error = "multiple definitions for implementation `" - + algorithm_information.name + "'"; - else if (path.empty() && enabled) - error = "missing path to executable for implementation `" - + algorithm_information.name + "'"; - - if (!error.empty()) - throw ConfigurationException - (toString(block_begin_line) - + (config_file_line_number > block_begin_line - ? "-" + toString(config_file_line_number) - : string("")), - error); - - vector params; - sliceString(unquoteString(substituteInQuotedString(parameters, " \t", "\n\n", - OUTSIDE_QUOTES)), - "\n", - params); - - /* - * Initialize the parameter array for the implementation. This array is - * arranged into a standard argv-style array of C-style strings (ready to be - * used as a parameter for one of the exec functions) and has the following - * structure: - * Index Description - * 0 -- Path to the executable for invoking the - * implementation (obtained from `path'). - * 1...params.size() -- Optional parameters (obtained from the - * `params' vector). - * params.size() + 1, -- Reserved for storing the input and output - * params.size() + 2 file names given as the last two parameters - * for the implementation. - * params.size() + 3 -- A 0 pointer terminating the parameter list. - */ - - algorithm_information.parameters = new char*[params.size() + 4]; - algorithm_information.num_parameters = params.size(); - - algorithm_information.parameters[0] = new char[path.size() + 1]; - memcpy(static_cast(algorithm_information.parameters[0]), - static_cast(path.c_str()), path.size() + 1); - - for (vector::size_type p = 0; - p < algorithm_information.num_parameters; - ++p) - { - algorithm_information.parameters[p + 1] = new char[params[p].size() + 1]; - memcpy(static_cast(algorithm_information.parameters[p + 1]), - static_cast(params[p].c_str()), params[p].size() + 1); - } - - algorithm_information.parameters - [algorithm_information.num_parameters + 3] = 0; - - algorithm_information.enabled = enabled; - - algorithm_names[algorithm_information.name] = algorithms.size(); - algorithms.push_back(algorithm_information); -} - -/* ========================================================================= */ -void Configuration::readProbability(double& target, const string& value) -/* ---------------------------------------------------------------------------- - * - * Description: Reads a probability and stores it into `target'. - * - * Arguments: target -- A reference to a double for storing the result. - * value -- The probability as a string. - * - * Returns: Nothing; the result is stored into `target'. The function - * throws a ConfigurationException if `value' is not a valid - * probability (a number between 0.0 and 1.0). - * - * ------------------------------------------------------------------------- */ -{ - char* endptr; - string error; - - target = strtod(value.c_str(), &endptr); - if (*endptr != '\0') - error = "`" + value + "' is not a valid real number"; - else if (target < 0.0 || target > 1.0) - error = "probability must be between 0.0 and 1.0 (inclusive)"; - - if (!error.empty()) - throw ConfigurationException(config_file_line_number, error); -} - -/* ========================================================================= */ -void Configuration::readSize(int valtype, const string& value) -/* ---------------------------------------------------------------------------- - * - * Description: Initializes formula or state space size ranges from `value'. - * - * Arguments: valtype -- If == OPT_STATESPACESIZE, store the result in - * `this->statespace_generator.min_size' and - * `this->statespace_generator.max_size'; otherwise - * store the result in - * `this->formula_options.formula_generator.size' - * and - * `this->formula_options.formula_generator. - * max_size'. - * value -- Size range as a string (a single integer or a - * closed integer interval). - * - * Returns: Nothing; the result is stored into the Configuration object. - * The function throws a ConfigurationException if `value' is - * not a valid positive integer or a closed nonempty integer - * interval. - * - * ------------------------------------------------------------------------- */ -{ - string error; - unsigned long int min, max; - - try - { - int interval_type = ::StringUtil::parseInterval(value, min, max); - if (!(interval_type & ::StringUtil::LEFT_BOUNDED) || - !(interval_type & ::StringUtil::RIGHT_BOUNDED)) - throw Exception(); - - if (min < 1) - { - if (valtype == OPT_STATESPACESIZE) - error = "state space size must be positive"; - else - error = "formula size must be positive"; - } - else if (min > max) - { - if (valtype == OPT_STATESPACESIZE) - error = "minimum state space size exceeds maximum state space size"; - else - error = "minimum formula size exceeds maximum formula size"; - } - } - catch (const Exception&) - { - error = "`" + value + "' is neither a valid positive integer nor a closed " - "integer interval"; - } - - if (!error.empty()) - throw ConfigurationException(config_file_line_number, error); - - if (valtype == OPT_STATESPACESIZE) - { - statespace_generator.min_size = min; - statespace_generator.max_size = max; - } - else - { - formula_options.formula_generator.size = min; - formula_options.formula_generator.max_size = max; - } -} - -/* ========================================================================= */ -void Configuration::readTruthValue(bool& target, const string& value) -/* ---------------------------------------------------------------------------- - * - * Description: Interprets a symbolic truth value and stores it into - * `target'. - * - * Arguments: target -- A reference to a Boolean variable whose value - * should be set according to the given value. - * value -- The symbolic truth value. - * - * Returns: Nothing; the interpreted value is stored in `target'. If - * `value' is not a valid truth value, the function throws a - * ConfigurationException. - * - * ------------------------------------------------------------------------- */ -{ - const string value_in_lower_case = ::StringUtil::toLowerCase(value); - - if (value_in_lower_case == "yes" || value_in_lower_case == "true") - target = true; - else if (value_in_lower_case == "no" || value_in_lower_case == "false") - target = false; - else - throw ConfigurationException - (config_file_line_number, - "`" + value + "' is not a valid truth value"); -} - -/* ========================================================================= */ -void Configuration::readInteractivity(const string& value) -/* ---------------------------------------------------------------------------- - * - * Description: Interprets a symbolic list of interactivity modes and updates - * `this->global_options.interactive' and - * `this->global_options.handle_breaks' accordingly. - * - * Argument: value -- The symbolic mode (a comma-separated list of - * "always", "onerror", "never" or "onbreak"; the - * case is not relevant). - * - * Returns: Nothing; the result is stored in - * `this->global_options.interactive' and/or - * `this->global_options.handle_breaks'. The function throws a - * ConfigurationException is `value' is not a valid - * interactivity mode. - * - * ------------------------------------------------------------------------- */ -{ - /* - * Reset the interactivity mode to NEVER and disable break handling to allow - * the interactivity specification to be interpreted correctly. - */ - - global_options.interactive = NEVER; - global_options.handle_breaks = false; - - vector modes; - ::StringUtil::sliceString(value, ",", modes); - for (vector::const_iterator mode = modes.begin(); - mode != modes.end(); - ++mode) - { - string mode_in_lower_case = ::StringUtil::toLowerCase(*mode); - - if (mode_in_lower_case == "always") - global_options.interactive = ALWAYS; - else if (mode_in_lower_case == "onerror") - global_options.interactive = ONERROR; - else if (mode_in_lower_case == "never") - global_options.interactive = NEVER; - else if (mode_in_lower_case == "onbreak") - global_options.handle_breaks = true; - else - throw ConfigurationException - (config_file_line_number, - "`" + *mode + "' is not a valid interactivity mode"); - } -} - -/* ========================================================================= */ -void Configuration::readProductType(const string& value) -/* ---------------------------------------------------------------------------- - * - * Description: Interprets a symbolic model checking mode and updates - * `this->global_options.product_mode' accordingly. - * - * Argument: value -- The symbolic mode (one of "local" or "global"; the - * case of characters is not relevant). - * - * Returns: Nothing; the result is stored in - * `this->global_options.product_mode'. The function throws a - * ConfigurationException is `value' is not a valid model - * checking mode. - * - * ------------------------------------------------------------------------- */ -{ - const string value_in_lower_case = ::StringUtil::toLowerCase(value); - - if (value_in_lower_case == "global") - global_options.product_mode = GLOBAL; - else if (value_in_lower_case == "local") - global_options.product_mode = LOCAL; - else - throw ConfigurationException - (config_file_line_number, - "`" + value + "' is not a valid model checking mode"); -} - -/* ========================================================================= */ -void Configuration::readFormulaMode(FormulaMode& target, const string& mode) -/* ---------------------------------------------------------------------------- - * - * Description: Interprets a symbolic formula mode and updates `target' - * accordingly. - * - * Argument: mode -- Symbolic formula mode (one of "normal" or "nnf"; - * the case of characters is not relevant). - * - * Returns: Nothing; the result is stored into `target'. The function - * throws a ConfigurationException if `mode' is not a valid mode - * string. - * - * ------------------------------------------------------------------------- */ -{ - const string mode_in_lower_case = ::StringUtil::toLowerCase(mode); - - if (mode_in_lower_case == "nnf") - target = NNF; - else if (mode_in_lower_case == "normal") - target = NORMAL; - else - throw ConfigurationException - (config_file_line_number, - "`" + mode + "' is not a valid formula mode"); -} - -/* ========================================================================= */ -void Configuration::readStateSpaceMode(const string& mode) -/* ---------------------------------------------------------------------------- - * - * Description: Interprets a symbolic state space generation mode and updates - * `global_options.statespace_generation_mode' accordingly. - * - * Argument: mode -- Symbolic state space generation mode (one of - * "randomconnectedgraph", "randomgraph", "randompath" - * and "enumeratedpath"; the case of characters is - * not relevant). - * - * Returns: Nothing; the result is stored into - * `global_options.statespace_generation_mode'. The function - * throws a ConfigurationException if `mode' is not one of the - * above keywords. - * - * ------------------------------------------------------------------------- */ -{ - const string mode_in_lower_case = ::StringUtil::toLowerCase(mode); - - if (mode_in_lower_case == "randomconnectedgraph") - global_options.statespace_generation_mode = RANDOMCONNECTEDGRAPH; - else if (mode_in_lower_case == "randomgraph") - global_options.statespace_generation_mode = RANDOMGRAPH; - else if (mode_in_lower_case == "randompath") - global_options.statespace_generation_mode = RANDOMPATH; - else if (mode_in_lower_case == "enumeratedpath") - global_options.statespace_generation_mode = ENUMERATEDPATH; - else - throw ConfigurationException - (config_file_line_number, - "`" + mode + "' is not a valid state space generation mode"); -} - -/* ========================================================================= */ -void Configuration::readTranslatorTimeout(const string& value) -/* ---------------------------------------------------------------------------- - * - * Description: Reads a time specification from a string into - * `this->global_options.translator_timeout'. - * - * Argument: value -- A time specification in the format expected by - * ::StringUtil::parseTime. - * - * Returns: Nothing; the result is stored into - * `this->global_options.translator_timeout'. The function - * throws a ConfigurationException if `value' is not a valid - * time specification. - * - * ------------------------------------------------------------------------- */ -{ - unsigned long int hours, minutes, seconds; - try - { - ::StringUtil::parseTime(value, hours, minutes, seconds); - } - catch (const Exception&) - { - throw ConfigurationException - (config_file_line_number, - "`" + value + "' is not a valid time specification"); - } - global_options.translator_timeout = (hours * 60 + minutes) * 60 + seconds; -} - -/* ========================================================================= */ -double Configuration::operatorProbability - (const int op, const int k, const int n, - const int total_short_unary_priority, const int total_long_unary_priority, - const int total_binary_priority, - ProbabilityMap& result_cache) const -/* ---------------------------------------------------------------------------- - * - * Description: Computes the probability with which a randomly generated - * formula of size `n' will contain exactly `k' occurrences of - * the operator `op'. - * - * Arguments: op -- Operator type identifier. - * k -- Number of occurrences of `op' - * in a formula. - * n -- Formula size. - * total_short_unary_priority -- Combined priority of all - * unary operators allowed in - * formulae of size 2. - * total_long_unary_priority -- Combined priority of all - * unary operators allowed in - * formulae of size greater than - * 2. - * total_binary_priority -- Combined priority of all - * binary operators (allowed in - * formulae of size greater than - * 2). - * result_cache -- Data structure for storing - * intermediate results. - * - * Returns: The probability with which a randomly generated formula of - * size `n' will contain exactly `k' occurrences of the operator - * `op'. - * - * ------------------------------------------------------------------------- */ -{ - double result; - - int arity; - int priority = formula_options.symbol_priority.find(op)->second; - - ProbabilityMap::const_iterator check_op(result_cache.find(op)); - if (check_op != result_cache.end()) - { - ProbabilityMapElement::const_iterator check_p - (check_op->second.find(make_pair(k, n))); - if (check_p != check_op->second.end()) - return check_p->second; - } - - switch (op) - { - case ::Ltl::LTL_NEGATION : - case ::Ltl::LTL_NEXT : - case ::Ltl::LTL_FINALLY : - case ::Ltl::LTL_GLOBALLY : - arity = 1; - break; - - default : - arity = 2; - break; - } - - if (k == 0) - { - result = 1.0; - for (int kp = 1; kp < n; kp++) - result -= operatorProbability(op, kp, n, - total_short_unary_priority, - total_long_unary_priority, - total_binary_priority, - result_cache); - } - else if (n == 1 || k >= n) - result = 0.0; - else if (k == 1 && n == 2) - { - if (arity == 1 && total_short_unary_priority > 0) - result = static_cast(priority) - / static_cast(total_short_unary_priority); - else - result = 0.0; - } - else - { - int p1, p2; - - if (arity == 1) - { - p1 = total_long_unary_priority; - if (op != ::Ltl::LTL_NEGATION || formula_options.generate_mode != NNF) - p1 -= priority; - p2 = total_binary_priority; - } - else - { - p1 = total_long_unary_priority; - p2 = total_binary_priority - priority; - } - - result = 0.0; - for (int m = 1; m <= n - 2; m++) - for (int i = 0; i <= k; i++) - { - if (i >= m || k - i >= n - m - 1) - continue; - result += operatorProbability(op, i, m, - total_short_unary_priority, - total_long_unary_priority, - total_binary_priority, - result_cache) - * operatorProbability(op, k - i, n - m - 1, - total_short_unary_priority, - total_long_unary_priority, - total_binary_priority, - result_cache); - } - - result *= static_cast(p2); - - if (arity == 1) - { - result /= static_cast(n - 2); - - if (op != ::Ltl::LTL_NEGATION || formula_options.generate_mode != NNF) - result += static_cast(priority) - * operatorProbability(op, k - 1, n - 1, - total_short_unary_priority, - total_long_unary_priority, - total_binary_priority, - result_cache); - } - else - { - double r = 0.0; - for (int m = 1; m <= n - 2; m++) - for (int i = 0; i <= k - 1; i++) - { - if (i >= m || k - 1 - i >= n - m - 1) - continue; - r += operatorProbability(op, i, m, - total_short_unary_priority, - total_long_unary_priority, - total_binary_priority, - result_cache) - * operatorProbability(op, k - 1 - i, n - m - 1, - total_short_unary_priority, - total_long_unary_priority, - total_binary_priority, - result_cache); - } - result += static_cast(priority) * r; - result /= static_cast(n - 2); - } - - result += static_cast(p1) - * operatorProbability(op, k, n - 1, - total_short_unary_priority, - total_long_unary_priority, - total_binary_priority, - result_cache); - - result /= static_cast(total_long_unary_priority - + total_binary_priority); - } - - result_cache[op][make_pair(k, n)] = result; - return result; -} diff --git a/lbtt/src/Configuration.h b/lbtt/src/Configuration.h deleted file mode 100644 index e7d9a1b56..000000000 --- a/lbtt/src/Configuration.h +++ /dev/null @@ -1,784 +0,0 @@ -/* - * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 - * Heikki Tauriainen - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#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::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::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 symbol_priority; /* Priorities for LTL - * formula symbols. - */ - - map 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 algorithms; /* A vector containing - * information about the - * algorithms used in - * the tests. - */ - - map 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, double> /* Type definitions for */ - ProbabilityMapElement; /* the result cache used */ - /* for computing the */ - typedef map /* 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 /* 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 -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 */ diff --git a/lbtt/src/DispUtil.cc b/lbtt/src/DispUtil.cc deleted file mode 100644 index 39f0b767f..000000000 --- a/lbtt/src/DispUtil.cc +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 - * Heikki Tauriainen - * - * 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 -#include -#include -#include "LbttAlloc.h" -#include "DispUtil.h" - -/****************************************************************************** - * - * Functions for displaying various statistics during testing. - * - *****************************************************************************/ - -namespace DispUtil -{ - -stack > /* 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(); -} - -} diff --git a/lbtt/src/DispUtil.h b/lbtt/src/DispUtil.h deleted file mode 100644 index 6f42e97d1..000000000 --- a/lbtt/src/DispUtil.h +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 - * Heikki Tauriainen - * - * 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 -#include -#include -#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 */ diff --git a/lbtt/src/EdgeContainer.h b/lbtt/src/EdgeContainer.h deleted file mode 100644 index 954eb8a36..000000000 --- a/lbtt/src/EdgeContainer.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 - * Heikki Tauriainen - * - * 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 -#include "Graph.h" - -typedef ::Graph::EdgeVector GraphEdgeContainer; - -#endif /* !EDGECONTAINER_H */ diff --git a/lbtt/src/Exception.h b/lbtt/src/Exception.h deleted file mode 100644 index 3ab2f3987..000000000 --- a/lbtt/src/Exception.h +++ /dev/null @@ -1,1222 +0,0 @@ -/* - * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 - * Heikki Tauriainen - * - * 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 EXCEPTION_H -#define EXCEPTION_H - -#include -#include -#include -#include -#include - -using namespace std; - -/****************************************************************************** - * - * A base class for the exceptions used in the other modules of the program. - * - *****************************************************************************/ - -class Exception : public exception -{ -public: - Exception(const string& message = ""); /* Constructor. */ - - /* default copy constructor */ - - virtual ~Exception() throw(); /* Destructor. */ - - /* default assignment operator */ - - virtual const char* what() const throw(); /* Returns the exception's - * error message. - */ - - virtual void changeMessage /* Changes the error */ - (const string& new_message); /* message. */ - -private: - string error_message; /* Error message. */ -}; - - - -/****************************************************************************** - * - * A class for reporting of a user break. - * - *****************************************************************************/ - -class UserBreakException : public Exception -{ -public: - UserBreakException /* Constructor. */ - (const string& message = "user break"); - - /* default copy constructor */ - - virtual ~UserBreakException() throw(); /* Destructor. */ - - UserBreakException& /* Assignment operator. */ - operator=(const UserBreakException& e); - - /* `what' inherited from class Exception */ - - /* `changeMessage' inherited from class Exception */ -}; - - - -/****************************************************************************** - * - * A base class for I/O exceptions. - * - *****************************************************************************/ - -class IOException : public Exception -{ -public: - IOException(const string& message = ""); /* Constructor. */ - - /* default copy constructor */ - - virtual ~IOException() throw(); /* Destructor. */ - - IOException& operator=(const IOException& e); /* Assignment operator. */ - - /* `what' inherited from class Exception */ - - /* `changeMessage' inherited from class Exception */ -}; - - - -/****************************************************************************** - * - * An exception class for reporting errors when trying to open a file. - * - *****************************************************************************/ - -class FileOpenException : public IOException -{ -public: - FileOpenException(); /* Default constructor. */ - - FileOpenException(const string& filename); /* Constructor which - * relates the exception's - * error message with a - * given file name. - */ - - /* default copy constructor */ - - ~FileOpenException() throw(); /* Destructor. */ - - FileOpenException& operator= /* Assignment operator. */ - (const FileOpenException& e); - - /* `what' inherited from class IOException */ - - /* `changeMessage' inherited from class IOException */ -}; - - - -/****************************************************************************** - * - * An exception class for reporting errors when trying to create a file. - * - *****************************************************************************/ - -class FileCreationException : public IOException -{ -public: - FileCreationException(); /* Default constructor. */ - - FileCreationException(const string& filename); /* Constructor which - * relates the exception's - * error message with a - * given file name. - */ - - /* default copy constructor */ - - ~FileCreationException() throw(); /* Destructor. */ - - FileCreationException& operator= /* Assignment operator. */ - (const FileCreationException& e); - - /* `what' inherited from class IOException */ - - /* `changeMessage' inherited from class IOException */ -}; - - - -/****************************************************************************** - * - * An exception class for reporting errors when reading a file. - * - *****************************************************************************/ - -class FileReadException : public IOException -{ -public: - FileReadException(); /* Default constructor. */ - - FileReadException /* Constructor which */ - (const string& filename, /* relates the */ - const string& details = ""); /* exception's error - * message with a given - * file, including a - * possible explanation - * for the error in the - * message. - */ - - /* default copy constructor */ - - ~FileReadException() throw(); /* Destructor. */ - - FileReadException& operator= /* Assignment operator. */ - (const FileReadException& e); - - /* `what' inherited from class IOException */ - - /* `changeMessage' inherited from class IOException */ -}; - - - -/****************************************************************************** - * - * An exception class for reporting errors when writing to a file. - * - *****************************************************************************/ - -class FileWriteException : public IOException -{ -public: - FileWriteException(); /* Default constructor. */ - - FileWriteException /* Constructor which */ - (const string& filename, /* relates the */ - const string& details = ""); /* exception's error - * message with a given - * file, including a - * possible explanation - * for the error in the - * message. - */ - - /* default copy constructor */ - - ~FileWriteException() throw(); /* Destructor. */ - - FileWriteException& operator= /* Assignment operator. */ - (const FileWriteException& e); - - /* `what' inherited from class IOException */ - - /* `changeMessage' inherited from class IOException */ -}; - - - -/****************************************************************************** - * - * An exception class for reporting errors when trying to execute an external - * program. - * - *****************************************************************************/ - -class ExecFailedException : public IOException -{ -public: - ExecFailedException(); /* Default constructor. */ - - ExecFailedException(const string& filename); /* Constructor which - * relates the exception's - * error message with a - * given file name. - */ - - /* default copy constructor */ - - ~ExecFailedException() throw(); /* Destructor. */ - - ExecFailedException& operator= /* Assignment operator. */ - (const ExecFailedException& e); - - /* `what' inherited from class IOException */ - - /* `changeMessage' inherited from class IOException */ -}; - - - -/****************************************************************************** - * - * A wrapper class for performing `guarded' input from a regular stream using - * the >> operator for reading the stream. If the input operation fails, an - * exception is thrown. - * - * (This class is required to make `guarded' input from regular streams - * possible with (at least) the GNU Standard C++ Library which does not fully - * support the ANSI C++ standard.) - * - *****************************************************************************/ - -class Exceptional_istream -{ -public: - Exceptional_istream /* Constructor. */ - (istream *istr, - ios::iostate mask = ios::goodbit); - - /* default copy constructor */ - - ~Exceptional_istream(); /* Destructor. */ - - /* default assignment operator */ - - template /* Operator for reading */ - Exceptional_istream &operator>>(T &t); /* from the stream. */ - - Exceptional_istream& get(istream::char_type& C); /* Reads a character from - * the stream. - */ - - Exceptional_istream& read /* Reads a given number */ - (istream::char_type* buffer, streamsize count); /* of characters from - * the stream into a - * buffer. - */ - - operator istream&(); /* Casts the exception- - * aware input stream into - * a regular input stream. - */ - -private: - istream* stream; /* A pointer to the - * `regular' input stream - * with which the object is - * associated. - */ - - ios::iostate exception_mask; /* Bit mask which - * determines when to throw - * an exception. - */ -}; - - - -/****************************************************************************** - * - * A wrapper class for performing `guarded' output to a regular stream using - * the << operator for writing to the stream. If the output operation fails, an - * exception is thrown. - * - * (This class is required to make `guarded' output from regular streams - * possible with (at least) the GNU Standard C++ Library which does not fully - * support the ANSI C++ standard.) - * - *****************************************************************************/ - -class Exceptional_ostream -{ -public: - Exceptional_ostream /* Constructor. */ - (ostream* ostr, - ios::iostate mask = ios::goodbit); - - /* default copy constructor */ - - ~Exceptional_ostream(); /* Destructor. */ - - /* default assignment operator */ - - template /* Operator for writing */ - Exceptional_ostream& operator<<(const T& t); /* to the stream. */ - - Exceptional_ostream& flush(); /* Flushes the stream. */ - - operator ostream&(); /* Casts the exception- - * aware output stream into - * a regular output stream. - */ - -private: - ostream* stream; /* A pointer to the - * `regular' output stream - * with which the object is - * associated. - */ - - ios::iostate exception_mask; /* Bit mask which - * determines when to throw - * an exception. - */ -}; - - - -/****************************************************************************** - * - * Inline function definitions for class Exception. - * - *****************************************************************************/ - -/* ========================================================================= */ -inline Exception::Exception(const string& message) : - error_message(message) -/* ---------------------------------------------------------------------------- - * - * Description: Constructor for class Exception. Creates a new exception - * object, initializing it with a given error message. - * - * Argument: message -- An error message. The message defaults to the - * empty string if this argument is not given. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -inline Exception::~Exception() throw() -/* ---------------------------------------------------------------------------- - * - * Description: Destructor for class Exception. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -inline const char* Exception::what() const throw() -/* ---------------------------------------------------------------------------- - * - * Description: Tells the Exception's error message. - * - * Arguments: None. - * - * Returns: The error message as a C-style string. - * - * ------------------------------------------------------------------------- */ -{ - return error_message.c_str(); -} - -/* ========================================================================= */ -inline void Exception::changeMessage(const string& new_message) -/* ---------------------------------------------------------------------------- - * - * Description: Changes the Exception's error message. - * - * Argument: new_message -- A replacement error message. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - error_message = new_message; -} - - - -/****************************************************************************** - * - * Inline function definitions for class UserBreakException. - * - *****************************************************************************/ - -/* ========================================================================= */ -inline UserBreakException::UserBreakException(const string& message) : - Exception(message) -/* ---------------------------------------------------------------------------- - * - * Description: Constructor for class UserBreakException. Creates a new - * UserBreakException object and initializes it with an error - * message. - * - * Argument: message -- An error message. The message defaults to the - * string `User break.' if no alternative message - * is given. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -inline UserBreakException::~UserBreakException() throw() -/* ---------------------------------------------------------------------------- - * - * Description: Destructor for class UserBreakException. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -inline UserBreakException& UserBreakException::operator= - (const UserBreakException& e) -/* ---------------------------------------------------------------------------- - * - * Descrption: Assignment operator for class UserBreakException. Assigns the - * value of another UserBreakException to `this' one. - * - * Argument: e -- A reference to a constant UserBreakException. - * - * Returns: A reference to the object assigned to. - * - * ------------------------------------------------------------------------- */ -{ - Exception::operator=(e); - return *this; -} - - - -/****************************************************************************** - * - * Inline function definitions for class IOException. - * - *****************************************************************************/ - -/* ========================================================================= */ -inline IOException::IOException(const string& message) : - Exception(message) -/* ---------------------------------------------------------------------------- - * - * Description: Constructor for class IOException. Creates a new IOException - * object and initializes it with an error message. - * - * Argument: message -- An error message. The message defaults to the - * empty string if the argument is not given. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -inline IOException::~IOException() throw() -/* ---------------------------------------------------------------------------- - * - * Description: Destructor for class IOException. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -inline IOException& IOException::operator=(const IOException& e) -/* ---------------------------------------------------------------------------- - * - * Descrption: Assignment operator for class IOException. Assigns the value - * of another IOException to `this' one. - * - * Argument: e -- A reference to a constant IOException. - * - * Returns: A reference to the object assigned to. - * - * ------------------------------------------------------------------------- */ -{ - Exception::operator=(e); - return *this; -} - - - -/****************************************************************************** - * - * Inline function definitions for class FileOpenException. - * - *****************************************************************************/ - -/* ========================================================================= */ -inline FileOpenException::FileOpenException() : - IOException("file open error") -/* ---------------------------------------------------------------------------- - * - * Description: Default constructor for class FileOpenException. Creates a - * new FileOpenException object and initializes it with a - * generic error message `File open error.' - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -inline FileOpenException::FileOpenException(const string& filename) : - IOException("error opening " + filename) -/* ---------------------------------------------------------------------------- - * - * Description: Constructor for class FileOpenException. This constructor - * relates the exception's error message with a given file name. - * - * Argument: filename -- A reference to a constant string (the file - * name). - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -inline FileOpenException::~FileOpenException() throw() -/* ---------------------------------------------------------------------------- - * - * Description: Destructor for class FileOpenException. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -inline FileOpenException& FileOpenException::operator= - (const FileOpenException& e) -/* ---------------------------------------------------------------------------- - * - * Description: Assignment operator for class FileOpenException. Assigns the - * `value' of another FileOpenException to `this' one. - * - * Argument: e -- A reference to a constant FileOpenException object. - * - * Returns: A reference to the object assigned to. - * - * ------------------------------------------------------------------------- */ -{ - IOException::operator=(e); - return *this; -} - - - -/****************************************************************************** - * - * Inline function definitions for class FileCreationException. - * - *****************************************************************************/ - -/* ========================================================================= */ -inline FileCreationException::FileCreationException() : - IOException("file creation error") -/* ---------------------------------------------------------------------------- - * - * Description: Default constructor for class FileCreationException. Creates - * a new FileCreationException, initializing the error message - * to `File creation error.' - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -inline FileCreationException::FileCreationException(const string& filename) : - IOException("unable to create " + filename) -/* ---------------------------------------------------------------------------- - * - * Description: Constructor for class FileCreationException. This constructor - * relates the exception's error message with a given file name. - * - * Argument: filename -- A reference to a constant string (the file - * name). - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -inline FileCreationException::~FileCreationException() throw() -/* ---------------------------------------------------------------------------- - * - * Description: Destructor for class FileCreationException. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -inline FileCreationException& FileCreationException::operator= - (const FileCreationException& e) -/* ---------------------------------------------------------------------------- - * - * Description: Assignment operator for class FileCreationException. Assigns - * the `value' of another FileCreationException to `this' one. - * - * Argument: e -- A reference to a constant FileCreationException. - * - * Returns: A reference to the object assigned to. - * - * ------------------------------------------------------------------------- */ -{ - IOException::operator=(e); - return *this; -} - - - -/****************************************************************************** - * - * Inline function definitions for class FileReadException. - * - *****************************************************************************/ - -/* ========================================================================= */ -inline FileReadException::FileReadException() : - IOException("error reading file") -/* ---------------------------------------------------------------------------- - * - * Description: Default constructor for class FileReadException. Creates a - * new FileReadException object and initializes it with the - * error message `Error reading file.' - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -inline FileReadException::FileReadException - (const string& filename, const string& details) : - IOException("error reading " + filename - + string(details.empty() ? "" : " " + details)) -/* ---------------------------------------------------------------------------- - * - * Description: Constructor for class FileReadException. This constructor - * relates the exception's error message to a given file name. - * The error message can also include an explanation for the - * error. - * - * Arguments: filename -- A reference to a constant string (the file - * name). - * details -- Explanation for the error (defaults to the - * empty string if not specified). - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -inline FileReadException::~FileReadException() throw() -/* ---------------------------------------------------------------------------- - * - * Description: Destructor for class FileReadException. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -inline FileReadException& FileReadException::operator= - (const FileReadException& e) -/* ---------------------------------------------------------------------------- - * - * Description: Assignment operator for class FileReadException. Assigns the - * `value' of another FileReadException to `this' one. - * - * Argument: e -- A reference to a constant FileReadException. - * - * Returns: A reference to the object assigned to. - * - * ------------------------------------------------------------------------- */ -{ - IOException::operator=(e); - return *this; -} - - - -/****************************************************************************** - * - * Inline function definitions for class FileWriteException. - * - *****************************************************************************/ - -/* ========================================================================= */ -inline FileWriteException::FileWriteException() : - IOException("error writing to file") -/* ---------------------------------------------------------------------------- - * - * Description: Default constructor for class FileWriteException. Creates a - * new FileWriteException object and initializes it with the - * error message `Error writing to file.' - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -inline FileWriteException::FileWriteException - (const string& filename, const string& details) : - IOException("error writing to " + filename - + string(details.empty() ? "" : " " + details)) -/* ---------------------------------------------------------------------------- - * - * Description: Constructor for class FileWriteException. This constructor - * relates the exception's error message to a given file name. - * The error message can also include an explanation for the - * error. - * - * Arguments: filename -- A reference to a constant string (the file - * name). - * details -- Explanation for the error (defaults to the - * empty string if not specified). - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -inline FileWriteException::~FileWriteException() throw() -/* ---------------------------------------------------------------------------- - * - * Description: Destructor for class FileWriteException. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -inline FileWriteException& FileWriteException::operator= - (const FileWriteException& e) -/* ---------------------------------------------------------------------------- - * - * Description: Assignment operator for class FileWriteException. Assigns the - * `value' of another FileWriteException to `this' one. - * - * Argument: e -- A reference to a constant FileWriteException. - * - * Returns: A reference to the object assigned to. - * - * ------------------------------------------------------------------------- */ -{ - IOException::operator=(e); - return *this; -} - - - -/****************************************************************************** - * - * Inline function definitions for class ExecFailedException. - * - *****************************************************************************/ - -/* ========================================================================= */ -inline ExecFailedException::ExecFailedException() : - IOException("program execution failed") -/* ---------------------------------------------------------------------------- - * - * Description: Default constructor for class ExecFailedException. Creates a - * new ExecFailedException object and initializes it with the - * error message `Program execution failed.' - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -inline ExecFailedException::ExecFailedException(const string& filename) : - IOException("execution of `" + filename + "' failed") -/* ---------------------------------------------------------------------------- - * - * Description: Constructor for class ExecFailedException. This constructor - * relates the exception's error message to a given file name. - * - * Argument: filename -- A reference to a constant string (the file - * name). - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -inline ExecFailedException::~ExecFailedException() throw() -/* ---------------------------------------------------------------------------- - * - * Description: Destructor for class ExecFailedException. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -inline ExecFailedException& ExecFailedException::operator= - (const ExecFailedException& e) -/* ---------------------------------------------------------------------------- - * - * Description: Assignment operator for class ExecFailedException. Assigns - * the `value' of another ExecFailedException object to `this' - * one. - * - * Argument: e -- A reference to a constant ExecFailedException. - * - * Returns: A reference to the object assigned to. - * - * ------------------------------------------------------------------------- */ -{ - IOException::operator=(e); - return *this; -} - - - -/****************************************************************************** - * - * Inline function definitions for class Exceptional_istream. - * - *****************************************************************************/ - -/* ========================================================================= */ -inline Exceptional_istream::Exceptional_istream - (istream* istr, ios::iostate mask) : - stream(istr), exception_mask(mask) -/* ---------------------------------------------------------------------------- - * - * Description: Constructor for class Exceptional_istream. Creates a new - * object providing `guarded' input from a regular stream - * using the >> operator for the input operations. - * - * Arguments: istr -- A pointer to an object of type istream. - * mask -- A bit mask determining when the Exceptional_istream - * should throw exceptions. The most useful constants - * for the bit mask are - * ios::badbit Throw an exception if the input - * stream (after performing an input - * operation) enters a state in which - * the call to bad() would return - * true. - * ios::failbit Throw an exception if the input - * stream (after performing an input - * operation) enters a state in which - * the call to fail() would return - * true. - * ios::eofbit Throw an exception if the input - * stream (after performing an input - * operation) enters a state in which - * the call to eof() would return - * true. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -inline Exceptional_istream::~Exceptional_istream() -/* ---------------------------------------------------------------------------- - * - * Description: Destructor for class Exceptional_istream. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -inline Exceptional_istream& Exceptional_istream::get(istream::char_type& c) -/* ---------------------------------------------------------------------------- - * - * Description: Reads a character from the input stream. - * - * Argument: c -- A reference to a character to extract. - * - * Returns: A reference to the stream. - * - * ------------------------------------------------------------------------- */ -{ - stream->get(c); - if (stream->rdstate() & exception_mask) - throw IOException("error reading from stream"); - - return *this; -} - -/* ========================================================================= */ -inline Exceptional_istream& Exceptional_istream::read - (istream::char_type* buffer, streamsize count) -/* ---------------------------------------------------------------------------- - * - * Description: Reads a given number of characters from the stream into a - * buffer. - * - * Arguments: buffer -- A pointer to the buffer. - * count -- Number of characters to read. - * - * Returns: A reference to the stream. - * - * ------------------------------------------------------------------------- */ -{ - stream->read(buffer, count); - if (stream->rdstate() & exception_mask) - throw IOException("error reading from stream"); - - return *this; -} - -/* ========================================================================= */ -inline Exceptional_istream::operator istream&() -/* ---------------------------------------------------------------------------- - * - * Description: Casts the exception-aware input stream into a regular input - * stream. - * - * Arguments: None. - * - * Returns: A reference to the input stream associated with the object. - * - * ------------------------------------------------------------------------- */ -{ - return *stream; -} - - - -/****************************************************************************** - * - * Template function definitions for class Exceptional_istream. - * - *****************************************************************************/ - -/* ========================================================================= */ -template -Exceptional_istream& Exceptional_istream::operator>>(T& t) -/* ---------------------------------------------------------------------------- - * - * Description: Input operator for reading from a stream. If the read - * operation puts the stream into an undesirable state, an - * exception will be thrown. - * - * Arguments: t -- A reference to an object which will store the value - * read. - * - * Returns: A reference to the Exceptional_istream object (to support - * chaining of the >> operators). - * - * ------------------------------------------------------------------------- */ -{ - *stream >> t; - if (stream->rdstate() & exception_mask) - throw IOException("error reading from stream"); - - return *this; -} - - - -/****************************************************************************** - * - * Inline function definitions for class Exceptional_ostream. - * - *****************************************************************************/ - -/* ========================================================================= */ -inline Exceptional_ostream::Exceptional_ostream - (ostream* ostr, ios::iostate mask) : - stream(ostr), exception_mask(mask) -/* ---------------------------------------------------------------------------- - * - * Description: Constructor for class Exceptional_ostream. Creates a new - * object providing `guarded' output into a regular stream - * using the << operator for the output operations. - * - * Arguments: ostr -- A pointer to an object of type ostream. - * mask -- A bit mask determining when the Exceptional_ostream - * should throw exceptions. The most useful constants - * for the bit mask are - * ios::badbit Throw an exception if the output - * stream (after performing an output - * operation) enters a state in which - * the call to bad() would return - * true. - * ios::failbit Throw an exception if the output - * stream (after performing an output - * operation) enters a state in which - * the call to fail() would return - * true. - * ios::eofbit Throw an exception if the output - * stream (after performing an output - * operation) enters a state in which - * the call to eof() would return - * true. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -inline Exceptional_ostream::~Exceptional_ostream() -/* ---------------------------------------------------------------------------- - * - * Description: Destructor for class Exceptional_ostream. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -inline Exceptional_ostream::operator ostream&() -/* ---------------------------------------------------------------------------- - * - * Description: Casts the exception-aware output stream into a regular output - * stream. - * - * Arguments: None. - * - * Returns: A reference to the input output associated with the object. - * - * ------------------------------------------------------------------------- */ -{ - return *stream; -} - -/* ========================================================================= */ -inline Exceptional_ostream& Exceptional_ostream::flush() -/* ---------------------------------------------------------------------------- - * - * Description: Flushes an Exceptional_ostream. - * - * Arguments: None. - * - * Returns: A reference to the Exceptional_ostream. - * - * ------------------------------------------------------------------------- */ -{ - stream->flush(); - if (stream->rdstate() & exception_mask) - throw IOException("error writing to stream"); - - return *this; -} - - - -/****************************************************************************** - * - * Template function definitions for class Exceptional_ostream. - * - *****************************************************************************/ - -/* ========================================================================= */ -template -Exceptional_ostream& Exceptional_ostream::operator<<(const T& t) -/* ---------------------------------------------------------------------------- - * - * Description: Output operator for writing into a stream. If the write - * operation puts the stream into an undesirable state, an - * exception will be thrown. - * - * Arguments: t -- A reference to a constant object which is to be - * written into the stream. - * - * Returns: A reference to the Exceptional_ostream object (to support - * chaining of the << operators). - * - * ------------------------------------------------------------------------- */ -{ - *stream << t; - if (stream->rdstate() & exception_mask) - throw IOException("error writing to stream"); - - return *this; -} - - - -#endif /* !EXCEPTION_H */ diff --git a/lbtt/src/ExternalTranslator.cc b/lbtt/src/ExternalTranslator.cc deleted file mode 100644 index 60cd80b9b..000000000 --- a/lbtt/src/ExternalTranslator.cc +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 - * Heikki Tauriainen - * - * 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 -#include -#include -#include -#include -#include -#ifdef HAVE_FCNTL_H -#include -#endif /* HAVE_FCNTL_H */ -#ifdef HAVE_UNISTD_H -#include -#endif /* HAVE_UNISTD_H */ -#include -#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); -} diff --git a/lbtt/src/ExternalTranslator.h b/lbtt/src/ExternalTranslator.h deleted file mode 100644 index 758ea67fe..000000000 --- a/lbtt/src/ExternalTranslator.h +++ /dev/null @@ -1,309 +0,0 @@ -/* - * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 - * Heikki Tauriainen - * - * 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 -#include -#include -#include -#ifdef HAVE_SSTREAM -#include -#else -#include -#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 > /* 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 */ diff --git a/lbtt/src/FormulaRandomizer.cc b/lbtt/src/FormulaRandomizer.cc deleted file mode 100644 index 964360c1b..000000000 --- a/lbtt/src/FormulaRandomizer.cc +++ /dev/null @@ -1,229 +0,0 @@ -/* - * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 - * Heikki Tauriainen - * - * 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 -#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::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 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; -} - -} diff --git a/lbtt/src/FormulaRandomizer.h b/lbtt/src/FormulaRandomizer.h deleted file mode 100644 index 915625e58..000000000 --- a/lbtt/src/FormulaRandomizer.h +++ /dev/null @@ -1,329 +0,0 @@ -/* - * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 - * Heikki Tauriainen - * - * 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 -#include -#include -#include -#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& /* Get the numbers of */ - propositionStatistics() const; /* different atomic - * propositions - * generated since the - * last call to `reset'. - */ - - const map& /* 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 IntegerPair; - - vector /* Operand symbols and */ - propositional_symbol_priorities; /* their priorities in - * random formulae. - */ - - vector short_formula_operators; /* Operators and their - * priorities in random - * formulae of size two. - */ - - vector 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 /* Number of different */ - proposition_statistics; /* atomic propositions - * generated since the - * last call to `reset' - */ - - map 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& -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& -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 */ diff --git a/lbtt/src/FormulaWriter.h b/lbtt/src/FormulaWriter.h deleted file mode 100644 index feaf2121a..000000000 --- a/lbtt/src/FormulaWriter.h +++ /dev/null @@ -1,450 +0,0 @@ -/* - * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 - * Heikki Tauriainen - * - * 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 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 -class ConstantWriter -{ -public: - static void write(Exceptional_ostream& estream); /* Implements the write */ -}; /* operation. */ - - - -/****************************************************************************** - * - * Template class for printing unary operators. - * - *****************************************************************************/ - -template -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 -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 -class BinaryOperatorInfixWriter -{ -public: - static void write /* Implements the write */ - (Exceptional_ostream& estream, int operand); /* operation. */ -}; - - - -/****************************************************************************** - * - * Inline function definitions for template class FormulaWriter. - * - *****************************************************************************/ - -/* ========================================================================= */ -template -inline FormulaWriter:: -FormulaWriter(Exceptional_ostream& stream) : - estream(stream) -/* ---------------------------------------------------------------------------- - * - * Description: Constructor for class FormulaWriter. - * - * Arguments: stream -- A reference to an exception-aware output - * stream. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -template -inline FormulaWriter:: -~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 -inline void ConstantWriter::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 -inline void UnaryOperatorWriter::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 -inline void BinaryOperatorPrefixWriter::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 -inline void BinaryOperatorInfixWriter::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 -void FormulaWriter:: -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(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 */ diff --git a/lbtt/src/Graph.h.in b/lbtt/src/Graph.h.in deleted file mode 100644 index 01028c3a6..000000000 --- a/lbtt/src/Graph.h.in +++ /dev/null @@ -1,2028 +0,0 @@ -/* - * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 - * Heikki Tauriainen - * - * 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 GRAPH_H -#define GRAPH_H - -#include -#include -#include -#include -#include -#include - -#ifdef HAVE_SLIST -@INCLUDE_SLIST_HEADER@ -using SLIST_NAMESPACE::slist; -#endif /* HAVE_SLIST */ - -#include -#include -#include "LbttAlloc.h" -#include "BitArray.h" -#include "Exception.h" - -using namespace std; - -namespace Graph -{ - -/* - * Output formats for printing a graph, its edges or nodes. All output - * functions for these objects will accept a parameter `fmt' which can be - * either of these constants (and defaults to NORMAL). - * `NORMAL' corresponds to a plain text description of the printed object. - * `DOT' corresponds to the format recognized by the tool `dot' (a tool - * for displaying graphs graphically), so this format can be used - * for generating input files for the tool. - */ - -enum GraphOutputFormat {NORMAL, DOT}; - - - -class BuchiAutomaton; -class StateSpace; -class ProductAutomaton; - - - -/****************************************************************************** - * - * A template base class for directed graphs. The template parameter specifies - * a class that will be used for storing the collection of edges beginning at - * the nodes of the graph. That is, each graph node will include a container - * (an object of the given class) storing all the edges beginning at the node. - * - * Different containers can be used to optimize the efficiency of different - * graph algorithms. For example, if the edges are often accessed randomly, a - * container which supports fast searching of any edge in the container may - * be useful: on the other hand, algorithms which only need to go through - * all the edges in some order will benefit from a more simple container since - * this container may consume less memory per container element. - * - * Definitions are provided for the following container classes: - * EdgeList -- Uses the STL `list' class (a doubly linked list) to store - * the edges. - * EdgeVector -- Uses the STL `vector' class to store the edges. - * EdgeSet -- Uses the STL `set' class to store the edges. Important - * note: This container will not allow multiple edges - * between a pair of nodes -- use EdgeMultiSet instead. - * EdgeMultiSet -- Uses the STL `multiset' class to store the edges. - * - * In addition, if using the SGI STL implementation, an additional container - * class `EdgeSlist' is available. This class is based on the `slist' (a - * singly linked list) container included in the SGI STL implementation. - * - * Any class used as a container (`EdgeContainer') must be able to hold - * objects of type Graph::Edge* and must support the following - * interface: - * - * Default constructor which can be called without arguments. - * - * EdgeContainer::size_type - * Data type able to represent the maximum number of elements - * that can be stored in the container. - * - * EdgeContainer::size_type size() - * Returns the number of elements currently stored in the - * containers. - * - * bool empty() - * Tells whether the container is currently empty. - * - * void clear() - * Makes the container empty. - * - * EdgeContainer::iterator - * EdgeContainer::const_iterator - * Input iterators that can be used to traverse through the - * elements of the container. The iterators must support - * increment and dereferencing operations. However, support for - * changing the container elements through the iterator is not - * required. - * - * const_iterator EdgeContainer::begin() - * Returns a const_iterator pointing to the first element in the - * container. - * - * iterator EdgeContainer::begin() - * Returns an iterator pointing to the last element in the - * container. - * - * const_iterator EdgeContainer::end() - * Returns a const_iterator pointing to the end of the container. - * - * iterator EdgeContainer::end() - * Returns an iterator pointing to the end of the container. - * - * const_iterator find(const Graph::Edge*) - * Finds an element of a given value in the container and returns - * a const_iterator pointing to it (or end() if the element is - * not found in the container). - * - * Very important note: - * In order for all the algorithms provided in this class to - * work correctly, searching an element in the container must - * be done by comparing the actual objects pointed to by the - * elements of the container, _not_ the pointers itself. - * - * The class Graph::Edge already provides two - * classes for this purpose: - * 1. Graph::Edge::ptr_less defines a `less - * than' relation between two pointers to - * Graph::Edges - * 2. Graph::Edge::ptr_equal defines an - * `equality' relation between two pointers to - * Graph::Edges. - * - * See the comments on these classes (and the provided - * container class examples) for information on how to use - * them. - * - * iterator find(const Graph::Edge*) - * Finds an element of a given value in the container and returns - * a iterator pointing to it (or end() if the element is not - * found in the container). - * - * insert(const Graph::Edge*) - * Inserts an edge into the container. - * - * erase(iterator pos) - * Removes the element pointed by the iterator `pos' from the - * container. - * - *****************************************************************************/ - -template -class Graph -{ -public: - - /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - - class Edge; /* A class for representing - * edges between graph - * nodes. - */ - - class Node; /* A class for representing - * graph nodes. - */ - - class PathElement; /* A class for representing - * (node, edge) pairs - */ - - /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -protected: - vector nodes; /* Nodes of the graph. - * Derived classes can - * access this vector - * directly. - */ - -public: - typedef typename vector::size_type /* Type definition for */ - size_type; /* the size of the - * graph. The size can - * be no greater than - * the maximum size of - * the vector containing - * the graph nodes. - */ - - typedef EdgeContainer EdgeContainerType; /* Type definition for - * containers of graph - * edges. - */ - - typedef deque Path; /* Type definition for - * paths in a graph. - */ - - typedef pair StateIdPair; /* Type definition for a - * pair of state - * identifiers in a graph. - */ - - explicit Graph /* Default constructor. */ - (const size_type initial_number_of_nodes = 0); - - Graph(const Graph& graph); /* Copy constructor. */ - - virtual ~Graph(); /* Destructor. */ - - Graph& operator=(const Graph& graph); /* Assignment operator. */ - - virtual Node& operator[](const size_type index) /* Indexing operator */ - const; /* (for referencing the - * nodes of the graph). - * This function will - * not check whether the - * given index is in a - * valid range. - */ - - virtual Node& node(const size_type index) const; /* Alternative way for - * referencing the graph - * nodes. This function - * also checks the range of - * the argument. - */ - - size_type size() const; /* Returns the number of - * nodes in the graph. - */ - - bool empty() const; /* Tests whether the graph - * is empty. - */ - - virtual void clear(); /* Makes the graph empty. - */ - - virtual size_type expand /* Inserts nodes to the */ - (size_type node_count = 1); /* graph. */ - - virtual void connect /* Inserts an edge */ - (const size_type father, /* between two nodes. */ - const size_type child); - - virtual void disconnect /* Removes an edge from */ - (const size_type father, /* between two nodes. */ - const size_type child); - - virtual bool connected /* Tests whether two */ - (const size_type father, /* nodes are connected */ - const size_type child) const; /* with an edge. */ - - virtual pair /* Returns the number of */ - stats() const; /* nodes and edges in - * the graph. - */ - - virtual pair /* Returns the number of */ - subgraphStats(const size_type index) const; /* nodes and edges in a - * connected subgraph of - * the graph. - */ - - virtual void print /* Prints the contents */ - (ostream& stream = cout, /* of the graph in */ - const int indent = 0, /* various formats */ - const GraphOutputFormat fmt = NORMAL) const; /* (determined by the - * `fmt' argument which - * can have the values - * NORMAL or DOT). - */ -}; - - - -/****************************************************************************** - * - * A template class for representing the directed edges between graph nodes. - * - *****************************************************************************/ - -template -class Graph::Edge -{ -public: - /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - - class ptr_equal /* Class for a function */ - { /* object defining an */ - public: /* equality relation */ - bool operator() /* between pointers to */ - (const Edge* edge_1, const Edge* edge_2) /* Edges. (Used with */ - const; /* container */ - }; /* algorithms.) */ - - class ptr_less /* Class for a function */ - { /* object defining a */ - public: /* `less than' relation */ - bool operator() /* between pointers to */ - (const Edge* edge_1, const Edge* edge_2) /* Edges. (Used with */ - const; /* container */ - }; /* algorithms.) */ - - /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - - Edge /* Constructor. */ - (const Graph::size_type target); - - /* default copy constructor */ - - virtual ~Edge(); /* Destructor. */ - - /* default assignment operator */ - - size_type targetNode() const; /* Returns the index of */ - /* the target node of - * the directed edge. - */ - - virtual void print /* Writes information */ - (ostream& stream = cout, /* about the edge to a */ - const int indent = 0, /* stream in various */ - const GraphOutputFormat fmt = NORMAL) const; /* formats (determined - * by the `fmt' - * argument). - */ - - friend class ptr_equal; - friend class ptr_less; - -protected: - virtual bool operator==(const Edge& edge) const; /* Equality relation - * between two edges. Used - * for sorting Edges in an - * STL container. - */ - - virtual bool operator<(const Edge& edge) const; /* `Less than' relation - * between two edges. Used - * for sorting Edges in an - * STL container. - */ - -private: - size_type target_node; /* Identifier of the edge's - * target node. - */ -}; - - - -/****************************************************************************** - * - * A template class for representing graph nodes. - * - *****************************************************************************/ - -template -class Graph::Node -{ -public: - Node(); /* Constructor. */ - - Node(const Node& node); /* Copy constructor. */ - - virtual ~Node(); /* Destructor. */ - - Node& operator=(const Node& node); /* Assignment operator. */ - - const EdgeContainer& edges() const; /* Returns the container of - * edges beginning at the - * node. - */ - - virtual void print /* Writes information */ - (ostream& stream = cout, /* about the node to a */ - const int indent = 0, /* stream in various */ - const GraphOutputFormat fmt = NORMAL) const; /* formats (determined - * by the `fmt' - * argument). - */ - -protected: - friend class Graph; - friend class BuchiAutomaton; - friend class StateSpace; - friend class ProductAutomaton; - - EdgeContainer outgoing_edges; /* Container of edges - * beginning at the node. - */ -}; - - - -/****************************************************************************** - * - * A template class for representing (node identifier, edge) pairs in a graph. - * - *****************************************************************************/ - -template -class Graph::PathElement -{ -public: - explicit PathElement /* Constructors. */ - (const typename Graph::size_type - n, - const typename Graph::Edge* - e = 0); - - PathElement - (const typename Graph::size_type - n, - const typename Graph::Edge& e); - - /* default copy constructor */ - - ~PathElement(); /* Destructor. */ - - /* default assignment operator */ - - size_type node() const; /* Returns the identifier - * of the node associated - * with the path element. - */ - - bool hasEdge() const; /* Tells whether there is - * an edge associated with - * the path element. - */ - - const Edge& edge() const; /* Returns the edge - * associated with the - * path element. - */ - -private: - typename Graph::size_type node_id; /* Identifier of the node - * associated with the path - * element. - */ - - const typename Graph::Edge* /* Pointer to the edge */ - edge_pointer; /* associated with the - * path element. - */ -}; - - - -/****************************************************************************** - * - * An exception class for reporting errors when indexing graph nodes. - * - *****************************************************************************/ - -class NodeIndexException : public Exception -{ -public: - NodeIndexException(); /* Default constructor. */ - - /* default copy constructor */ - - ~NodeIndexException() throw(); /* Destructor. */ - - NodeIndexException& operator= /* Assignment operator. */ - (const NodeIndexException& e); - - /* `what' inherited from class Exception */ -}; - - - -/****************************************************************************** - * - * An edge container class based on the basic STL container class `list', a - * doubly linked list. - * - *****************************************************************************/ - -class EdgeList : public list::Edge*> -{ -public: - EdgeList(); /* Constructor. */ - - /* default copy constructor */ - - ~EdgeList(); /* Destructor. */ - - /* default assignment operator */ - - void insert(Graph::Edge* edge); /* Inserts an element to - * the end of the list. - */ - - list::Edge*>::const_iterator /* Functions for finding */ - find(const Graph::Edge* edge) const; /* an element in the - * list. - */ - - list::Edge*>::iterator - find(const Graph::Edge* edge); -}; - - - -/****************************************************************************** - * - * An edge container class based on the basic container class `slist' - * (available in SGI STL implementation), a singly linked list. - * - *****************************************************************************/ - -#ifdef HAVE_SLIST - -class EdgeSlist : public slist::Edge*> -{ -public: - EdgeSlist(); /* Constructor. */ - - /* default copy constructor */ - - ~EdgeSlist(); /* Destructor. */ - - /* default assignment operator */ - - void insert(Graph::Edge* edge); /* Inserts an element to - * the beginning of the - * list. - */ - - slist::Edge*>::const_iterator /* Functions for finding */ - find(const Graph::Edge* edge) const; /* an element in the - * list. - */ - - slist::Edge*>::iterator - find(const Graph::Edge* edge); -}; - -#endif /* HAVE_SLIST */ - - - -/****************************************************************************** - * - * An edge container class based on the basic STL container class `vector'. - * - *****************************************************************************/ - -class EdgeVector : public vector::Edge*> -{ -public: - EdgeVector(); /* Constructor. */ - - /* default copy constructor */ - - ~EdgeVector(); /* Destructor. */ - - /* default assignment operator */ - - void insert(Graph::Edge* edge); /* Inserts an element to - * the vector of pointers - * to edges. - */ - - vector::Edge*>::const_iterator /* Functions for finding */ - find(const Graph::Edge* edge) /* an element in the */ - const; /* container. */ - - vector::Edge*>::iterator - find(const Graph::Edge* edge); -}; - - - -/****************************************************************************** - * - * An edge container class based on the basic STL container class `set'. - * - *****************************************************************************/ - -class EdgeSet : public set::Edge*, - Graph::Edge::ptr_less> -{ -}; - - - -/****************************************************************************** - * - * An edge container class based on the basic STL container class `multiset'. - * - *****************************************************************************/ - -class EdgeMultiSet : public multiset::Edge*, - Graph::Edge::ptr_less> -{ -}; - - - -/****************************************************************************** - * - * Inline function definitions for template class Graph. - * - *****************************************************************************/ - -/* ========================================================================= */ -template -inline Graph::~Graph() -/* ---------------------------------------------------------------------------- - * - * Description: Destructor for template class Graph. - * Deallocates the memory reserved for the object. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - clear(); -} - -/* ========================================================================= */ -template -inline typename Graph::Node& Graph::operator[] - (const size_type index) const -/* ---------------------------------------------------------------------------- - * - * Description: Indexing operator for template class Graph. - * Can be used to access single nodes of the graph. This - * function does not perform any range checks on its argument. - * - * Argument: index -- Index of a node. - * - * Returns: A reference to a graph node. - * - * ------------------------------------------------------------------------- */ -{ - return *nodes[index]; -} - -/* ========================================================================= */ -template -inline typename Graph::size_type Graph::size() - const -/* ---------------------------------------------------------------------------- - * - * Description: Returns the number of nodes in the graph. - * - * Arguments: None. - * - * Returns: Number of nodes in the graph. - * - * ------------------------------------------------------------------------- */ -{ - return nodes.size(); -} - -/* ========================================================================= */ -template -inline bool Graph::empty() const -/* ---------------------------------------------------------------------------- - * - * Description: Tests whether the graph is empty. - * - * Arguments: None. - * - * Returns: A truth value. - * - * ------------------------------------------------------------------------- */ -{ - return nodes.empty(); -} - -/* ========================================================================= */ -template -inline ostream& operator<<(ostream& stream, const Graph& graph) -/* ---------------------------------------------------------------------------- - * - * Description: Defines an alternative way for printing a Graph by using the - * << operator. - * - * Arguments: stream -- A reference to an output stream. - * graph -- A reference to a constant graph to be printed. - * - * Returns: A reference to the output stream. - * - * ------------------------------------------------------------------------- */ -{ - graph.print(stream); - return stream; -} - - - -/****************************************************************************** - * - * Function definitions for template class Graph. - * - *****************************************************************************/ - -/* ========================================================================= */ -template -Graph::Graph(const size_type initial_number_of_nodes) : - nodes(initial_number_of_nodes) -/* ---------------------------------------------------------------------------- - * - * Description: Constructor for template class Graph. - * Initializes a new Graph object with a given - * initial size (which can be extended later). - * - * Argument: initial_number_of_nodes -- Initial size of the graph. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - nodes.reserve(initial_number_of_nodes); - - for (typename vector::iterator node = nodes.begin(); - node != nodes.end(); - ++node) - *node = new Node(); -} - -/* ========================================================================= */ -template -Graph::Graph(const Graph& graph) -/* ---------------------------------------------------------------------------- - * - * Description: Copy constructor for template class Graph. - * Initializes a copy of a Graph object. - * - * Argument: graph -- A reference to a constant Graph - * to be copied. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - nodes.reserve(graph.nodes.size()); - for (typename vector::const_iterator node = graph.nodes.begin(); - node != graph.nodes.end(); ++node) - nodes.push_back(new Node(**node)); -} - -/* ========================================================================= */ -template -Graph& Graph::operator= - (const Graph& graph) -/* ---------------------------------------------------------------------------- - * - * Description: Assignment operator for template class Graph. - * Copies a Graph object to another. - * - * Argument: graph -- A reference to the constant Graph - * to be copied. - * - * Returns: A reference to the graph whose contents were changed. - * - * ------------------------------------------------------------------------- */ -{ - if (&graph != this) - { - clear(); - - nodes.reserve(graph.nodes.size()); - for (typename vector::const_iterator node = graph.nodes.begin(); - node != graph.nodes.end(); - ++node) - nodes.push_back(new Node(**node)); - } - - return *this; -} - -/* ========================================================================= */ -template -typename Graph::Node& Graph::node - (const size_type index) const -/* ---------------------------------------------------------------------------- - * - * Description: Function for accessing individual nodes of the graph. This - * function also performs a range check on its argument. - * - * Argument: index -- Index of the node. - * - * Returns: A reference to the node. - * - * ------------------------------------------------------------------------- */ -{ - if (index >= nodes.size()) - throw NodeIndexException(); - - return *nodes[index]; -} - -/* ========================================================================= */ -template -void Graph::clear() -/* ---------------------------------------------------------------------------- - * - * Description: Makes the graph empty. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - for (typename vector::reverse_iterator node = nodes.rbegin(); - node != nodes.rend(); - ++node) - delete *node; - - nodes.clear(); - nodes.reserve(0); -} - -/* ========================================================================= */ -template -typename Graph::size_type Graph::expand - (size_type node_count) -/* ---------------------------------------------------------------------------- - * - * Description: Inserts a given number of nodes to a graph. - * - * Arguments: node_count -- Number of nodes to be inserted. - * - * Returns: The index of the last inserted node. - * - * ------------------------------------------------------------------------- */ -{ - nodes.reserve(nodes.size() + node_count); - - Node* new_node; - - while (node_count > 0) - { - new_node = new Node(); - try - { - nodes.push_back(new_node); - } - catch (...) - { - delete new_node; - throw; - } - node_count--; - } - - return nodes.size() - 1; -} - -/* ========================================================================= */ -template -void Graph::connect - (const size_type father, const size_type child) -/* ---------------------------------------------------------------------------- - * - * Description: Inserts an edge between two nodes of the graph. - * - * Arguments: father -- Source node of the edge. - * child -- Target node of the edge. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - Edge* new_edge(new Edge(child)); - - try - { - nodes[father]->outgoing_edges.insert(new_edge); - } - catch (...) - { - delete new_edge; - throw; - } -} - -/* ========================================================================= */ -template -void Graph::disconnect - (const size_type father, const size_type child) -/* ---------------------------------------------------------------------------- - * - * Description: Removes an edge between two nodes of the graph. - * - * Arguments: father -- Source node of the edge. - * child -- Target node of the edge. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - Edge e(child); - - /* - * Scan the set of the node's outgoing edges for an edge with the given - * target node and remove it if such an edge exists. - */ - - typename EdgeContainer::iterator search_edge - = nodes[father]->outgoing_edges.find(&e); - - if (search_edge != nodes[father]->outgoing_edges.end()) - { - delete *search_edge; - nodes[father]->outgoing_edges.erase(search_edge); - } -} - -/* ========================================================================= */ -template -bool Graph::connected - (const size_type father, const size_type child) const -/* ---------------------------------------------------------------------------- - * - * Description: Tests whether there exists an edge from a given graph node - * to another one. - * - * Arguments: father -- Source node of the edge. - * child -- Target node of the edge. - * - * Returns: A truth value. - * - * ------------------------------------------------------------------------- */ -{ - Edge e(child); - return (nodes[father]->outgoing_edges.find(&e) - != nodes[father]->outgoing_edges.end()); -} - -/* ========================================================================= */ -template -pair::size_type, unsigned long int> -Graph::stats() const -/* ---------------------------------------------------------------------------- - * - * Description: Returns the number of nodes and edges in a graph. - * - * Arguments: None. - * - * Returns: A pair consisting of the number of nodes and the number of - * transitions in the graph. - * - * ------------------------------------------------------------------------- */ -{ - pair result; - - result.first = nodes.size(); - result.second = 0; - - for (typename vector::const_iterator node = nodes.begin(); - node != nodes.end(); ++node) - result.second += (*node)->edges().size(); - - return result; -} - -/* ========================================================================= */ -template -pair::size_type, unsigned long int> -Graph::subgraphStats(const size_type index) const -/* ---------------------------------------------------------------------------- - * - * Description: Computes the number of nodes and edges in some connected - * subgraph of the graph. The subgraph is computed by performing - * a depth-first traversal of a graph component starting from a - * given node (the `root' of the subgraph). - * - * Arguments: index -- Index of the node acting as the `root' of the - * subgraph. - * - * Returns: A pair consisting of the number of nodes and the number of - * transitions in the subgraph. - * - * ------------------------------------------------------------------------- */ -{ - if (empty()) - return make_pair(0, 0); - - const size_type s = nodes.size(); - - if (index >= s) - throw NodeIndexException(); - - stack > unprocessed_nodes; - BitArray visited_nodes(s); - visited_nodes.clear(s); - - unprocessed_nodes.push(index); - visited_nodes.setBit(index); - - size_type current_node, child_node, number_of_subgraph_nodes = 0; - unsigned long int number_of_subgraph_edges = 0; - - while (!unprocessed_nodes.empty()) - { - current_node = unprocessed_nodes.top(); - unprocessed_nodes.pop(); - - ++number_of_subgraph_nodes; - number_of_subgraph_edges += nodes[current_node]->edges().size(); - - for (typename EdgeContainer::const_iterator - edge = nodes[current_node]->edges().begin(); - edge != nodes[current_node]->edges().end(); - ++edge) - { - child_node = (*edge)->targetNode(); - if (!visited_nodes.test(child_node)) - { - unprocessed_nodes.push(child_node); - visited_nodes.setBit(child_node); - } - } - } - - return make_pair(number_of_subgraph_nodes, number_of_subgraph_edges); -} - -/* ========================================================================= */ -template -void Graph::print - (ostream& stream, const int indent, const GraphOutputFormat fmt) const -/* ---------------------------------------------------------------------------- - * - * Description: Writes information about the graph 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 graph 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 graph is empty.\n"; - } - else - { - if (fmt == NORMAL) - { - pair statistics = stats(); - - estream << string(indent, ' ') + "The graph consists of\n" - + string(indent + 4, ' ') - << statistics.first - << " states and\n" + string(indent + 4, ' ') - << statistics.second - << " transitions.\n"; - } - - size_type s = nodes.size(); - for (size_type node = 0; node < s; ++node) - { - estream << string(indent, ' '); - if (fmt == NORMAL) - { - estream << "Node " << node << ":\n"; - nodes[node]->print(stream, indent + 4, fmt); - } - else if (fmt == DOT) - { - typename EdgeContainer::const_iterator edge; - - estream << " n" << node << " [shape=circle,label=\"" << node - << "\",fontsize=12];\n"; - - for (edge = nodes[node]->edges().begin(); - edge != nodes[node]->edges().end(); - ++edge) - { - estream << string(indent + 2, ' ') + 'n' << node; - (*edge)->print(stream, 0, fmt); - estream << ";\n"; - } - } - } - } - - if (fmt == DOT) - estream << string(indent, ' ') + "}\n"; - - estream.flush(); -} - - - -/****************************************************************************** - * - * Inline function definitions for class Graph::Edge. - * - *****************************************************************************/ - -/* ========================================================================= */ -template -inline Graph::Edge::Edge - (const Graph::size_type target) : target_node(target) -/* ---------------------------------------------------------------------------- - * - * Description: Constructor for template class Graph::Edge. - * Creates a new edge and initializes its target node. - * - * Arguments: target -- Identifier of the edge's target node. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -template -inline Graph::Edge::~Edge() -/* ---------------------------------------------------------------------------- - * - * Description: Destructor for template class Graph::Edge. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -template -inline bool Graph::Edge::operator==(const Edge& edge) const -/* ---------------------------------------------------------------------------- - * - * Description: Equality relation for class Graph::Edge. Two - * edges are `equal' if and only if their target nodes have the - * same identifier. - * - * Argument: edge -- A reference to a constant - * Graph::Edge. - * - * Returns: Truth value according to the relationship between the two - * edges. - * - * ------------------------------------------------------------------------- */ -{ - return (target_node == edge.target_node); -} - -/* ========================================================================= */ -template -inline bool Graph::Edge::operator<(const Edge& edge) const -/* ---------------------------------------------------------------------------- - * - * Description: `Less than' relation for class Graph::Edge. An - * edge is `less than' another if and only if the edge's target - * node has a smaller identifier than that of the other edge. - * - * Argument: edge -- A reference to a constant - * Graph::Edge. - * - * Returns: Truth value according to the relationship between the two - * edges. - * - * ------------------------------------------------------------------------- */ -{ - return (target_node < edge.target_node); -} - -/* ========================================================================= */ -template -inline typename Graph::size_type -Graph::Edge::targetNode() const -/* ---------------------------------------------------------------------------- - * - * Description: Returns the identifier of the edge's target node. - * - * Arguments: None. - * - * Returns: Identifier of the target node. - * - * ------------------------------------------------------------------------- */ -{ - return target_node; -} - -/* ========================================================================= */ -template -inline ostream& operator<< - (ostream& stream, const typename Graph::Edge& edge) -/* ---------------------------------------------------------------------------- - * - * Description: Defines an alternative way for printing a - * Graph::Edge by using the << operator. - * - * Arguments: stream -- A reference to an output stream. - * edge -- A reference to a constant edge to be printed. - * - * Returns: A reference to the output stream. - * - * ------------------------------------------------------------------------- */ -{ - edge.print(stream); - return stream; -} - - - -/****************************************************************************** - * - * Function definitions for class Graph::Edge. - * - *****************************************************************************/ - -/* ========================================================================= */ -template -void Graph::Edge::print - (ostream& stream, const int indent, const GraphOutputFormat fmt) const -/* ---------------------------------------------------------------------------- - * - * Description: Writes information about the edge to a stream. - * - * Arguments: stream -- A reference to an output stream. - * indent -- Number of spaces to write before the edge - * description. - * fmt -- Determines the output format of the edge. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - Exceptional_ostream estream(&stream, ios::failbit | ios::badbit); - - if (fmt == NORMAL) - estream << string(indent, ' ') << "Edge to node " << target_node << '\n'; - else if (fmt == DOT) - estream << " -> n" << target_node; - - estream.flush(); -} - - - -/****************************************************************************** - * - * Inline function definitions for class Graph::Edge::ptr_equal. - * - *****************************************************************************/ - -/* ========================================================================= */ -template -inline bool Graph::Edge::ptr_equal::operator() - (const Graph::Edge* edge_1, - const Graph::Edge* edge_2) const -/* ---------------------------------------------------------------------------- - * - * Description: Function to test the `equality' of two pointers to - * Graph::Edges, the other one of which is stored - * in the function object for whom this member function is - * called. - * - * Arguments: edge_1, edge_2 -- Two pointers to constant - * Graph::Edges. - * - * Returns: A truth value according to the result of the equality test. - * - * ------------------------------------------------------------------------- */ -{ - return (*edge_1 == *edge_2); -} - - - -/****************************************************************************** - * - * Inline function definitions for class Graph::Edge::ptr_less. - * - *****************************************************************************/ - -/* ========================================================================= */ -template -inline bool Graph::Edge::ptr_less::operator() - (const Graph::Edge* edge_1, - const Graph::Edge* edge_2) const -/* ---------------------------------------------------------------------------- - * - * Description: Defines a `less than' relation between two pointers to - * Graph::Edges by mapping the relation between - * the pointers to the relation between the objects itself. - * (Used for storing pointers to Edges into a container.) - * - * Arguments: edge_1, edge_2 -- Two pointers to constant - * Graph::Edges. - * - * Returns: Truth value according to the relationship of the two edges - * involved. - * - * ------------------------------------------------------------------------- */ -{ - return (*edge_1 < *edge_2); -} - - - -/****************************************************************************** - * - * Inline function definitions for class Graph::Node. - * - *****************************************************************************/ - -/* ========================================================================= */ -template -inline Graph::Node::Node() -/* ---------------------------------------------------------------------------- - * - * Description: Constructor for class Graph::Node. Creates a - * new node. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -template -inline const EdgeContainer& Graph::Node::edges() const -/* ---------------------------------------------------------------------------- - * - * Description: Returns the set of edges starting from the node. - * - * Arguments: None. - * - * Returns: A reference to the constant container of pointers to the - * edges starting from the node. - * - * ------------------------------------------------------------------------- */ -{ - return outgoing_edges; -} - -/* ========================================================================= */ -template -inline ostream& operator<< - (ostream& stream, const typename Graph::Node& node) -/* ---------------------------------------------------------------------------- - * - * Description: An alternative method for printing a - * Graph::Node object by using the << operator. - * - * Arguments: stream -- A reference to an output stream. - * node -- Node to be printed. - * - * Returns: A reference to the output stream. - * - * ------------------------------------------------------------------------- */ -{ - node.print(stream); - return stream; -} - - - -/****************************************************************************** - * - * Function definitions for class Graph::Node. - * - *****************************************************************************/ - -/* ========================================================================= */ -template -Graph::Node::Node(const Node& node) -/* ---------------------------------------------------------------------------- - * - * Description: Copy constructor for Graph::Node. Initializes - * a copy of a Node. - * - * Argument: node -- A reference to a constant node to be copied. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - typename EdgeContainer::const_iterator edge; - - for (edge = node.outgoing_edges.begin(); edge != node.outgoing_edges.end(); - ++edge) - outgoing_edges.insert(new Edge(**edge)); -} - -/* ========================================================================= */ -template -Graph::Node::~Node() -/* ---------------------------------------------------------------------------- - * - * Description: Destructor for Graph::Node. Deallocates the - * memory reserved by the object. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - typename EdgeContainer::iterator edge; - - for (edge = outgoing_edges.begin(); edge != outgoing_edges.end(); ++edge) - delete *edge; -} - -/* ========================================================================= */ -template -typename Graph::Node& Graph::Node::operator= - (const Graph::Node& node) -/* ---------------------------------------------------------------------------- - * - * Description: Assignment operator for class Graph::Node. - * Assigns a graph node a copy of another one. - * - * Argument: node -- A reference to the constant node to be copied. - * - * Returns: A reference to the graph node whose contents were changed. - * - * ------------------------------------------------------------------------- */ -{ - if (&node != this) - { - typename EdgeContainer::iterator edge; - - for (edge = outgoing_edges.begin(); edge != outgoing_edges.end(); ++edge) - delete *edge; - - outgoing_edges.clear(); - - for (edge = node.outgoing_edges.begin(); edge != node.outgoing_edges.end(); - ++edge) - outgoing_edges.insert(new Edge(**edge)); - } - - return *this; -} - -/* ========================================================================= */ -template -void Graph::Node::print - (ostream& stream, const int indent, const GraphOutputFormat fmt) const -/* ---------------------------------------------------------------------------- - * - * Description: Writes information about a graph node 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 node output format. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - if (fmt == DOT) - return; - - Exceptional_ostream estream(&stream, ios::failbit | ios::badbit); - - if (outgoing_edges.empty()) - estream << string(indent, ' ') + "The node has no successors.\n"; - else - { - typename EdgeContainer::const_iterator edge; - - estream << string(indent, ' ') + "The node has " - << outgoing_edges.size() - << " successor nodes:\n"; - - for (edge = outgoing_edges.begin(); edge != outgoing_edges.end(); ++edge) - (*edge)->print(stream, indent + 4); - } - - estream.flush(); -} - - - -/****************************************************************************** - * - * Inline function definitions for template class - * Graph::PathElement. - * - *****************************************************************************/ - -/* ========================================================================= */ -template -inline Graph::PathElement::PathElement - (const typename Graph::size_type n, - const typename Graph::Edge* e) : - node_id(n), edge_pointer(e) -/* ---------------------------------------------------------------------------- - * - * Description: Constructor for class Graph::PathElement. - * Creates a (node identifier, edge) pair from a node identifier - * and a pointer to an edge. - * - * Arguments: n -- Numeric identifier of a graph node. - * e -- A constant pointer to a graph edge. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -template -inline Graph::PathElement::PathElement - (const typename Graph::size_type n, - const typename Graph::Edge& e) : - node_id(n), edge_pointer(&e) -/* ---------------------------------------------------------------------------- - * - * Description: Constructor for class Graph::PathElement. - * Creates a (node identifier, edge) pair from a node identifier - * and an edge. - * - * Arguments: n -- Numeric identifier of a graph node. - * e -- A constant reference to a graph edge. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -template -inline Graph::PathElement::~PathElement() -/* ---------------------------------------------------------------------------- - * - * Description: Destructor for class Graph::PathElement. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -template -inline typename Graph::size_type -Graph::PathElement::node() const -/* ---------------------------------------------------------------------------- - * - * Description: Returns the identifier of the node associated with a - * Graph::PathElement object. - * - * Arguments: None. - * - * Returns: Identifier of the node associated with the object. - * - * ------------------------------------------------------------------------- */ -{ - return node_id; -} - -/* ========================================================================= */ -template -inline bool Graph::PathElement::hasEdge() const -/* ---------------------------------------------------------------------------- - * - * Description: Tells whether there is an edge associated with a - * Graph::PathElement object. - * - * Arguments: None. - * - * Returns: true iff there is an edge associated with the object. - * - * ------------------------------------------------------------------------- */ -{ - return edge_pointer != 0; -} - -/* ========================================================================= */ -template -inline const typename Graph::Edge& -Graph::PathElement::edge() const -/* ---------------------------------------------------------------------------- - * - * Description: Returns the edge associated with a - * Graph::PathElement object. The function - * assumes that there is such an edge; it is an error to call - * this function for a PathElement object `element' for which - * `element.hasEdge() == false'. - * - * Arguments: None. - * - * Returns: The edge associated with the object. - * - * ------------------------------------------------------------------------- */ -{ - return *edge_pointer; -} - - - -/****************************************************************************** - * - * Inline function definitions for class NodeIndexException. - * - *****************************************************************************/ - -/* ========================================================================= */ -inline NodeIndexException::NodeIndexException() : - Exception("graph node index out of range") -/* ---------------------------------------------------------------------------- - * - * Description: Constructor for class NodeIndexException. Creates a new - * exception object. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -inline NodeIndexException::~NodeIndexException() throw() -/* ---------------------------------------------------------------------------- - * - * Description: Destructor for class NodeIndexException. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -inline NodeIndexException& NodeIndexException::operator= - (const NodeIndexException& e) -/* ---------------------------------------------------------------------------- - * - * Description: Assignment operator for class NodeIndexException. - * - * Arguments: e -- A reference to another NodeIndexException. - * - * Returns: A reference to the assigned exception object. - * - * ------------------------------------------------------------------------- */ -{ - Exception::operator=(e); - return *this; -} - - - -/****************************************************************************** - * - * Inline function definitions for class EdgeList. - * - *****************************************************************************/ - -/* ========================================================================= */ -inline EdgeList::EdgeList() -/* ---------------------------------------------------------------------------- - * - * Description: Constructor for class EdgeList. Creates a new container based - * on doubly linked lists for storing graph edges. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -inline EdgeList::~EdgeList() -/* ---------------------------------------------------------------------------- - * - * Description: Destructor for class EdgeList. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -inline void EdgeList::insert(Graph::Edge* edge) -/* ---------------------------------------------------------------------------- - * - * Description: Inserts a new edge to the end of the list. - * - * Argument: edge -- A pointer to a Graph::Edge. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - push_back(edge); -} - -/* ========================================================================= */ -inline list::Edge*>::const_iterator -EdgeList::find(const Graph::Edge* edge) const -/* ---------------------------------------------------------------------------- - * - * Description: Finds an edge in the EdgeList. - * - * Argument: edge -- Pointer to an edge to be searched in the list. - * Note that during the search, comparison is done - * between the actual values of the edges (not the - * pointers). - * - * Returns: A list::Edge*>::const_iterator - * pointing to the edge in the list or - * list::Edge*>::end() if the edge is - * not found in the list. - * - * ------------------------------------------------------------------------- */ -{ - Graph::Edge::ptr_equal isEqual; - - const_iterator e; - for (e = begin(); e != end() && !isEqual(edge, *e); ++e) - ; - - return e; -} - -/* ========================================================================= */ -inline list::Edge*>::iterator -EdgeList::find(const Graph::Edge* edge) -/* ---------------------------------------------------------------------------- - * - * Description: Finds an edge in the EdgeList. - * - * Argument: edge -- Pointer to an edge to be searched in the list. - * Note that during the search, comparison is done - * between the actual values of the edges (not the - * pointers). - * - * Returns: A list::Edge*>::iterator pointing - * to the edge in the list or - * list::Edge*>::end() if the edge is - * not found in the list. - * - * ------------------------------------------------------------------------- */ -{ - Graph::Edge::ptr_equal isEqual; - - iterator e; - for (e = begin(); e != end() && !isEqual(edge, *e); ++e) - ; - - return e; -} - - - -/****************************************************************************** - * - * Inline function definitions for class EdgeSlist. - * - *****************************************************************************/ - -#ifdef HAVE_SLIST - -/* ========================================================================= */ -inline EdgeSlist::EdgeSlist() -/* ---------------------------------------------------------------------------- - * - * Description: Constructor for class EdgeList. Creates a new container based - * on singly linked lists for storing graph edges. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -inline EdgeSlist::~EdgeSlist() -/* ---------------------------------------------------------------------------- - * - * Description: Destructor for class EdgeSlist. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -inline void EdgeSlist::insert(Graph::Edge* edge) -/* ---------------------------------------------------------------------------- - * - * Description: Inserts a new edge to the beginning of the list. - * - * Argument: edge -- A pointer to a Graph::Edge. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - push_front(edge); -} - -/* ========================================================================= */ -inline slist::Edge*>::const_iterator -EdgeSlist::find(const Graph::Edge* edge) const -/* ---------------------------------------------------------------------------- - * - * Description: Finds an edge in the EdgeSlist. - * - * Argument: edge -- Pointer to an edge to be searched in the list. - * Note that during the search, comparison is done - * between the actual values of the edges (not the - * pointers). - * - * Returns: A slist::Edge*>::const_iterator - * pointing to the edge in the list or - * slist::Edge*>::end() if the edge - * is not found in the list. - * - * ------------------------------------------------------------------------- */ -{ - Graph::Edge::ptr_equal isEqual; - - const_iterator e; - for (e = begin(); e != end() && !isEqual(edge, *e); ++e) - ; - - return e; -} - -/* ========================================================================= */ -inline slist::Edge*>::iterator -EdgeSlist::find(const Graph::Edge* edge) -/* ---------------------------------------------------------------------------- - * - * Description: Finds an edge in the EdgeSlist. - * - * Argument: edge -- Pointer to an edge to be searched in the list. - * Note that during the search, comparison is done - * between the actual values of the edges (not the - * pointers). - * - * Returns: A slist::Edge*>::iterator - * pointing to the edge in the list or - * slist::Edge*>::end() if the edge - * is not found in the list. - * - * ------------------------------------------------------------------------- */ -{ - Graph::Edge::ptr_equal isEqual; - - iterator e; - for (e = begin(); e != end() && !isEqual(edge, *e); ++e) - ; - - return e; -} - -#endif /* HAVE_SLIST */ - - - -/****************************************************************************** - * - * Inline function definitions for class EdgeVector. - * - *****************************************************************************/ - -/* ========================================================================= */ -inline EdgeVector::EdgeVector() -/* ---------------------------------------------------------------------------- - * - * Description: Constructor for class EdgeVector. Creates a new container - * based on a vector for storing graph edges. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -inline EdgeVector::~EdgeVector() -/* ---------------------------------------------------------------------------- - * - * Description: Destructor for class EdgeVector. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -inline void EdgeVector::insert(Graph::Edge* edge) -/* ---------------------------------------------------------------------------- - * - * Description: Inserts an edge into the edge vector. - * - * Arguments: edge -- A pointer to a Graph::Edge. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - push_back(edge); -} - -/* ========================================================================= */ -inline vector::Edge*>::const_iterator -EdgeVector::find(const Graph::Edge* edge) const -/* ---------------------------------------------------------------------------- - * - * Description: Finds an edge in the EdgeVector. - * - * Argument: edge -- Pointer to an edge to be searched in the vector. - * Note that during the search, comparison is done - * between the actual values of the edges (not the - * pointers). - * - * Returns: A vector::Edge*>::const_iterator - * pointing to the edge in the container or - * vector::Edge*>::end() if the - * edge is not found in the container. - * - * ------------------------------------------------------------------------- */ -{ - Graph::Edge::ptr_equal isEqual; - - const_iterator e; - for (e = begin(); e != end() && !isEqual(edge, *e); ++e) - ; - - return e; -} - -/* ========================================================================= */ -inline vector::Edge*>::iterator -EdgeVector::find(const Graph::Edge* edge) -/* ---------------------------------------------------------------------------- - * - * Description: Finds an edge in the EdgeVector. - * - * Argument: edge -- Pointer to an edge to be searched in the vector. - * Note that during the search, comparison is done - * between the actual values of the edges (not the - * pointers). - * - * Returns: A vector::Edge*>::iterator - * pointing to the edge in the container or - * vector::Edge*>::end() if the edge - * is not found in the container. - * - * ------------------------------------------------------------------------- */ -{ - Graph::Edge::ptr_equal isEqual; - - iterator e; - for (e = begin(); e != end() && !isEqual(edge, *e); ++e) - ; - - return e; -} - -} - -#endif /* !GRAPH_H */ diff --git a/lbtt/src/IntervalList.cc b/lbtt/src/IntervalList.cc deleted file mode 100644 index d35c9b66e..000000000 --- a/lbtt/src/IntervalList.cc +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright (C) 2004, 2005 - * Heikki Tauriainen - * - * 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::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::iterator interval2 = interval; - ++interval2; - while (interval2 != intervals.end() - && interval2->first <= interval->second + 1) - { - if (interval->second < interval2->second) - interval->second = interval2->second; - list::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::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::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::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::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; -} diff --git a/lbtt/src/IntervalList.h b/lbtt/src/IntervalList.h deleted file mode 100644 index b8276bf34..000000000 --- a/lbtt/src/IntervalList.h +++ /dev/null @@ -1,500 +0,0 @@ -/* - * Copyright (C) 2004, 2005 - * Heikki Tauriainen - * - * 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 -#include -#include -#include -#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 - 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_list; /* The interval list - * associated with the - * iterator. - */ - - list::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::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 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 */ diff --git a/lbtt/src/LbtWrapper.h b/lbtt/src/LbtWrapper.h deleted file mode 100644 index bd889b18d..000000000 --- a/lbtt/src/LbtWrapper.h +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 - * Heikki Tauriainen - * - * 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 -#include -#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 */ diff --git a/lbtt/src/LbttAlloc.h b/lbtt/src/LbttAlloc.h deleted file mode 100644 index c98ceaa07..000000000 --- a/lbtt/src/LbttAlloc.h +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 - * Heikki Tauriainen - * - * 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 - -#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 -#include -#include - -/****************************************************************************** - * - * 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 */ diff --git a/lbtt/src/Ltl-parse.y b/lbtt/src/Ltl-parse.y deleted file mode 100644 index b308f7f30..000000000 --- a/lbtt/src/Ltl-parse.y +++ /dev/null @@ -1,610 +0,0 @@ -/* - * Copyright (C) 2004, 2005, 2008 - * Heikki Tauriainen - * - * 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 -#include -#include -#include -#include -#include -#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 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 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 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::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(*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; - } -} diff --git a/lbtt/src/Ltl-parse_.cc b/lbtt/src/Ltl-parse_.cc deleted file mode 100644 index 49e910798..000000000 --- a/lbtt/src/Ltl-parse_.cc +++ /dev/null @@ -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" diff --git a/lbtt/src/LtlFormula.cc b/lbtt/src/LtlFormula.cc deleted file mode 100644 index faad76f56..000000000 --- a/lbtt/src/LtlFormula.cc +++ /dev/null @@ -1,1126 +0,0 @@ -/* - * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 - * Heikki Tauriainen - * - * 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 -#include "FormulaWriter.h" -#include "LtlFormula.h" - -namespace Ltl -{ - -set /* Shared storage for */ - LtlFormula::formula_storage; /* LTL formulae. */ - -unsigned long int /* Upper limit for the */ - LtlFormula::eval_proposition_id_limit; /* atomic proposition - * identifiers (used - * when evaluating the - * truth value of the - * formula in a given - * truth assignment). - */ - -/****************************************************************************** - * - * Function for obtaining the infix symbol associated with a given - * FormulaType constant. - * - *****************************************************************************/ - -/* ========================================================================= */ -const char* infixSymbol(const int symbol) -/* ---------------------------------------------------------------------------- - * - * Description: Tells the infix symbol corresponding to a given FormulaType - * constant. - * - * Argument: symbol -- A symbol identifier. - * - * Returns: A pointer to a C-style string containing the symbol (or - * "UNKNOWN" if the argument does not correspond to a valid - * FormulaType symbol). - * - * ------------------------------------------------------------------------- */ -{ - switch (symbol) - { - case LTL_TRUE : - return static_cast(LtlTrue::infix_symbol); - - case LTL_FALSE : - return static_cast(LtlFalse::infix_symbol); - - case LTL_ATOM : - return "p"; - - case LTL_NEGATION : - return static_cast(LtlNegation::infix_symbol); - - case LTL_CONJUNCTION : - return static_cast(LtlConjunction::infix_symbol); - - case LTL_DISJUNCTION : - return static_cast(LtlDisjunction::infix_symbol); - - case LTL_IMPLICATION : - return static_cast(LtlImplication::infix_symbol); - - case LTL_EQUIVALENCE : - return static_cast(LtlEquivalence::infix_symbol); - - case LTL_XOR : - return static_cast(LtlXor::infix_symbol); - - case LTL_NEXT : - return static_cast(LtlNext::infix_symbol); - - case LTL_UNTIL : - return static_cast(LtlUntil::infix_symbol); - - case LTL_WEAK_UNTIL : - return static_cast(LtlWeakUntil::infix_symbol); - - case LTL_FINALLY : - return static_cast(LtlFinally::infix_symbol); - - case LTL_V : - return static_cast(LtlV::infix_symbol); - - case LTL_STRONG_RELEASE : - return static_cast(LtlStrongRelease::infix_symbol); - - case LTL_GLOBALLY : - return static_cast(LtlGlobally::infix_symbol); - - case LTL_BEFORE : - return static_cast(LtlBefore::infix_symbol); - - default : - return "UNKNOWN"; - } -} - - - -/****************************************************************************** - * - * A function class for convering an LtlFormula into negation normal form. - * - *****************************************************************************/ - -class NnfConverter -{ -public: - NnfConverter(); /* Constructor. */ - - ~NnfConverter(); /* Destructor. */ - - void operator() /* Implements the */ - (const LtlFormula* f, int operand); /* conversion operation. */ - - LtlFormula* getResult() const; /* Returns the result of - * the conversion. - */ - -private: - stack > - formula_stack; - - stack > negation_stack; - - NnfConverter(const NnfConverter&); /* Prevent copying and */ - NnfConverter& operator=(const NnfConverter&); /* assignment of - * NnfConverter objects. - */ -}; - - - -/****************************************************************************** - * - * A function class for computing the size of the parse tree of a formula. - * - *****************************************************************************/ - -class FormulaSizeCounter -{ -public: - FormulaSizeCounter(); /* Constructor. */ - - ~FormulaSizeCounter(); /* Destructor. */ - - void operator()(const LtlFormula*, int); /* Implements the node - * counting operation. - */ - - unsigned long int size; /* Node count. */ - -private: - FormulaSizeCounter(const FormulaSizeCounter&); /* Prevent copying and */ - FormulaSizeCounter& operator= /* assignment of */ - (const FormulaSizeCounter&); /* FormulaSizeCounter - * objects. - */ -}; - - - -/****************************************************************************** - * - * A function class for collecting the subformulae of an LtlFormula into a - * stack. - * - *****************************************************************************/ - -class SubformulaCollector -{ -public: - SubformulaCollector /* Constructor. */ - (stack >& - result_stack); - - ~SubformulaCollector(); /* Destructor. */ - - void operator()(const LtlFormula* f, int); /* Implements the - * subformula collection - * operation. - */ - -private: - stack >& - subformula_stack; - - SubformulaCollector(const SubformulaCollector&); /* Prevent copying and */ - SubformulaCollector& operator= /* assignment of */ - (const SubformulaCollector&); /* SubformulaCollector - * objects. - */ -}; - - - -/****************************************************************************** - * - * A function class for finding the largest atom identifier in a LtlFormula. - * - *****************************************************************************/ - -class MaxAtomFinder -{ -public: - MaxAtomFinder(); /* Constuctor. */ - - ~MaxAtomFinder(); /* Destructor. */ - - void operator()(const LtlFormula* f, int); /* Implements the atom - * identifier search - * operation. - */ - - long int getResult() const; /* Returns the result of - * the operation. - */ - -private: - long int max_atom_id; /* Largest identifier for - * an atom in an - * LtlFormula. - */ - - MaxAtomFinder(const SubformulaCollector&); /* Prevent copying and */ - MaxAtomFinder& operator= /* assignment of */ - (const MaxAtomFinder&); /* MaxAtomFinder - * objects. - */ -}; - - - -/****************************************************************************** - * - * Inline function definitions for class NnfConverter. - * - *****************************************************************************/ - -/* ========================================================================= */ -inline NnfConverter::NnfConverter() -/* ---------------------------------------------------------------------------- - * - * Description: Constructor for class NnfConverter. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - negation_stack.push(true); -} - -/* ========================================================================= */ -inline NnfConverter::~NnfConverter() -/* ---------------------------------------------------------------------------- - * - * Description: Destructor for class NnfConverter. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - while (!formula_stack.empty()) - { - LtlFormula::destruct(formula_stack.top()); - formula_stack.pop(); - } -} - -/* ========================================================================= */ -inline LtlFormula* NnfConverter::getResult() const -/* ---------------------------------------------------------------------------- - * - * Description: Returns the result of negation normal form conversion or - * `static_cast(0)' if there is no result - * available. - * - * Arguments: None. - * - * Returns: A pointer to the result of the conversion. - * - * ------------------------------------------------------------------------- */ -{ - if (!formula_stack.empty()) - return formula_stack.top()->clone(); - else - return static_cast(0); -} - - - -/****************************************************************************** - * - * Inline function definitions for class FormulaSizeCounter. - * - *****************************************************************************/ - -/* ========================================================================= */ -inline FormulaSizeCounter::FormulaSizeCounter() : - size(0) -/* ---------------------------------------------------------------------------- - * - * Description: Constructor for class FormulaSizeCounter. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -inline FormulaSizeCounter::~FormulaSizeCounter() -/* ---------------------------------------------------------------------------- - * - * Description: Destructor for class FormulaSizeCounter. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -inline void FormulaSizeCounter::operator()(const LtlFormula*, int) -/* ---------------------------------------------------------------------------- - * - * Description: Implementation for the parse tree node counting operation. - * - * Arguments: The arguments are needed only for supporting the function - * interface. - * - * Returns: Nothing; increments `this->size' by 1. - * - * ------------------------------------------------------------------------- */ -{ - ++size; -} - - - -/****************************************************************************** - * - * Inline function definitions for class SubformulaCollector. - * - *****************************************************************************/ - -/* ========================================================================= */ -inline SubformulaCollector::SubformulaCollector - (stack >& result_stack) : - subformula_stack(result_stack) -/* ---------------------------------------------------------------------------- - * - * Description: Constructor for class SubformulaCollector. - * - * Arguments: result_stack -- A stack of constant LtlFormulae for - * collecting the results. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -inline SubformulaCollector::~SubformulaCollector() -/* ---------------------------------------------------------------------------- - * - * Description: Destructor for class SubformulaCollector. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -inline void SubformulaCollector::operator()(const LtlFormula* f, int) -/* ---------------------------------------------------------------------------- - * - * Description: Implementation for the subformula collection operation. - * - * Arguments: f -- A pointer to a constant LtlFormula. - * The other argument is needed only for supporting the function - * interface. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - subformula_stack.push(f); -} - - - -/****************************************************************************** - * - * Inline function definitions for class MaxAtomFinder. - * - *****************************************************************************/ - -/* ========================================================================= */ -inline MaxAtomFinder::MaxAtomFinder() : - max_atom_id(-1) -/* ---------------------------------------------------------------------------- - * - * Description: Constructor for class MaxAtomFinder. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -inline MaxAtomFinder::~MaxAtomFinder() -/* ---------------------------------------------------------------------------- - * - * Description: Destructor for class MaxAtomFinder. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -inline void MaxAtomFinder::operator()(const LtlFormula* f, int) -/* ---------------------------------------------------------------------------- - * - * Description: Implements the search for the largest atomic proposition in - * an LtlFormula. - * - * Arguments: f -- A pointer to a constant LtlFormula. - * The other argument is needed only for supporting the function - * interface. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - if (f->what() == LTL_ATOM - && static_cast(f)->getId() > max_atom_id) - max_atom_id = static_cast(f)->getId(); -} - -/* ========================================================================= */ -inline long int MaxAtomFinder::getResult() const -/* ---------------------------------------------------------------------------- - * - * Description: Returns the largest identifier of an atomic proposition - * found by the MaxAtomFinder object. - * - * Arguments: None. - * - * Returns: Largest identifier for an atomic proposition in an - * LtlFormula or -1 if the formula does not contain any - * atomic propositions. - * - * ------------------------------------------------------------------------- */ -{ - return max_atom_id; -} - - - -/****************************************************************************** - * - * Function definitions for class NnfConverter. - * - *****************************************************************************/ - -/* ========================================================================= */ -void NnfConverter::operator()(const LtlFormula* f, int operand) -/* ---------------------------------------------------------------------------- - * - * Description: Implements the negation normal form conversion for an - * LtlFormula. - * - * Arguments: f -- A pointer to a constant LtlFormula to be - * converted into negation normal form. - * operand -- - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - if (operand == 0) - { - switch (f->what()) - { - case LTL_ATOM : - { - Atom* a = &Atom::construct(static_cast(f)->getId()); - if (negation_stack.top()) - formula_stack.push(a); - else - formula_stack.push(&Not::construct(a)); - negation_stack.pop(); - break; - } - - case LTL_TRUE : case LTL_FALSE : - if ((f->what() == LTL_TRUE) == negation_stack.top()) - formula_stack.push(&True::construct()); - else - formula_stack.push(&False::construct()); - negation_stack.pop(); - break; - - default : - negation_stack.push(f->what() != LTL_NEGATION - && f->what() != LTL_BEFORE - ? negation_stack.top() - : !negation_stack.top()); - - switch (f->what()) - { - case LTL_CONJUNCTION : case LTL_DISJUNCTION : case LTL_UNTIL : - case LTL_V : case LTL_WEAK_UNTIL : case LTL_STRONG_RELEASE : - negation_stack.push(negation_stack.top()); - break; - - case LTL_IMPLICATION : - case LTL_BEFORE : - negation_stack.push(!negation_stack.top()); - break; - - case LTL_EQUIVALENCE : - negation_stack.push(true); - break; - - case LTL_XOR : - negation_stack.push(false); - break; - - default : - break; - } - } - - return; - } - - switch (f->what()) - { - case LTL_NEGATION : - break; - - case LTL_NEXT : - formula_stack.top() = &Next::construct(formula_stack.top()); - break; - - case LTL_FINALLY : case LTL_GLOBALLY : - if ((f->what() == LTL_FINALLY) == negation_stack.top()) - formula_stack.top() - = &Until::construct(&True::construct(), formula_stack.top()); - else - formula_stack.top() - = &V::construct(&False::construct(), formula_stack.top()); - break; - - default : /* binary operator */ - { - LtlFormula* rgt = formula_stack.top(); - formula_stack.pop(); - - switch (f->what()) - { - case LTL_CONJUNCTION : case LTL_DISJUNCTION : case LTL_IMPLICATION : - if ((f->what() == LTL_CONJUNCTION) == negation_stack.top()) - formula_stack.top() - = &And::construct(formula_stack.top(), rgt); - else - formula_stack.top() - = &Or::construct(formula_stack.top(), rgt); - break; - - case LTL_EQUIVALENCE : case LTL_XOR : - { - LtlFormula* g = &Not::construct(*formula_stack.top()); - LtlFormula* lft_neg = g->nnfClone(); - LtlFormula::destruct(g); - g = &Not::construct(*rgt); - LtlFormula* rgt_neg = g->nnfClone(); - LtlFormula::destruct(g); - - formula_stack.top() - = &And::construct(&Or::construct(formula_stack.top(), rgt_neg), - &Or::construct(lft_neg, rgt)); - break; - } - - case LTL_UNTIL : case LTL_V : case LTL_BEFORE : - if ((f->what() == LTL_UNTIL) == negation_stack.top()) - formula_stack.top() - = &Until::construct(formula_stack.top(), rgt); - else - formula_stack.top() - = &V::construct(formula_stack.top(), rgt); - break; - - default : /* LTL_WEAK_UNTIL || LTL_STRONG_RELEASE */ - if ((f->what() == LTL_WEAK_UNTIL) == negation_stack.top()) - formula_stack.top() - = &Or::construct(&Until::construct(*formula_stack.top(), rgt), - &V::construct(&False::construct(), - formula_stack.top())); - else - formula_stack.top() - = &And::construct(&V::construct(*formula_stack.top(), rgt), - &Until::construct(&True::construct(), - formula_stack.top())); - break; - } - - break; - } - } - - negation_stack.pop(); -} - - - -/****************************************************************************** - * - * Definitions for symbols used for printing the formula. - * - *****************************************************************************/ - -const char LtlTrue::prefix_symbol[] = "t"; -const char LtlTrue::infix_symbol[] = "true"; - -const char LtlFalse::prefix_symbol[] = "f"; -const char LtlFalse::infix_symbol[] = "false"; - -const char LtlNegation::prefix_symbol[] = "!"; -const char LtlNegation::infix_symbol[] = "!"; - -const char LtlNext::prefix_symbol[] = "X"; -const char LtlNext::infix_symbol[] = "X"; - -const char LtlFinally::prefix_symbol[] = "F"; -const char LtlFinally::infix_symbol[] = "<>"; - -const char LtlGlobally::prefix_symbol[] = "G"; -const char LtlGlobally::infix_symbol[] = "[]"; - -const char LtlConjunction::prefix_symbol[] = "&"; -const char LtlConjunction::infix_symbol[] = "/\\"; - -const char LtlDisjunction::prefix_symbol[] = "|"; -const char LtlDisjunction::infix_symbol[] = "\\/"; - -const char LtlImplication::prefix_symbol[] = "i"; -const char LtlImplication::infix_symbol[] = "->"; - -const char LtlEquivalence::prefix_symbol[] = "e"; -const char LtlEquivalence::infix_symbol[] = "<->"; - -const char LtlXor::prefix_symbol[] = "^"; -const char LtlXor::infix_symbol[] = "xor"; - -const char LtlUntil::prefix_symbol[] = "U"; -const char LtlUntil::infix_symbol[] = "U"; - -const char LtlV::prefix_symbol[] = "V"; -const char LtlV::infix_symbol[] = "V"; - -const char LtlWeakUntil::prefix_symbol[] = "W"; -const char LtlWeakUntil::infix_symbol[] = "W"; - -const char LtlStrongRelease::prefix_symbol[] = "M"; -const char LtlStrongRelease::infix_symbol[] = "M"; - -const char LtlBefore::prefix_symbol[] = "B"; -const char LtlBefore::infix_symbol[] = "B"; - - - -/****************************************************************************** - * - * Function definitions for class LtlFormula. - * - *****************************************************************************/ - -/* ========================================================================= */ -LtlFormula* LtlFormula::nnfClone() -/* ---------------------------------------------------------------------------- - * - * Description: Creates a copy of an LtlFormula in negation normal form. - * - * Arguments: None. - * - * Returns: A pointer to a newly allocated LtlFormula, which is - * equivalent to `this' formula in negation normal form. - * - * ------------------------------------------------------------------------- */ -{ - NnfConverter nc; - traverse(nc, LTL_PREORDER | LTL_POSTORDER); - return nc.getResult(); -} - -/* ========================================================================= */ -unsigned long int LtlFormula::size() const -/* ---------------------------------------------------------------------------- - * - * Description: Computes the number of nodes in the parse tree of an - * LtlFormula. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - FormulaSizeCounter fsc; - traverse(fsc, LTL_PREORDER); - return fsc.size; -} - -/* ========================================================================= */ -void LtlFormula::collectSubformulae - (stack >& result_stack) const -/* ---------------------------------------------------------------------------- - * - * Description: Collects the subformulae of a LtlFormula into a stack. After - * the operation, the result stack contains the subformulae of - * the formula in post-depth-first-search order, i.e., each - * subformula of the formula can be accessed in the stack only - * after its subformulae have been accessed. - * - * Argument: result_stack -- A reference to a stack for collecting the - * results. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - SubformulaCollector sc(result_stack); - traverse(sc, LTL_PREORDER); -} - -/* ========================================================================= */ -long int LtlFormula::maxAtom() const -/* ---------------------------------------------------------------------------- - * - * Description: Returns the identifier of the "greatest" atomic proposition - * in the formula. - * - * Arguments: None. - * - * Returns: The identifier of the "greatest" atomic proposition in the - * formula or -1 if the formula is a constant formula. - * - * ------------------------------------------------------------------------- */ -{ - if (info_flags.is_constant) - return -1; - - MaxAtomFinder maf; - traverse(maf, LTL_PREORDER); - return maf.getResult(); -} - -/* ========================================================================= */ -bool LtlFormula::satisfiable(long int max_atom) const -/* ---------------------------------------------------------------------------- - * - * Description: Tells whether the formula is satisfiable. (This check is - * allowed only on fully propositional formulae.) - * - * Arguments: max_atom -- Identifier of the "greatest" atomic proposition - * in the formula. - * - * Returns: A truth value according to the result of the test. - * - * ------------------------------------------------------------------------- */ -{ - if (!info_flags.is_propositional) - throw Exception("satisfiability check not allowed on a temporal formula"); - - if (max_atom < 0) - max_atom = maxAtom(); - - TableauStack tableau_stack; - return sat_eval(tableau_stack, max_atom); -} - -/* ========================================================================= */ -Bitset LtlFormula::findPropositionalModel(long int max_atom) const -/* ---------------------------------------------------------------------------- - * - * Description: Finds a model for a fully propositional formula (if the - * formula is satisfiable). - * - * Arguments: max_atom -- Identifier of the "greatest" atomic proposition - * in the formula. - * - * Returns: A Bitset defining a truth assignment for the propositional - * variables in the formula such that the formula is satisfied. - * - * ------------------------------------------------------------------------- */ -{ - if (!info_flags.is_propositional) - throw Exception("satisfiability check not allowed on a temporal formula"); - - if (max_atom < 0) - max_atom = maxAtom(); - - TableauStack tableau_stack; - - if (!sat_eval(tableau_stack, max_atom)) - throw Exception("formula is not satisfiable"); - - Bitset model(max_atom + 1); - model.clear(); - - for (long int i = 0; i <= max_atom; i++) - { - if (tableau_stack.top().second.test(i)) - model.setBit(i); - } - - return model; -} - -/* ========================================================================= */ -void LtlFormula::print(Exceptional_ostream& estream, OutputMode mode) const -/* ---------------------------------------------------------------------------- - * - * Description: Writes the formula to a stream. - * - * Arguments: estream -- A reference to an exception-aware output stream. - * mode -- Chooses between prefix and infix notation. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - if (mode == LTL_PREFIX) - { - FormulaWriter, - ConstantWriter, - AtomWriter, - UnaryOperatorWriter, - UnaryOperatorWriter, - UnaryOperatorWriter, - UnaryOperatorWriter, - BinaryOperatorPrefixWriter, - BinaryOperatorPrefixWriter, - BinaryOperatorPrefixWriter, - BinaryOperatorPrefixWriter, - BinaryOperatorPrefixWriter, - BinaryOperatorPrefixWriter, - BinaryOperatorPrefixWriter, - BinaryOperatorPrefixWriter, - BinaryOperatorPrefixWriter, - BinaryOperatorPrefixWriter - > - fw(estream); - - traverse(fw, LTL_PREORDER | LTL_INORDER | LTL_POSTORDER); - } - else - { - FormulaWriter, - ConstantWriter, - AtomWriter, - UnaryOperatorWriter, - UnaryOperatorWriter, - UnaryOperatorWriter, - UnaryOperatorWriter, - BinaryOperatorInfixWriter, - BinaryOperatorInfixWriter, - BinaryOperatorInfixWriter, - BinaryOperatorInfixWriter, - BinaryOperatorInfixWriter, - BinaryOperatorInfixWriter, - BinaryOperatorInfixWriter, - BinaryOperatorInfixWriter, - BinaryOperatorInfixWriter, - BinaryOperatorInfixWriter - > - fw(estream); - - traverse(fw, LTL_PREORDER | LTL_INORDER | LTL_POSTORDER); - } -} - -/* ========================================================================= */ -bool LtlFormula::sat_eval - (TableauStack& tableau_stack, const long int max_atom) const -/* ---------------------------------------------------------------------------- - * - * Description: Determines whether the formula is satisfiable. If yes, a - * model of the formula will be stored in the map given as a - * parameter. (This check is allowed only on fully propositional - * formulae.) - * - * Arguments: tableau_stack -- Nodes of the tableau used for - * satisfiability testing. - * max_atom -- Identifier of the "greatest" atomic - * proposition in the formula. - * - * Returns: A truth value telling whether the formula is satisfiable or - * not. - * - * ------------------------------------------------------------------------- */ -{ - bool prove_true; - const LtlFormula* current_formula; - - tableau_stack.push - (make_pair(FormulaStack(), - Bitset((static_cast(max_atom) + 1) * 2))); - tableau_stack.top().second.clear(); - - FormulaStack* formula_stack = &tableau_stack.top().first; - - formula_stack->push(make_pair(true, this)); - - while (!formula_stack->empty()) - { - prove_true = formula_stack->top().first; - current_formula = formula_stack->top().second; - formula_stack->pop(); - - switch (current_formula->what()) - { - case LTL_ATOM : - { - long int atom_id = static_cast(current_formula)->getId(); - - if (prove_true) - { - if (tableau_stack.top().second.test(atom_id + max_atom + 1)) - { - tableau_stack.pop(); - if (tableau_stack.empty()) - return false; - formula_stack = &tableau_stack.top().first; - } - else - tableau_stack.top().second.setBit(atom_id); - } - else - { - if (tableau_stack.top().second.test(atom_id)) - { - tableau_stack.pop(); - if (tableau_stack.empty()) - return false; - formula_stack = &tableau_stack.top().first; - } - else - tableau_stack.top().second.setBit(atom_id + max_atom + 1); - } - - break; - } - - case LTL_TRUE : - if (!prove_true) - { - tableau_stack.pop(); - if (tableau_stack.empty()) - return false; - formula_stack = &tableau_stack.top().first; - } - - break; - - case LTL_FALSE : - if (prove_true) - { - tableau_stack.pop(); - if (tableau_stack.empty()) - return false; - formula_stack = &tableau_stack.top().first; - } - - break; - - case LTL_NEGATION : - { - const Not* f = static_cast(current_formula); - formula_stack->push(make_pair(!prove_true, f->subformula)); - break; - } - - case LTL_DISJUNCTION : - { - const Or* f = static_cast(current_formula); - - if (prove_true) - { - tableau_stack.push(tableau_stack.top()); - formula_stack->push(make_pair(true, f->subformula2)); - formula_stack = &tableau_stack.top().first; - formula_stack->push(make_pair(true, f->subformula1)); - } - else - { - formula_stack->push(make_pair(false, f->subformula2)); - formula_stack->push(make_pair(false, f->subformula1)); - } - - break; - } - - case LTL_CONJUNCTION : - { - const And* f = static_cast(current_formula); - - if (prove_true) - { - formula_stack->push(make_pair(true, f->subformula2)); - formula_stack->push(make_pair(true, f->subformula1)); - } - else - { - tableau_stack.push(tableau_stack.top()); - formula_stack->push(make_pair(false, f->subformula2)); - formula_stack = &tableau_stack.top().first; - formula_stack->push(make_pair(false, f->subformula1)); - } - - break; - } - - case LTL_IMPLICATION : - { - const Imply* f = static_cast(current_formula); - - if (prove_true) - { - tableau_stack.push(tableau_stack.top()); - formula_stack->push(make_pair(true, f->subformula2)); - formula_stack = &tableau_stack.top().first; - formula_stack->push(make_pair(false, f->subformula1)); - } - else - { - formula_stack->push(make_pair(false, f->subformula2)); - formula_stack->push(make_pair(true, f->subformula1)); - } - - break; - } - - case LTL_EQUIVALENCE : - { - const Equiv* f = static_cast(current_formula); - - tableau_stack.push(tableau_stack.top()); - formula_stack->push(make_pair(!prove_true, f->subformula2)); - formula_stack->push(make_pair(false, f->subformula1)); - formula_stack = &tableau_stack.top().first; - formula_stack->push(make_pair(prove_true, f->subformula2)); - formula_stack->push(make_pair(true, f->subformula1)); - - break; - } - - case LTL_XOR : - { - const Xor* f = static_cast(current_formula); - - tableau_stack.push(tableau_stack.top()); - formula_stack->push(make_pair(prove_true, f->subformula2)); - formula_stack->push(make_pair(false, f->subformula1)); - formula_stack = &tableau_stack.top().first; - formula_stack->push(make_pair(!prove_true, f->subformula2)); - formula_stack->push(make_pair(true, f->subformula1)); - - break; - } - - default : - throw Exception("satisfiable(): unknown formula type"); - } - } - - return true; -} - -} diff --git a/lbtt/src/LtlFormula.h b/lbtt/src/LtlFormula.h deleted file mode 100644 index a53303ba7..000000000 --- a/lbtt/src/LtlFormula.h +++ /dev/null @@ -1,2642 +0,0 @@ -/* - * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 - * Heikki Tauriainen - * - * 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 LTLFORMULA_H -#define LTLFORMULA_H - -#include -#include -#include -#include -#include -#include -#include "LbttAlloc.h" -#include "BitArray.h" -#include "Exception.h" - -using namespace std; - -extern bool user_break; - -namespace Ltl -{ - -/****************************************************************************** - * - * Constants for identifying LTL formulae of various types. - * - *****************************************************************************/ - -enum FormulaType - {LTL_TRUE = 't', LTL_FALSE = 'f', LTL_ATOM = 'p', LTL_NEGATION = '!', - LTL_NEXT = 'X', LTL_FINALLY = 'F', LTL_GLOBALLY = 'G', - LTL_CONJUNCTION = '&', LTL_DISJUNCTION = '|', LTL_IMPLICATION = 'i', - LTL_EQUIVALENCE = 'e', LTL_XOR = '^', LTL_UNTIL = 'U', LTL_V = 'V', - LTL_WEAK_UNTIL = 'W', LTL_STRONG_RELEASE = 'M', LTL_BEFORE = 'B'}; - -const char* infixSymbol(const int symbol); /* Returns the infix - * symbol corresponding to - * a given FormulaType - * constant. - */ - - - -/****************************************************************************** - * - * Constants for selecting between the traversal modes in the parse tree of an - * LTL formula. - * - *****************************************************************************/ - -enum TraversalMode {LTL_PREORDER = 1, LTL_INORDER = 2, LTL_POSTORDER = 4}; - - - -/****************************************************************************** - * - * Constants for selecting the notation in which to print an LtlFormula. - * - *****************************************************************************/ - -enum OutputMode {LTL_PREFIX, LTL_INFIX}; - - - -/****************************************************************************** - * - * A base class for LTL formulae. - * - *****************************************************************************/ - -class LtlFormula -{ -public: - LtlFormula(); /* Creates a new LTL - * formula. - */ - - virtual ~LtlFormula(); /* Destructor. */ - -private: - LtlFormula(const LtlFormula& f); /* Prevent copying and */ - LtlFormula& operator=(const LtlFormula& f); /* assignment of - * LtlFormula objects. - */ - -public: - static void destruct(LtlFormula* f); /* Removes an LTL formula - * from `formula_storage'. - */ - - virtual bool operator<(const LtlFormula& f) /* ``Less than'' */ - const = 0; /* comparison. */ - - LtlFormula* clone(); /* Creates a copy of the - * formula object. - */ - - LtlFormula* nnfClone(); /* Creates a copy of the - * formula object in - * negation normal form. - */ - - bool evaluate /* These functions */ - (const BitArray& valuation, /* evaluate the formula */ - const unsigned long int valuation_size) const; /* in a given truth */ - /* assignment for the */ - bool evaluate /* atomic propositions. */ - (const Bitset& valuation) const; /* (The functions are - * intended to be used - * mainly with pure - * propositional - * formulae. If the - * formula contains - * temporal operators, - * calling one of these - * functions is - * interpreted as a - * request to evaluate - * the formula in a - * state space - * consisting of a - * single state having a - * transition to itself, - * with the given truth - * assignment for the - * atomic propositions.) - */ - - bool propositional() const; /* Tells whether the - * formula contains any - * temporal operators. - */ - - bool constant() const; /* Tells whether the - * formula is a constant, - * i.e., whether all its - * atoms are Boolean - * constants. - */ - - unsigned long int size() const; /* Returns the number of - * nodes in the parse tree - * of the formula. - */ - - long int maxAtom() const; /* Finds the largest - * identifier of the - * atomic propositions in - * the formula. - */ - - bool satisfiable(long int max_atom = -1) const; /* Tells whether the - * formula is satisfiable. - * (This test is only - * allowed if the formula - * is propositional.) - */ - - Bitset findPropositionalModel /* Finds a model for a */ - (long int max_atom = -1) const; /* purely propositional - * formula (if it is - * satisfiable). - */ - - virtual FormulaType what() const = 0; /* Tells the type of the - * formula. - */ - - static LtlFormula* read(istream& stream); /* Constructs an LtlFormula - * by parsing input from an - * input stream. - */ - - void print /* Writes the formula to */ - (ostream& stream = cout, /* an output stream. */ - OutputMode mode = LTL_INFIX) const; - - void print /* Writes the formula to */ - (Exceptional_ostream& stream, /* an exception-aware */ - OutputMode mode) const; /* output stream. */ - - template /* Performs a depth- */ - void traverse(F& f, int mode) const; /* first traversal on */ - /* the formula parse - * tree, calling the - * function object `f' - * at each node. - */ - - /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - - class ParseErrorException : public Exception /* A class for reporting */ - /* errors when */ - /* constructing an */ - /* LtlFormula by reading */ - { /* it from a stream. */ - public: - ParseErrorException(const string& msg); /* Constructor. */ - - /* default copy constructor */ - - ~ParseErrorException() throw(); /* Destructor. */ - - ParseErrorException& operator= /* Assignment operator. */ - (const ParseErrorException& e); - }; - - /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - - class ptr_less /* Class for mapping */ - { /* the `less than' */ - public: /* relation between two */ - bool operator() /* pointers to */ - (const LtlFormula* f1, /* LtlFormulae to the */ - const LtlFormula* f2) const; /* corresponding */ - }; /* relation between the - * formulae itself. - */ - - /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -protected: - struct /* These flags tell */ - { /* whether the formula */ - unsigned int is_propositional : 1; /* contains any temporal */ - unsigned int is_constant : 1; /* operators and atomic */ - } info_flags; /* propositions. */ - - unsigned long int refcount; /* Number of references to - * `this' LtlFormula. - */ - - static LtlFormula& /* Updates the shared */ - insertToStorage(LtlFormula* f); /* formula storage with - * a new formula. - */ - -private: - virtual bool eval /* Helper function for */ - (const BitArray& valuation) const = 0; /* evaluating the - * formula in a given - * truth assignment. - */ - - void collectSubformulae /* Builds a stack of the */ - (stack >& /* formula. */ - result_stack) const; - - typedef pair /* Shorthand type */ - FormulaStackElement; /* definitions for the */ - typedef stack > /* satisfiability */ - FormulaStack; /* checking algorithm. */ - typedef pair - TableauStackElement; - typedef stack > - TableauStack; - - bool sat_eval /* Helper function for */ - (TableauStack& tableau_stack, /* testing the */ - const long int max_atom) /* satisfiability of a */ - const; /* propositional - * formula. - */ - - static set /* Shared storage for */ - formula_storage; /* LTL formulae. */ - - static unsigned long int /* Upper limit for the */ - eval_proposition_id_limit; /* atomic proposition - * identifiers (used - * when evaluating the - * truth value of the - * formula in a given - * truth assignment). - */ - - friend class Atom; /* Friend declarations. */ - - friend class LtlNegation; - friend class LtlNext; - friend class LtlFinally; - friend class LtlGlobally; - - friend class LtlDisjunction; - friend class LtlConjunction; - friend class LtlImplication; - friend class LtlEquivalence; - friend class LtlXor; - friend class LtlUntil; - friend class LtlV; - friend class LtlWeakUntil; - friend class LtlStrongRelease; - friend class LtlBefore; - - friend class PathEvaluator; - - template - friend class UnaryFormula; - - template - friend class BinaryFormula; -}; - - - -/****************************************************************************** - * - * Interface to the formula parser. - * - *****************************************************************************/ - -extern LtlFormula* parseFormula(istream& stream); - - - -/****************************************************************************** - * - * A class for atomic propositions. - * - *****************************************************************************/ - -class Atom : public LtlFormula -{ -public: - static Atom& construct(long int a); /* Creates a new atomic - * proposition. - */ - -private: - explicit Atom(long int a); /* Constructor for an - * atomic proposition. - */ - - ~Atom(); /* Destructor. */ - - Atom(const Atom&); /* Prevent copying and */ - Atom& operator=(const Atom&); /* assignment of Atom - * objects. - */ - -public: - long int getId() const; /* Returns the identifier - * of the atomic - * proposition. - */ - - bool operator<(const LtlFormula& f) const; /* ``Less than'' - * comparison. - */ - - FormulaType what() const; /* Returns the type of - * the formula, i.e. the - * constant LTL_ATOM. - */ - - friend class LtlNegation; /* Friend declarations. */ - friend class LtlNext; - friend class LtlFinally; - friend class LtlGlobally; - - friend class LtlDisjunction; - friend class LtlConjunction; - friend class LtlImplication; - friend class LtlEquivalence; - friend class LtlXor; - friend class LtlUntil; - friend class LtlV; - friend class LtlWeakUntil; - friend class LtlStrongRelease; - friend class LtlBefore; - - friend class PathEvaluator; - -private: - bool eval(const BitArray& valuation) const; /* Returns the truth value - * of the atom in a given - * truth assignment. - */ - - long int atom; /* Identifier of a - * propositional variable. - */ -}; - - - -/****************************************************************************** - * - * A template class for Boolean constants. The class (`Symbol') used to - * instantiate the template must satisfy the following requirements: - * - * (1) The class contains two static public constant arrays of characters - * `prefix_symbol' and `infix_symbol' representing the textual symbols - * that should be used when printing the constant in prefix or infix - * notation, respectively. - * - * (2) The class contains a static public constant attribute `type' of type - * FormulaType which can be used to identify the constant. - * - * (3) The class contains a static public member function `eval' which can - * be called without any parameters. The function returns a truth value - * of the constant. - * - *****************************************************************************/ - -template -class Constant : public LtlFormula -{ -public: - static Constant& construct(); /* Creates a Boolean - * constant. - */ - -private: - Constant(); /* Constructor for a - * Boolean constant. - */ - - ~Constant(); /* Destructor. */ - - Constant(const Constant&); /* Prevent copying and */ - Constant& operator= /* assignment of */ - (const Constant&); /* Constants. */ - -public: - bool operator<(const LtlFormula& f) const; /* ``Less than'' - * comparison. - */ - - FormulaType what() const; /* Returns the type of - * the constant, i.e. - * Symbol::type. - */ - - friend class LtlNegation; /* Friend declarations. */ - friend class LtlNext; - friend class LtlFinally; - friend class LtlGlobally; - - friend class LtlDisjunction; - friend class LtlConjunction; - friend class LtlImplication; - friend class LtlEquivalence; - friend class LtlXor; - friend class LtlUntil; - friend class LtlV; - friend class LtlWeakUntil; - friend class LtlStrongRelease; - friend class LtlBefore; - - friend class PathEvaluator; - -private: - bool eval(const BitArray&) const; /* This function only tells - * the truth value of the - * constant. It is needed - * to satisfy the - * LtlFormula member - * function interface. - */ -}; - - - -/****************************************************************************** - * - * A class for the Boolean constant `true'. - * - *****************************************************************************/ - -class LtlTrue -{ -public: - static const char prefix_symbol[]; /* Symbols for printing */ - static const char infix_symbol[]; /* the constant. */ - - static const FormulaType type = LTL_TRUE; /* Type of the constant. */ - - static bool eval(); /* Returns the truth value - * of the constant. - */ -}; - - - -/****************************************************************************** - * - * A class for the Boolean constant `false'. - * - *****************************************************************************/ - -class LtlFalse -{ -public: - static const char prefix_symbol[]; /* Symbols for printing */ - static const char infix_symbol[]; /* the constant. */ - - static const FormulaType type = LTL_FALSE; /* Type of the constant. */ - - static bool eval(); /* Returns the truth value - * of the constant. - */ -}; - - - -/****************************************************************************** - * - * Type definitions for propositional constants to make them accessible - * without using the template instantiation syntax. - * - *****************************************************************************/ - -typedef Constant True; -typedef Constant False; - - - -/****************************************************************************** - * - * A template class for LTL formulae consisting of a unary operator (e.g. - * negation) and a subformula. The class `Operator' used to instantiate the - * template must satisfy the following requirements: - * - * (1) The class contains two static public constant arrays of characters - * `prefix_symbol' and `infix_symbol' representing the textual symbols - * that should be used when printing the operator in prefix or infix - * notation, respectively. - * - * (2) The class contains a static public constant attribute `type' of type - * FormulaType which can be used to identify the exact type of the - * formula. - * - * (3) The class contains a static public member function `eval' which can - * be called with two parameters: - * - a BitArray object assigning truth values to atomic propositions - * - a pointer to an LtlFormula object (the subformula associated with - * the unary operator). - * The function must return a truth value (assumed to be the truth value - * of the formula in the truth assignment given by the BitArray object). - * - *****************************************************************************/ - -template -class UnaryFormula : public LtlFormula -{ -public: - static UnaryFormula& construct /* Create a new unary */ - (LtlFormula* f); /* LTL formula. */ - static UnaryFormula& construct - (LtlFormula& f); - -private: - UnaryFormula(LtlFormula* f); /* Constructor for unary - * LTL formulae. - */ - - ~UnaryFormula(); /* Destructor. */ - - UnaryFormula /* Prevent copying and */ - (const UnaryFormula& f); /* assignment of */ - UnaryFormula& operator= /* UnaryFormula objects. */ - (const UnaryFormula& f); - -public: - bool operator<(const LtlFormula& f) const; /* ``Less than'' - * comparison. - */ - - FormulaType what() const; /* Tells the type of the - * formula. - */ - - friend class LtlFormula; /* Friend declarations. */ - - friend class LtlNegation; - friend class LtlNext; - friend class LtlFinally; - friend class LtlGlobally; - - friend class LtlDisjunction; - friend class LtlConjunction; - friend class LtlImplication; - friend class LtlEquivalence; - friend class LtlXor; - friend class LtlUntil; - friend class LtlV; - friend class LtlWeakUntil; - friend class LtlStrongRelease; - friend class LtlBefore; - - friend class PathEvaluator; - -private: - bool eval(const BitArray& valuation) const; /* Returns the truth value - * of the formula in a - * given truth assignment. - */ - - LtlFormula* subformula; /* Pointer to the operand - * formula of the unary - * operator. - */ -}; - - - -/****************************************************************************** - * - * A class for negation operator. - * - *****************************************************************************/ - -class LtlNegation -{ -public: - static const char prefix_symbol[]; /* Symbols for printing */ - static const char infix_symbol[]; /* the formula. */ - - static const FormulaType type = LTL_NEGATION; /* Type of the formula. */ - - static bool eval /* Evaluates a negated */ - (const BitArray& valuation, /* formula in a given */ - const LtlFormula* f); /* truth assignment (a - * single-state state - * space). - */ -}; - - - -/****************************************************************************** - * - * A class for "Next" operator. - * - *****************************************************************************/ - -class LtlNext -{ -public: - static const char prefix_symbol[]; /* Symbols for printing */ - static const char infix_symbol[]; /* the formula. */ - - static const FormulaType type = LTL_NEXT; /* Type of the formula. */ - - static bool eval /* Evaluates a "Next" */ - (const BitArray& valuation, /* formula in a given */ - const LtlFormula* f); /* truth assignment (a - * single-state state - * space). - */ -}; - - - -/****************************************************************************** - * - * A class for "Finally" operator. - * - *****************************************************************************/ - -class LtlFinally -{ -public: - static const char prefix_symbol[]; /* Symbols for printing */ - static const char infix_symbol[]; /* the formula. */ - - static const FormulaType type = LTL_FINALLY; /* Type of the formula. */ - - static bool eval /* Evaluates a "Finally" */ - (const BitArray& valuation, /* formula in a given */ - const LtlFormula* f); /* truth assignment (a - * single-state state - * space). - */ -}; - - - -/****************************************************************************** - * - * A class for "Globally" operator. - * - *****************************************************************************/ - -class LtlGlobally -{ -public: - static const char prefix_symbol[]; /* Symbols for printing */ - static const char infix_symbol[]; /* the formula. */ - - static const FormulaType type = LTL_GLOBALLY; /* Type of the formula. */ - - static bool eval /* Evaluates a */ - (const BitArray& valuation, /* "Globally" formula in */ - const LtlFormula* f); /* a given truth - * assignment (a single- - * state state space). - */ -}; - - - -/****************************************************************************** - * - * Type definitions for unary LTL formulae to make them accessible without - * using the template instantiation syntax. - * - *****************************************************************************/ - -typedef UnaryFormula Not; -typedef UnaryFormula Next; -typedef UnaryFormula Finally; -typedef UnaryFormula Globally; - - - -/****************************************************************************** - * - * A template class for LTL formulae consisting of a binary operator - * (e.g. conjunction) with two subformulae. The class `Operator' used for - * instantiating the template must satisfy the following requirements: - * - * (1) The class contains two static public constant arrays of characters - * `prefix_symbol' and `infix_symbol' representing the textual symbols - * that should be used when printing the operator in prefix or infix - * notation, respectively. - * - * (2) The class contains a static public constant attribute `type' of type - * FormulaType which can be used to identify the exact type of the - * formula. - * - * (3) The class contains a static public member function `eval' which can - * be called with three parameters: - * - a BitArray object assigning truth values to atomic propositions - * - two pointers to LtlFormula objects (the subformulae associated - * with the binary operator) - * The function must return a truth value (assumed to be the truth value - * of the formula in the truth assignment given by the BitArray object). - * - *****************************************************************************/ - -template -class BinaryFormula : public LtlFormula -{ -public: - static BinaryFormula& construct /* Create a binary LTL */ - (LtlFormula* f1, LtlFormula* f2); /* formula. */ - static BinaryFormula& construct - (LtlFormula& f1, LtlFormula& f2); - static BinaryFormula& construct - (LtlFormula* f1, LtlFormula& f2); - static BinaryFormula& construct - (LtlFormula& f1, LtlFormula* f2); - -private: - BinaryFormula(LtlFormula* f1, LtlFormula* f2); /* Constructor for a */ - /* binary LTL formula. */ - - ~BinaryFormula(); /* Destructor. */ - - BinaryFormula /* Prevent copying and */ - (const BinaryFormula& f); /* assignment of */ - BinaryFormula& operator= /* BinaryFormula */ - (const BinaryFormula& f); /* objects. */ - -public: - bool operator<(const LtlFormula& f) const; /* ``Less than'' - * comparison. - */ - - FormulaType what() const; /* Tells the type of the - * formula. - */ - - friend class LtlFormula; /* Friend declarations. */ - - friend class LtlNegation; - friend class LtlNext; - friend class LtlFinally; - friend class LtlGlobally; - - friend class LtlDisjunction; - friend class LtlConjunction; - friend class LtlImplication; - friend class LtlEquivalence; - friend class LtlXor; - friend class LtlUntil; - friend class LtlV; - friend class LtlWeakUntil; - friend class LtlStrongRelease; - friend class LtlBefore; - - friend class PathEvaluator; - -private: - bool eval(const BitArray& valuation) const; /* Returns the truth value - * of the formula in a - * given truth assignment. - */ - - LtlFormula* subformula1; /* Pointer to the first - * operand of the binary - * operator. - */ - - LtlFormula* subformula2; /* Pointer to the second - * operand. - */ -}; - - - -/****************************************************************************** - * - * A class for disjunction operator. - * - *****************************************************************************/ - -class LtlDisjunction -{ -public: - static const char prefix_symbol[]; /* Symbols for printing */ - static const char infix_symbol[]; /* the formula. */ - - static const FormulaType type = LTL_DISJUNCTION; /* Type of the formula. */ - - static bool eval /* Evaluates the */ - (const BitArray& valuation, /* disjunctive formula */ - const LtlFormula* f1, /* in a given truth */ - const LtlFormula* f2); /* assignment. */ -}; - - - -/****************************************************************************** - * - * A class for conjunction operator. - * - *****************************************************************************/ - -class LtlConjunction -{ -public: - static const char prefix_symbol[]; /* Symbols for printing */ - static const char infix_symbol[]; /* the formula. */ - - static const FormulaType type = LTL_CONJUNCTION; /* Type of the formula. */ - - static bool eval /* Evaluates the */ - (const BitArray& valuation, /* conjunctive formula */ - const LtlFormula* f1, /* in a given truth */ - const LtlFormula* f2); /* assignment. */ -}; - - - -/****************************************************************************** - * - * A class for implication operator. - * - *****************************************************************************/ - -class LtlImplication -{ -public: - static const char prefix_symbol[]; /* Symbols for printing */ - static const char infix_symbol[]; /* the formula. */ - - static const FormulaType type = LTL_IMPLICATION; /* Type of the formula. */ - - static bool eval /* Evaluates the */ - (const BitArray& valuation, /* implication formula */ - const LtlFormula* f1, /* in a given truth */ - const LtlFormula* f2); /* assignment. */ -}; - - - -/****************************************************************************** - * - * A class for equivalence operator. - * - *****************************************************************************/ - -class LtlEquivalence -{ -public: - static const char prefix_symbol[]; /* Symbols for printing */ - static const char infix_symbol[]; /* the formula. */ - - static const FormulaType type = LTL_EQUIVALENCE; /* Type of the formula. */ - - static bool eval /* Evaluates the */ - (const BitArray& valuation, /* equivalence formula */ - const LtlFormula* f1, /* in a given truth */ - const LtlFormula* f2); /* assignment. */ -}; - - - -/****************************************************************************** - * - * A class for the ``exclusive or'' operator. - * - *****************************************************************************/ - -class LtlXor -{ -public: - static const char prefix_symbol[]; /* Symbols for printing */ - static const char infix_symbol[]; /* the formula. */ - - static const FormulaType type = LTL_XOR; /* Type of the formula. */ - - static bool eval /* Evaluates the ``xor'' */ - (const BitArray& valuation, /* formula in a given */ - const LtlFormula* f1, /* truth assignment. */ - const LtlFormula* f2); -}; - - - -/****************************************************************************** - * - * A class for `Until' operator. - * - *****************************************************************************/ - -class LtlUntil -{ -public: - static const char prefix_symbol[]; /* Symbols for printing */ - static const char infix_symbol[]; /* the formula. */ - - static const FormulaType type = LTL_UNTIL; /* Type of the formula. */ - - static bool eval /* Evaluates the */ - (const BitArray& valuation, /* "Until" formula in a */ - const LtlFormula*, /* given truth */ - const LtlFormula* f2); /* assignment. */ -}; - - - -/****************************************************************************** - * - * A class for `V' (the dual of `Until') operator. - * - *****************************************************************************/ - -class LtlV -{ -public: - static const char prefix_symbol[]; /* Symbols for printing */ - static const char infix_symbol[]; /* the formula. */ - - static const FormulaType type = LTL_V; /* Type of the formula. */ - - static bool eval /* Evaluates the "V" */ - (const BitArray& valuation, /* formula in a given */ - const LtlFormula*, /* truth assignment. */ - const LtlFormula* f2); -}; - - - -/****************************************************************************** - * - * A class for `weak until' operator. - * - *****************************************************************************/ - -class LtlWeakUntil -{ -public: - static const char prefix_symbol[]; /* Symbols for printing */ - static const char infix_symbol[]; /* the formula. */ - - static const FormulaType type = LTL_WEAK_UNTIL; /* Type of the formula. */ - - static bool eval /* Evaluates the "weak */ - (const BitArray& valuation, /* until" formula in a */ - const LtlFormula* f1, /* given truth */ - const LtlFormula* f2); /* assignment. */ -}; - - - -/****************************************************************************** - * - * A class for `strong release' operator. - * - *****************************************************************************/ - -class LtlStrongRelease -{ -public: - static const char prefix_symbol[]; /* Symbols for printing */ - static const char infix_symbol[]; /* the formula. */ - - static const FormulaType type /* Type of the formula. */ - = LTL_STRONG_RELEASE; - - static bool eval /* Evaluates the "strong */ - (const BitArray& valuation, /* release" formula in a */ - const LtlFormula* f1, /* given truth */ - const LtlFormula* f2); /* assignment. */ -}; - - - -/****************************************************************************** - * - * A class for `before' operator. - * - *****************************************************************************/ - -class LtlBefore -{ -public: - static const char prefix_symbol[]; /* Symbols for printing */ - static const char infix_symbol[]; /* the formula. */ - - static const FormulaType type = LTL_BEFORE; /* Type of the formula. */ - - static bool eval /* Evaluates the */ - (const BitArray& valuation, /* "before" formula in a */ - const LtlFormula*, /* given truth */ - const LtlFormula* f2); /* assignment. */ -}; - - - -/****************************************************************************** - * - * Type definitions for the different binary LTL formulae to make them - * accessible without using the template instantiation syntax. - * - *****************************************************************************/ - -typedef BinaryFormula Or; -typedef BinaryFormula And; -typedef BinaryFormula Imply; -typedef BinaryFormula Equiv; -typedef BinaryFormula Xor; -typedef BinaryFormula Until; -typedef BinaryFormula V; -typedef BinaryFormula WeakUntil; -typedef BinaryFormula StrongRelease; -typedef BinaryFormula Before; - - - -/****************************************************************************** - * - * Inline function definitions for class LtlFormula. - * - *****************************************************************************/ - -/* ========================================================================= */ -inline LtlFormula::LtlFormula() : refcount(1) -/* ---------------------------------------------------------------------------- - * - * Description: Constructor for class LtlFormula. Initializes the attributes - * of the base class LtlFormula. - * - * Arguments: None. - * - * Returns: Nothing. - * - * --------------------------------------------------------------------------*/ -{ -} - -/* ========================================================================= */ -inline LtlFormula::~LtlFormula() -/* ---------------------------------------------------------------------------- - * - * Description: Destructor for class LtlFormula. Deallocates the memory - * reserved for the formula. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -inline void LtlFormula::destruct(LtlFormula* f) -/* ---------------------------------------------------------------------------- - * - * Description: Updates the shared formula storage to remove one reference to - * the formula. The formula object is deleted if the reference - * count becomes zero. - * - * Argument: f -- A pointer to the formula to be removed from the shared - * storage. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - if (--f->refcount == 0) - { - formula_storage.erase(f); - delete f; - } -} - -/* ========================================================================= */ -inline LtlFormula* LtlFormula::clone() -/* ---------------------------------------------------------------------------- - * - * Description: Updates the shared formula storage to add a new reference to - * `this' LtlFormula. - * - * Arguments: None. - * - * Returns: A pointer to the same formula. - * - * ------------------------------------------------------------------------- */ -{ - ++refcount; - return this; -} - -/* ========================================================================= */ -inline bool LtlFormula::evaluate - (const BitArray& valuation, const unsigned long int valuation_size) const -/* ---------------------------------------------------------------------------- - * - * Description: Computes the truth value of the formula in a given truth - * assignment for the atomic propositions in the formula. This - * function can be used to evaluate purely propositional - * formulae without the requirement to evaluate the formula with - * respect to some state space. However, if the formula - * contains temporal operators, calling this function for the - * formula is equivalent to evaluating the formula in a state - * space consisting of a single state with a self-loop (with the - * given assignment for the propositions in the state). - * - * Arguments: valuation -- A reference to a constant BitArray - * representing the truth assignment. - * valuation_size -- Number of propositions in the valuation - * (if the formula contains propositions - * with an identifier greater or equal to - * the limit, they are assumed to be false - * in the valuation). - * - * Returns: The truth value of the formula. - * - * ------------------------------------------------------------------------- */ -{ - eval_proposition_id_limit = valuation_size; - return eval(valuation); -} - -/* ========================================================================= */ -inline bool LtlFormula::evaluate(const Bitset& valuation) const -/* ---------------------------------------------------------------------------- - * - * Description: See above. - * - * Argument: valuation -- A reference to a constant Bitset representing - * the truth assignment. - * - * Returns: The truth value of the formula. - * - * ------------------------------------------------------------------------- */ -{ - return evaluate(valuation, valuation.capacity()); -} - -/* ========================================================================= */ -inline bool LtlFormula::propositional() const -/* ---------------------------------------------------------------------------- - * - * Description: Tells whether the formula contains any temporal operators. - * - * Arguments: None. - * - * Returns: true or false according to the test whether the formula is - * propositional or not. - * - * ------------------------------------------------------------------------- */ -{ - return info_flags.is_propositional; -} - -/* ========================================================================= */ -inline bool LtlFormula::constant() const -/* ---------------------------------------------------------------------------- - * - * Description: Tells whether the formula contains any non-constant atoms. - * - * Arguments: None. - * - * Returns: A truth value according to the test for the property. - * - * ------------------------------------------------------------------------- */ -{ - return info_flags.is_constant; -} - -/* ========================================================================= */ -inline LtlFormula* LtlFormula::read(istream& stream) -/* ---------------------------------------------------------------------------- - * - * Description: Constructs an LtlFormula by parsing input from a stream. - * - * Arguments: stream -- A reference to an input stream. - * - * Returns: The constructed LtlFormula. - * - * ------------------------------------------------------------------------- */ -{ - return parseFormula(stream); -} - -/* ========================================================================= */ -inline void LtlFormula::print(ostream& stream, OutputMode mode) const -/* ---------------------------------------------------------------------------- - * - * Description: Writes the formula to a stream. - * - * Arguments: stream -- A reference to an output stream. - * mode -- Chooses between prefix and infix notation. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - Exceptional_ostream estream(&stream, ios::badbit | ios::failbit); - print(estream, mode); -} - -/* ========================================================================= */ -inline ostream& operator<<(ostream& stream, const LtlFormula& f) -/* ---------------------------------------------------------------------------- - * - * Description: Alternative method for printing an LTL formula by using the - * << operator. - * - * Arguments: stream -- A reference to the output stream to which the - * formula should be printed. - * f -- A reference to the constant LTL formula. - * - * Returns: A reference to the output stream (to support chaining of the - * << operators). - * - * --------------------------------------------------------------------------*/ -{ - f.print(stream); - return stream; -} - -/* ========================================================================= */ -inline Exceptional_ostream& operator<< - (Exceptional_ostream& stream, const LtlFormula& f) -/* ---------------------------------------------------------------------------- - * - * Description: Alternative method for printing an LTL formula by using the - * << operator. - * - * Arguments: stream -- A reference to the exception-aware output stream - * to which the formula should be printed. - * f -- A reference to the constant LTL formula. - * - * Returns: A reference to the output stream (to support chaining of the - * << operators). - * - * --------------------------------------------------------------------------*/ -{ - f.print(stream, LTL_INFIX); - return stream; -} - -/* ========================================================================= */ -inline LtlFormula& LtlFormula::insertToStorage(LtlFormula* f) -/* ---------------------------------------------------------------------------- - * - * Description: Inserts a formula to the formula storage. - * - * Arguments: f -- The formula to be inserted. - * - * Returns: A pointer to the formula. - * - * ------------------------------------------------------------------------- */ -{ - set::iterator inserter = formula_storage.find(f); - if (inserter != formula_storage.end()) - { - delete f; - ++(*inserter)->refcount; - return **inserter; - } - - formula_storage.insert(f); - return *f; -} - - - -/****************************************************************************** - * - * Template function definitions for class LtlFormula. - * - *****************************************************************************/ - -/* ========================================================================= */ -template -void LtlFormula::traverse(F& f, int mode) const -/* ---------------------------------------------------------------------------- - * - * Description: Implements a depth-first traversal algorithm in the parse - * tree of an LtlFormula. - * - * Arguments: f -- A reference to a function object implementing an - * operation that will be performed in each node of - * the parse tree of the formula. The class F must - * define the member function - * void operator()(const LtlFormula* f, int operand). - * The function will then be called by the depth-first - * traversal function such that - * `f' - * points to the subformula rooted at the node, and - * - * `operand' - * is an integer that can be used to determine the - * state of the depth-first search. The possible - * values are: - * 0 -- The depth-first has just entered the - * node from its parent node. - * 1 -- The depth-first search has traversed - * the left-hand subtree of the node and - * will proceed next to the right-hand - * subtree of the node. (`operand' may - * have this value only if the node has - * two children, i.e., if the node is - * associated with a binary operator.) - * 2 -- The depth-first search has traversed - * all subtrees of the node and will - * backtrack to the parent node. - * mode -- A bitwise combination of the constants - * `LTL_PREORDER', `LTL_INORDER' and `LTL_POSTORDER'. - * The value of `mode' controls when the node - * operation `f' should be performed. If - * `mode & LTL_PREORDER != 0', the node operation will - * be performed when the depth-first search has just - * entered the node. If `mode & LTL_INORDER != 0' and - * the node is associated with a binary operator, the - * node operation will be performed when the depth- - * first search is about to enter the right-hand - * subtree of the node. If `mode & LTL_POSTORDER != 0' - * the operation will be performed just before the - * depth-first search backtracks from the node. (If - * the current parse tree node is a leaf node, the - * node operation is always performed once using the - * value 0 for the `operand' parameter.) - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - if (what() == LTL_ATOM || what() == LTL_TRUE || what() == LTL_FALSE) - { - f(this, 0); - return; - } - - if (mode & LTL_PREORDER) - f(this, 0); - - switch (what()) - { - case LTL_NEGATION : - static_cast(this)->subformula->traverse(f, mode); - goto postorder_visit; - - case LTL_NEXT : - static_cast(this)->subformula->traverse(f, mode); - goto postorder_visit; - - case LTL_FINALLY : - static_cast(this)->subformula->traverse(f, mode); - goto postorder_visit; - - case LTL_GLOBALLY : - static_cast(this)->subformula->traverse(f, mode); - goto postorder_visit; - - case LTL_CONJUNCTION : - static_cast(this)->subformula1->traverse(f, mode); - break; - - case LTL_DISJUNCTION : - static_cast(this)->subformula1->traverse(f, mode); - break; - - case LTL_IMPLICATION : - static_cast(this)->subformula1->traverse(f, mode); - break; - - case LTL_EQUIVALENCE : - static_cast(this)->subformula1->traverse(f, mode); - break; - - case LTL_XOR : - static_cast(this)->subformula1->traverse(f, mode); - break; - - case LTL_UNTIL : - static_cast(this)->subformula1->traverse(f, mode); - break; - - case LTL_V : - static_cast(this)->subformula1->traverse(f, mode); - break; - - case LTL_WEAK_UNTIL : - static_cast(this)->subformula1->traverse(f, mode); - break; - - case LTL_STRONG_RELEASE : - static_cast(this)->subformula1->traverse(f, mode); - break; - - default : /* LTL_BEFORE */ - static_cast(this)->subformula1->traverse(f, mode); - break; - } - - if (mode & LTL_INORDER) - f(this, 1); - - switch (what()) - { - case LTL_CONJUNCTION : - static_cast(this)->subformula2->traverse(f, mode); - break; - - case LTL_DISJUNCTION : - static_cast(this)->subformula2->traverse(f, mode); - break; - - case LTL_IMPLICATION : - static_cast(this)->subformula2->traverse(f, mode); - break; - - case LTL_EQUIVALENCE : - static_cast(this)->subformula2->traverse(f, mode); - break; - - case LTL_XOR : - static_cast(this)->subformula2->traverse(f, mode); - break; - - case LTL_UNTIL : - static_cast(this)->subformula2->traverse(f, mode); - break; - - case LTL_V : - static_cast(this)->subformula2->traverse(f, mode); - break; - - case LTL_WEAK_UNTIL : - static_cast(this)->subformula2->traverse(f, mode); - break; - - case LTL_STRONG_RELEASE : - static_cast(this)->subformula2->traverse(f, mode); - break; - - default : /* LTL_BEFORE */ - static_cast(this)->subformula2->traverse(f, mode); - break; - } - -postorder_visit: - if (mode & LTL_POSTORDER) - f(this, 2); -} - - - -/****************************************************************************** - * - * Inline function definitions for class LtlFormula::ptr_less. - * - *****************************************************************************/ - -/* ========================================================================= */ -inline bool LtlFormula::ptr_less::operator() - (const LtlFormula* f1, const LtlFormula* f2) const -/* ---------------------------------------------------------------------------- - * - * Description: This function maps the `less than' relation between two - * pointers to LtlFormula objects to the corresponding relation - * between the formulae. Used when storing pointers to - * LtlFormulae into STL containers. - * - * Arguments: f1, f2 -- Two pointers to LtlFormulae. - * - * Returns: A truth value according to the relation between the formulae. - * - * ------------------------------------------------------------------------- */ -{ - return f1->operator<(*f2); -} - - - -/****************************************************************************** - * - * Inline function definitions for class Atom. - * - *****************************************************************************/ - -/* ========================================================================= */ -inline Atom& Atom::construct(long int a) -/* ---------------------------------------------------------------------------- - * - * Description: Inserts a new propositional atom into the shared formula - * storage. - * - * Arguments: a -- Identifier of the atom (>=0). - * - * Returns: A reference to the atom. - * - * ------------------------------------------------------------------------- */ -{ - if (a < 0) - throw Exception("cannot construct an atomic proposition with a negative " - "id"); - - return static_cast(LtlFormula::insertToStorage(new Atom(a))); -} - -/* ========================================================================= */ -inline Atom::Atom(long int a) : atom(a) -/* ---------------------------------------------------------------------------- - * - * Description: Constructor for class Atom. Creates a new propositional atom. - * - * Argument: a -- Identifier of a propositional variable. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - info_flags.is_propositional = 1; - info_flags.is_constant = 0; -} - -/* ========================================================================= */ -inline Atom::~Atom() -/* ---------------------------------------------------------------------------- - * - * Description: Destructor for class Atom. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -inline long int Atom::getId() const -/* ---------------------------------------------------------------------------- - * - * Description: Tells the identifier of an atomic proposition. - * - * Arguments: None. - * - * Returns: Identifier of the atomic proposition. - * - * ------------------------------------------------------------------------- */ -{ - return atom; -} - -/* ========================================================================= */ -inline bool Atom::operator<(const LtlFormula& f) const -/* ---------------------------------------------------------------------------- - * - * Description: ``Less than'' comparison between an Atom and an LtlFormula. - * An Atom is ``less than'' another LtlFormula if and only if - * the corresponding relation holds between the integer type - * identifiers between the formulae or if the other formula is - * also an Atom, but it refers to a propositional variable - * with a larger identifier. - * - * Arguments: f -- A reference to an LtlFormula. - * - * Returns: A truth value according to the result of the comparison. - * - * ------------------------------------------------------------------------- */ -{ - if (what() < f.what()) - return true; - - if (f.what() < what()) - return false; - - return atom < static_cast(f).atom; -} - -/* ========================================================================= */ -inline FormulaType Atom::what() const -/* ---------------------------------------------------------------------------- - * - * Description: Returns the `formula type' of the atom, i.e. the constant - * LTL_ATOM. - * - * Arguments: None. - * - * Returns: The constant LTL_ATOM. - * - * ------------------------------------------------------------------------- */ -{ - return LTL_ATOM; -} - -/* ========================================================================= */ -inline bool Atom::eval(const BitArray& valuation) const -/* ---------------------------------------------------------------------------- - * - * Description: Returns the truth value of the atom in a given truth - * assignment. - * - * Argument: valuation -- A reference to a constant BitArray - * representing the truth assignment. - * - * Returns: The truth value of the atom in the assignment. (If the - * atom identifier exceeds - * `LtlFormula::eval_proposition_id_limit' representing the - * assignment, the truth value of the atom is assumed to be - * false.) - * - * ------------------------------------------------------------------------- */ -{ - return (static_cast(atom) - < LtlFormula::eval_proposition_id_limit - && valuation.test(atom)); -} - - - -/****************************************************************************** - * - * Inline function definitions for template class Constant. - * - *****************************************************************************/ - -/* ========================================================================= */ -template -inline Constant& Constant::construct() -/* ---------------------------------------------------------------------------- - * - * Description: Inserts a new propositional constant into the shared formula - * storage. - * - * Arguments: None. - * - * Returns: A reference to the constant. - * - * ------------------------------------------------------------------------- */ -{ - return static_cast&> - (LtlFormula::insertToStorage(new Constant())); -} - -/* ========================================================================= */ -template -inline Constant::Constant() -/* ---------------------------------------------------------------------------- - * - * Description: Constructor for a LTL constant. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - info_flags.is_propositional = 1; - info_flags.is_constant = 1; -} - -/* ========================================================================= */ -template -inline Constant::~Constant() -/* ---------------------------------------------------------------------------- - * - * Description: Destructor for a LTL constant. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -template -inline bool Constant::operator<(const LtlFormula& f) const -/* ---------------------------------------------------------------------------- - * - * Description: ``Less than'' comparison between a constant and an - * LtlFormula. A constant is ``less than'' another LtlFormula if - * and only if the corresponding relation holds between the - * integer type identifiers between the formulae. - * - * Arguments: f -- A reference to an LtlFormula. - * - * Returns: A truth value according to the result of the comparison. - * - * ------------------------------------------------------------------------- */ -{ - return (what() < f.what()); -} - -/* ========================================================================= */ -template -inline FormulaType Constant::what() const -/* ---------------------------------------------------------------------------- - * - * Description: Tells the type of the constant. - * - * Arguments: None. - * - * Returns: Type of the constant as a value of type FormulaType. - * - * ------------------------------------------------------------------------- */ -{ - return Symbol::type; -} - -/* ========================================================================= */ -template -inline bool Constant::eval(const BitArray&) const -/* ---------------------------------------------------------------------------- - * - * Description: Evaluates the constant in a truth assignment, i.e., simply - * returns the constant's truth value. - * - * Argument: A reference to a constant BitArray (required in order to - * satisfy the class interface restrictions). - * - * Returns: Truth value of the constant. - * - * ------------------------------------------------------------------------- */ -{ - return Symbol::eval(); -} - - - -/****************************************************************************** - * - * Inline function definitions for class True. - * - *****************************************************************************/ - -/* ========================================================================= */ -inline bool LtlTrue::eval() -/* ---------------------------------------------------------------------------- - * - * Description: Tells the truth value of a `true' constant. - * - * Arguments: None. - * - * Returns: true - * - * ------------------------------------------------------------------------- */ -{ - return true; -} - - - -/****************************************************************************** - * - * Inline function definitions for class False. - * - *****************************************************************************/ - -/* ========================================================================= */ -inline bool LtlFalse::eval() -/* ---------------------------------------------------------------------------- - * - * Description: Tells the truth value of a `false' constant. - * - * Arguments: None. - * - * Returns: false - * - * ------------------------------------------------------------------------- */ -{ - return false; -} - - - -/****************************************************************************** - * - * Inline function definitions for template class UnaryFormula. - * - *****************************************************************************/ - -/* ========================================================================= */ -template -inline UnaryFormula& UnaryFormula::construct(LtlFormula* f) -/* ---------------------------------------------------------------------------- - * - * Description: Inserts a new unary formula into the shared formula storage. - * - * Arguments: f -- A pointer to the subformula to be associated with the - * unary formula. After the initialization, the new - * object will ``own'' its subformula. - * - * Returns: A reference to the formula. - * - * ------------------------------------------------------------------------- */ -{ - return static_cast&> - (LtlFormula::insertToStorage(new UnaryFormula(f))); -} - -/* ========================================================================= */ -template -inline UnaryFormula& UnaryFormula::construct(LtlFormula& f) -/* ---------------------------------------------------------------------------- - * - * Description: Inserts a new unary formula into the shared formula storage. - * - * Arguments: f -- A reference to a LtlFormula to be associated with the - * unary formula. - * - * Returns: A reference to the formula. - * - * ------------------------------------------------------------------------- */ -{ - return static_cast&> - (LtlFormula::insertToStorage(new UnaryFormula - (f.clone()))); -} - -/* ========================================================================= */ -template -inline UnaryFormula::UnaryFormula(LtlFormula* f) : subformula(f) -/* ---------------------------------------------------------------------------- - * - * Description: Constructs an LTL formula with a unary operator. - * - * Argument: f -- Pointer to the subformula of the operator. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - info_flags.is_propositional = (f->propositional() - && Operator::type == LTL_NEGATION); - info_flags.is_constant = f->constant(); -} - -/* ========================================================================= */ -template -inline UnaryFormula::~UnaryFormula() -/* ---------------------------------------------------------------------------- - * - * Description: Destructor for unary LTL formulae. Releases the memory - * allocated for the operand of the unary operator. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - LtlFormula::destruct(subformula); -} - -/* ========================================================================= */ -template -inline bool UnaryFormula::operator<(const LtlFormula& f) const -/* ---------------------------------------------------------------------------- - * - * Description: ``Less than'' comparison between a unary formula and an - * LtlFormula. A unary formula is ``less than'' another - * LtlFormula if and only if the corresponding relation holds - * between the integer type identifiers between the formulae, - * or if both formulae are of the same type and the relation - * holds between their subformulae. - * - * Arguments: f -- A reference to an LtlFormula. - * - * Returns: A truth value according to the result of the comparison. - * - * ------------------------------------------------------------------------- */ -{ - if (what() < f.what()) - return true; - - if (f.what() < what()) - return false; - - return subformula->operator< - (*(static_cast&>(f).subformula)); -} - -/* ========================================================================= */ -template -inline FormulaType UnaryFormula::what() const -/* ---------------------------------------------------------------------------- - * - * Description: Tells the exact type of the unary formula. - * - * Arguments: None. - * - * Returns: Type of the formula (a FormulaType constant). - * - * ------------------------------------------------------------------------- */ -{ - return Operator::type; -} - -/* ========================================================================= */ -template -inline bool UnaryFormula::eval(const BitArray& valuation) const -/* ---------------------------------------------------------------------------- - * - * Description: Evaluates the unary formula in a given truth assignment (in - * a state space consisting of a single state with a transition - * to itself). - * - * Argument: A reference to a constant BitArray, defining the truth - * assignment. - * - * Returns: Truth value of the formula in the assignment. - * - * ------------------------------------------------------------------------- */ -{ - return Operator::eval(valuation, subformula); -} - - - -/****************************************************************************** - * - * Inline function definitions for class LtlNegation. - * - *****************************************************************************/ - -/* ========================================================================= */ -inline bool LtlNegation::eval(const BitArray& valuation, const LtlFormula* f) -/* ---------------------------------------------------------------------------- - * - * Description: Evaluates the negated formula in a given assignment for the - * propositional variables. - * - * Arguments: valuation -- A reference to a constant BitArray - * representing the truth assignment. - * f -- A pointer to the subformula of the negation - * operator. - * - * Returns: The truth value of the formula in the truth assignment. - * - * ------------------------------------------------------------------------- */ -{ - return (!f->eval(valuation)); -} - - - -/****************************************************************************** - * - * Inline function definitions for class LtlNext. - * - *****************************************************************************/ - -/* ========================================================================= */ -inline bool LtlNext::eval(const BitArray& valuation, const LtlFormula* f) -/* ---------------------------------------------------------------------------- - * - * Description: Evaluates the `Next' formula in a given truth assignment for - * the propositional variables (in a state space consisting of a - * single state with a transition to itself). - * - * Arguments: valuation -- A reference to a constant BitArray - * representing the truth assignment. - * f -- A pointer to the subformula of the `Next' - * operator. - * - * Returns: The truth value of the formula in the assignment. - * - * ------------------------------------------------------------------------- */ -{ - return f->eval(valuation); -} - - - -/****************************************************************************** - * - * Inline function definitions for class LtlFinally. - * - *****************************************************************************/ - -/* ========================================================================= */ -inline bool LtlFinally::eval(const BitArray& valuation, const LtlFormula* f) -/* ---------------------------------------------------------------------------- - * - * Description: Evaluates the `Finally' formula in a given truth assignment - * for the propositional variables (in a state space consisting - * of a single state with a transition to itself). - * - * Arguments: valuation -- A reference to a constant BitArray - * representing the truth assignment. - * f -- A pointer to the subformula of the `Finally' - * operator. - * - * Returns: The truth value of the formula in the assignment. - * - * ------------------------------------------------------------------------- */ -{ - return f->eval(valuation); -} - - - -/****************************************************************************** - * - * Inline function definitions for class LtlGlobally. - * - *****************************************************************************/ - -/* ========================================================================= */ -inline bool LtlGlobally::eval(const BitArray& valuation, const LtlFormula* f) -/* ---------------------------------------------------------------------------- - * - * Description: Evaluates the `Globally' formula in a given truth assignment - * for the propositional variables (in a state space consisting - * of a single state with a transition to itself). - * - * Arguments: valuation -- A reference to a constant BitArray - * representing the truth assignment. - * f -- A pointer to the subformula of the `Globally' - * operator. - * - * Returns: The truth value of the formula in the assignment. - * - * ------------------------------------------------------------------------- */ -{ - return f->eval(valuation); -} - - - -/****************************************************************************** - * - * Inline function definitions for template class BinaryFormula. - * - *****************************************************************************/ - -/* ========================================================================= */ -template -inline BinaryFormula& -BinaryFormula::construct(LtlFormula* f1, LtlFormula* f2) -/* ---------------------------------------------------------------------------- - * - * Description: Inserts a new binary formula into the shared formula storage. - * - * Arguments: f1, f2 -- Pointers to the subformulae to be associated with - * the binary formula. The new returned object will - * ``own'' its both subformulae. - * - * Returns: A reference to the formula. - * - * ------------------------------------------------------------------------- */ -{ - return static_cast&> - (LtlFormula::insertToStorage(new BinaryFormula(f1, f2))); -} - -/* ========================================================================= */ -template -inline BinaryFormula& -BinaryFormula::construct(LtlFormula& f1, LtlFormula& f2) -/* ---------------------------------------------------------------------------- - * - * Description: Inserts a new binary formula into the shared formula storage. - * - * Arguments: f1, f2 -- References to two LtlFormulae to be associated - * with the binary formula. - * - * Returns: A reference to the formula. - * - * ------------------------------------------------------------------------- */ -{ - return static_cast&> - (LtlFormula::insertToStorage(new BinaryFormula - (f1.clone(), f2.clone()))); -} - -/* ========================================================================= */ -template -inline BinaryFormula& -BinaryFormula::construct(LtlFormula* f1, LtlFormula& f2) -/* ---------------------------------------------------------------------------- - * - * Description: Inserts a new binary formula into the shared formula storage. - * - * Arguments: f1 -- A pointer to a LtlFormula to be associated with the - * binary formula (the ``left-hand'' subformula). - * f2 -- A reference to a LtlFormula to be associated with the - * binary formula (the ``right-hand'' subformula). - * - * Returns: A reference to the formula. - * - * ------------------------------------------------------------------------- */ -{ - return static_cast&> - (LtlFormula::insertToStorage(new BinaryFormula - (f1, f2.clone()))); -} - -/* ========================================================================= */ -template -inline BinaryFormula& -BinaryFormula::construct(LtlFormula& f1, LtlFormula* f2) -/* ---------------------------------------------------------------------------- - * - * Description: Inserts a new binary formula into the shared formula storage. - * - * Arguments: f1 -- A reference to a LtlFormula to be associated with the - * binary formula (the ``left-hand'' subformula). - * f2 -- A pointer to a LtlFormula to be associated with the - * binary formula (the ``right-hand'' subformula). - * - * Returns: A reference to the formula. - * - * ------------------------------------------------------------------------- */ -{ - return static_cast&> - (LtlFormula::insertToStorage(new BinaryFormula - (f1.clone(), f2))); -} - -/* ========================================================================= */ -template -inline BinaryFormula::BinaryFormula(LtlFormula* f1, LtlFormula* f2) : - subformula1(f1), subformula2(f2) -/* ---------------------------------------------------------------------------- - * - * Description: Constructs a binary LTL formula. - * - * Arguments: f1 -- Pointer to an LTL formula to be associated with the - * new formula as its left operand. - * f2 -- Pointer to an LTL formula to be associated with the - * new formula as its right operand. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - info_flags.is_propositional = (f1->propositional() - && f2->propositional() - && Operator::type != LTL_UNTIL - && Operator::type != LTL_V - && Operator::type != LTL_WEAK_UNTIL - && Operator::type != LTL_STRONG_RELEASE - && Operator::type != LTL_BEFORE); - info_flags.is_constant = (f1->constant() && f2->constant()); -} - -/* ========================================================================= */ -template -inline BinaryFormula::~BinaryFormula() -/* ---------------------------------------------------------------------------- - * - * Description: Destructor for binary LTL formulae. Releases the memory - * allocated for the operands of the binary operator. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - LtlFormula::destruct(subformula1); - LtlFormula::destruct(subformula2); -} - -/* ========================================================================= */ -template -inline bool BinaryFormula::operator<(const LtlFormula& f) const -/* ---------------------------------------------------------------------------- - * - * Description: ``Less than'' comparison between a binary formula and an - * LtlFormula. A binary formula is ``less than'' another - * LtlFormula if and only if - * (1) the corresponding relation holds between the integer - * type identifiers between the formulae; - * OR (2) both formulae are of the same type and the relation - * holds between their ``left-hand'' subformulae; - * OR (3) both formulae are of the same type, their - * ``left-hand'' subformulae are of the same type, and - * the relation holds between the ``right-hand'' - * subformulae - * - * Arguments: f -- A reference to an LtlFormula. - * - * Returns: A truth value according to the result of the comparison. - * - * ------------------------------------------------------------------------- */ -{ - if (what() < f.what()) - return true; - - if (f.what() < what()) - return false; - - const BinaryFormula& ff - = static_cast&>(f); - - if (subformula1->operator<(*ff.subformula1)) - return true; - - if (ff.subformula1->operator<(*subformula1)) - return false; - - return (subformula2->operator<(*ff.subformula2)); -} - -/* ========================================================================= */ -template -inline FormulaType BinaryFormula::what() const -/* ---------------------------------------------------------------------------- - * - * Description: Tells the exact type of the binary formula. - * - * Arguments: None. - * - * Returns: Type of the formula (a FormulaType constant). - * - * ------------------------------------------------------------------------- */ -{ - return Operator::type; -} - -/* ========================================================================= */ -template -inline bool BinaryFormula::eval(const BitArray& valuation) const -/* ---------------------------------------------------------------------------- - * - * Description: Evaluates the binary formula in a given truth assignment (in - * a state space consisting of a single state with a transition - * to itself). - * - * Argument: A reference to a constant BitArray, defining the truth - * assignment. - * - * Returns: Truth value of the formula in the assignment. - * - * ------------------------------------------------------------------------- */ -{ - return Operator::eval(valuation, subformula1, subformula2); -} - - - -/****************************************************************************** - * - * Inline function definitions for class LtlDisjunction. - * - *****************************************************************************/ - -/* ========================================================================= */ -inline bool LtlDisjunction::eval - (const BitArray& valuation, const LtlFormula* f1, const LtlFormula* f2) -/* ---------------------------------------------------------------------------- - * - * Description: Evaluates the disjunctive formula in a given assignment for - * the propositional variables. - * - * Arguments: valuation -- A reference to a constant BitArray - * representing the truth assignment. - * f1, f2 -- Pointers to the subformulae of the disjunction - * operator. - * - * Returns: The truth value of the formula in the truth assignment. - * - * ------------------------------------------------------------------------- */ -{ - return (f1->eval(valuation) || f2->eval(valuation)); -} - - - -/****************************************************************************** - * - * Inline function definitions for class LtlConjunction. - * - *****************************************************************************/ - -/* ========================================================================= */ -inline bool LtlConjunction::eval - (const BitArray& valuation, const LtlFormula* f1, const LtlFormula* f2) -/* ---------------------------------------------------------------------------- - * - * Description: Evaluates the conjunctive formula in a given assignment for - * the propositional variables. - * - * Arguments: valuation -- A reference to a constant BitArray - * representing the truth assignment. - * f1, f2 -- Pointers to the subformulae of the conjunction - * operator. - * - * Returns: The truth value of the formula in the truth assignment. - * - * ------------------------------------------------------------------------- */ -{ - return (f1->eval(valuation) && f2->eval(valuation)); -} - - - -/****************************************************************************** - * - * Inline function definitions for class LtlImplication. - * - *****************************************************************************/ - -/* ========================================================================= */ -inline bool LtlImplication::eval - (const BitArray& valuation, const LtlFormula* f1, const LtlFormula* f2) -/* ---------------------------------------------------------------------------- - * - * Description: Evaluates the implication in a given assignment for the - * propositional variables. - * - * Arguments: valuation -- A reference to a constant BitArray - * representing the truth assignment. - * f1, f2 -- Pointers to the subformulae of the implication - * operator. - * - * Returns: The truth value of the formula in the truth assignment. - * - * ------------------------------------------------------------------------- */ -{ - return (!f1->eval(valuation) || f2->eval(valuation)); -} - - - -/****************************************************************************** - * - * Inline function definitions for class LtlEquivalence. - * - *****************************************************************************/ - -/* ========================================================================= */ -inline bool LtlEquivalence::eval - (const BitArray& valuation, const LtlFormula* f1, const LtlFormula* f2) -/* ---------------------------------------------------------------------------- - * - * Description: Evaluates the equivalence in a given assignment for the - * propositional variables. - * - * Arguments: valuation -- A reference to a constant BitArray - * representing the truth assignment. - * f1, f2 -- Pointers to the subformulae of the equivalence - * operator. - * - * Returns: The truth value of the formula in the truth assignment. - * - * ------------------------------------------------------------------------- */ -{ - return (f1->eval(valuation) == f2->eval(valuation)); -} - - - -/****************************************************************************** - * - * Inline function definitions for class LtlXor. - * - *****************************************************************************/ - -/* ========================================================================= */ -inline bool LtlXor::eval - (const BitArray& valuation, const LtlFormula* f1, const LtlFormula* f2) -/* ---------------------------------------------------------------------------- - * - * Description: Evaluates the exclusive disjunction in a given assignment for - * the atomic propositions. - * - * Arguments: valuation -- A reference to a constant BitArray - * representing the truth assignment. - * f1, f2 -- Pointers to the subformulae of the ``exclusive - * or'' operator. - * - * Returns: The truth value of the formula in the truth assignment. - * - * ------------------------------------------------------------------------- */ -{ - return (f1->eval(valuation) != f2->eval(valuation)); -} - - - -/****************************************************************************** - * - * Inline function definitions for class LtlUntil. - * - *****************************************************************************/ - -/* ========================================================================= */ -inline bool LtlUntil::eval - (const BitArray& valuation, const LtlFormula*, const LtlFormula* f2) -/* ---------------------------------------------------------------------------- - * - * Description: Evaluates the `Until' formula in a given truth assignment - * for the propositional variables (in a state space consisting - * of a single state with a transition to itself). - * - * Arguments: valuation -- A reference to a constant BitArray - * representing the truth assignment. - * f1, f2 -- Pointers to the subformulae of the `Until' - * operator. - * - * Returns: The truth value of the formula in the assignment. - * - * ------------------------------------------------------------------------- */ -{ - return f2->eval(valuation); -} - - - -/****************************************************************************** - * - * Inline function definitions for class LtlV. - * - *****************************************************************************/ - -/* ========================================================================= */ -inline bool LtlV::eval - (const BitArray& valuation, const LtlFormula*, const LtlFormula* f2) -/* ---------------------------------------------------------------------------- - * - * Description: Evaluates the `Release' formula in a given truth assignment - * for the propositional variables (in a state space consisting - * of a single state with a transition to itself). - * - * Arguments: valuation -- A reference to a constant BitArray - * representing the truth assignment. - * f1, f2 -- A pointer to the subformula of the `V' - * operator. - * - * Returns: The truth value of the formula in the assignment. - * - * ------------------------------------------------------------------------- */ -{ - return f2->eval(valuation); -} - - - -/****************************************************************************** - * - * Inline function definitions for class LtlWeakUntil. - * - *****************************************************************************/ - -/* ========================================================================= */ -inline bool LtlWeakUntil::eval - (const BitArray& valuation, const LtlFormula* f1, const LtlFormula* f2) -/* ---------------------------------------------------------------------------- - * - * Description: Evaluates the `Weak until' formula in a given truth - * assignment for the propositional variables (in a state space - * consisting of a single state with a transition to itself). - * - * Arguments: valuation -- A reference to a constant BitArray - * representing the truth assignment. - * f1, f2 -- Pointers to the subformulae of the `Weak - * until' operator. - * - * Returns: The truth value of the formula in the assignment. - * - * ------------------------------------------------------------------------- */ -{ - return (f1->eval(valuation) || f2->eval(valuation)); -} - - - -/****************************************************************************** - * - * Inline function definitions for class LtlStrongRelease. - * - *****************************************************************************/ - -/* ========================================================================= */ -inline bool LtlStrongRelease::eval - (const BitArray& valuation, const LtlFormula* f1, const LtlFormula* f2) -/* ---------------------------------------------------------------------------- - * - * Description: Evaluates the `Strong release' formula in a given truth - * assignment for the propositional variables (in a state space - * consisting of a single state with a transition to itself). - * - * Arguments: valuation -- A reference to a constant BitArray - * representing the truth assignment. - * f1, f2 -- Pointers to the subformulae of the `String - * release' operator. - * - * Returns: The truth value of the formula in the assignment. - * - * ------------------------------------------------------------------------- */ -{ - return (f1->eval(valuation) && f2->eval(valuation)); -} - - - -/****************************************************************************** - * - * Inline function definitions for class LtlBefore. - * - *****************************************************************************/ - -/* ========================================================================= */ -inline bool LtlBefore::eval - (const BitArray& valuation, const LtlFormula*, const LtlFormula* f2) -/* ---------------------------------------------------------------------------- - * - * Description: Evaluates the `Before' formula in a given truth assignment - * for the propositional variables (in a state space consisting - * of a single state with a transition to itself). - * - * Arguments: valuation -- A reference to a constant BitArray - * representing the truth assignment. - * f1, f2 -- Pointers to the subformulae of the `String - * release' operator. - * - * Returns: The truth value of the formula in the assignment. - * - * ------------------------------------------------------------------------- */ -{ - return !f2->eval(valuation); -} - - - -/****************************************************************************** - * - * Inline function definitions for class LtlFormula::ParseErrorException. - * - *****************************************************************************/ - -/* ========================================================================= */ -inline LtlFormula::ParseErrorException::ParseErrorException - (const string& msg) : - Exception(msg) -/* ---------------------------------------------------------------------------- - * - * Description: Constructor for class LtlFormula::ParseErrorException. - * Initializes an exception object with an error message. - * - * Argument: msg -- Error message. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -inline LtlFormula::ParseErrorException::~ParseErrorException() throw() -/* ---------------------------------------------------------------------------- - * - * Description: Destructor for class LtlFormula::ParseErrorException. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -inline LtlFormula::ParseErrorException& -LtlFormula::ParseErrorException::operator=(const ParseErrorException& e) -/* ---------------------------------------------------------------------------- - * - * Description: Assignment operator for class - * LtlFormula::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 /* !LTLFORMULA_H */ diff --git a/lbtt/src/Makefile.am b/lbtt/src/Makefile.am deleted file mode 100644 index 3dd7ad820..000000000 --- a/lbtt/src/Makefile.am +++ /dev/null @@ -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@ diff --git a/lbtt/src/NeverClaim-lex.ll b/lbtt/src/NeverClaim-lex.ll deleted file mode 100644 index 54f8d3cb9..000000000 --- a/lbtt/src/NeverClaim-lex.ll +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 - * Heikki Tauriainen - * - * 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 -#include -#include -#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(0)) - { - current_neverclaim_line = ""; - current_neverclaim_line_number++; - s = t + 1; - } - } - while (t != static_cast(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(); -} diff --git a/lbtt/src/NeverClaim-parse.y b/lbtt/src/NeverClaim-parse.y deleted file mode 100644 index 9179e0f05..000000000 --- a/lbtt/src/NeverClaim-parse.y +++ /dev/null @@ -1,301 +0,0 @@ -/* - * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008 - * Heikki Tauriainen - * - * 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 -#include -#include -#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(yyleng)) - error_pos -= yyleng; - - do - { - c = getCharacter(); - if (c != EOF && c != '\n') - current_neverclaim_line += static_cast(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 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 NC_PROPOSITION NC_TRUE NC_FALSE -%right NC_OR -%right NC_AND -%nonassoc NC_NOT - -%type 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(); -} diff --git a/lbtt/src/NeverClaim-parse_.cc b/lbtt/src/NeverClaim-parse_.cc deleted file mode 100644 index b3bec99bd..000000000 --- a/lbtt/src/NeverClaim-parse_.cc +++ /dev/null @@ -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" diff --git a/lbtt/src/NeverClaimAutomaton.cc b/lbtt/src/NeverClaimAutomaton.cc deleted file mode 100644 index 122f389b7..000000000 --- a/lbtt/src/NeverClaimAutomaton.cc +++ /dev/null @@ -1,317 +0,0 @@ -/* - * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 - * Heikki Tauriainen - * - * 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 -#include -#include -#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::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::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::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::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"); - } -} diff --git a/lbtt/src/NeverClaimAutomaton.h b/lbtt/src/NeverClaimAutomaton.h deleted file mode 100644 index 49cf37324..000000000 --- a/lbtt/src/NeverClaimAutomaton.h +++ /dev/null @@ -1,455 +0,0 @@ -/* - * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 - * Heikki Tauriainen - * - * 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 -#include -#include -#include -#include -#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 state_list; /* States of the automaton. - */ - - map 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& 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 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(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::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 */ diff --git a/lbtt/src/PathEvaluator.cc b/lbtt/src/PathEvaluator.cc deleted file mode 100644 index 7737ae251..000000000 --- a/lbtt/src/PathEvaluator.cc +++ /dev/null @@ -1,986 +0,0 @@ -/* - * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 - * Heikki Tauriainen - * - * 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 -#include -#include -#include -#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(0); - current_path = static_cast(0); - current_loop_state = 0; - path_states.clear(); - - for (map::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 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 > 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(f)->subformula1; - h = static_cast(f)->subformula2; - check_value_1 = check_value_2 = true; - lfp = true; - break; - - case LTL_FINALLY : - g = 0; - h = static_cast(f)->subformula; - check_value_1 = check_value_2 = true; - lfp = true; - break; - - case LTL_V : - val->set(path_states.size()); - g = static_cast(f)->subformula1; - h = static_cast(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(f)->subformula; - check_value_1 = check_value_2 = false; - lfp = false; - break; - - default : /* LTL_BEFORE */ - val->set(path_states.size()); - g = static_cast(f)->subformula1; - h = static_cast(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(f)->subformula1; - g = static_cast(f)->subformula2; - check_value = false; - } - else - { - h = static_cast(f)->subformula1; - g = static_cast(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(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(f)->subformula1; - const LtlFormula* h = static_cast(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(f)->subformula1; - const LtlFormula* h = static_cast(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(f)->subformula1; - const LtlFormula* h = static_cast(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(f)->subformula1; - const LtlFormula* h = static_cast(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(f)->subformula1; - const LtlFormula* h = static_cast(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(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, |") + (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(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(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(f)->subformula1; - f2 = static_cast(f)->subformula2; - branch = prove_true; - val1 = val2 = false; - break; - - case LTL_DISJUNCTION : - f1 = static_cast(f)->subformula1; - f2 = static_cast(f)->subformula2; - branch = !prove_true; - val1 = val2 = true; - break; - - case LTL_IMPLICATION : - f1 = static_cast(f)->subformula1; - f2 = static_cast(f)->subformula2; - branch = !prove_true; - val1 = false; - val2 = true; - break; - - case LTL_EQUIVALENCE : - f1 = static_cast(f)->subformula1; - f2 = static_cast(f)->subformula2; - branch = true; - break; - - default : /* LTL_XOR */ - f1 = static_cast(f)->subformula1; - f2 = static_cast(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(f)->subformula1; - f2 = static_cast(f)->subformula2; - eventuality = true; - check_value_1 = check_value_2 = true; - break; - - case LTL_FINALLY : - f1 = 0; - f2 = static_cast(f)->subformula; - eventuality = true; - check_value_1 = check_value_2 = true; - break; - - case LTL_V : - f1 = static_cast(f)->subformula1; - f2 = static_cast(f)->subformula2; - eventuality = false; - check_value_1 = check_value_2 = false; - break; - - case LTL_GLOBALLY : - f1 = 0; - f2 = static_cast(f)->subformula; - eventuality = false; - check_value_1 = check_value_2 = false; - break; - - case LTL_BEFORE : - f1 = static_cast(f)->subformula1; - f2 = static_cast(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(f)->subformula2; - f2 = static_cast(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(f)->subformula2; - f2 = static_cast(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); -} - -} diff --git a/lbtt/src/PathEvaluator.h b/lbtt/src/PathEvaluator.h deleted file mode 100644 index 4d361d8f8..000000000 --- a/lbtt/src/PathEvaluator.h +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 - * Heikki Tauriainen - * - * 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 -#include -#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 path_states; /* Correspondence - * between states of the - * path and the states - * of the current state - * space. - */ - - map /* 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(0)), - current_path(static_cast(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 */ diff --git a/lbtt/src/PathIterator.cc b/lbtt/src/PathIterator.cc deleted file mode 100644 index 6489b7b1b..000000000 --- a/lbtt/src/PathIterator.cc +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 - * Heikki Tauriainen - * - * 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 -#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); - } -} - -} diff --git a/lbtt/src/PathIterator.h b/lbtt/src/PathIterator.h deleted file mode 100644 index 28e02a2f5..000000000 --- a/lbtt/src/PathIterator.h +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 - * Heikki Tauriainen - * - * 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 -#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 */ diff --git a/lbtt/src/Product.h b/lbtt/src/Product.h deleted file mode 100644 index 041ff5d36..000000000 --- a/lbtt/src/Product.h +++ /dev/null @@ -1,2933 +0,0 @@ -/* - * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 - * Heikki Tauriainen - * - * 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 PRODUCT_H -#define PRODUCT_H - -#include -#include -#include -#include -#include -#include "LbttAlloc.h" -#include "BitArray.h" -#include "EdgeContainer.h" -#include "Exception.h" -#include "Graph.h" -#include "SccCollection.h" - -using namespace std; - -extern bool user_break; - -namespace Graph -{ - -/****************************************************************************** - * - * A template class for representing the product of two - * Graph objects (which, in lbtt, are always either two - * BuchiAutomaton objects, or a BuchiAutomaton and a StateSpace). - * - * The class provides functions for checking the products of these objects for - * emptiness (i.e., for two Büchi automata, whether the intersection of their - * languages is (non)empty; for a Büchi automaton and a state space, whether - * some infinite path in the state space is accepted by the automaton). The - * functions are as follows: - * - * * bool localEmptinessCheck - * (Graph::size_type, - * Graph::size_type) - * Checks whether the subproduct rooted at a product state - * determined by a pair of component state identifiers is not - * empty and returns true if this is the case. - * - * * pair::size_type, unsigned long int> - * globalEmptinessCheck - * (Graph::size_type state, Bitset&, - * unsigned long int emptiness_check_size) - * Checks a set of subproducts for emptiness and stores the - * results in a bit set that should have room for (at least) - * `emptiness_check_size' bits (this number is assumed to be less - * than the number of states in the second component of the - * product). The first parameter `state' identifies a state in - * the first component of the product. After the call, the i'th - * bit (for all 0 <= i < emptiness_check_size) in the bit set will - * then be 1 iff the subproduct rooted at the product state - * determined by the pair of state identifiers (state, i) is - * nonempty. The function returns a pair of numbers corresponding - * to the number of product states and transitions generated - * during the emptiness check. - * - * * void findWitness - * (Graph::size_type, - * Graph::size_type, - * Product::Witness&) - * Checks whether the subproduct rooted at a product state - * determined by a pair of component state identifiers is not - * empty. If this is the case, the function constructs a - * certificate (a "witness") for the nonemptiness. For the - * product of two Büchi automata, the witness is an accepting - * execution from both automata on the same input; for the product - * of a Büchi automaton and a state space, the witness is a path - * in the state space that is accepted by the automaton. - * - * All of these functions construct the product "on the fly" with the help of - * operations provided by the class Operations used for instantiating the - * template. The public interface of this class must support the following - * operations: - * - * * Operations(const Graph&, - * const Graph&) - * Constructor that accepts references to the first and second - * component of the product (in this order) as parameters. - * - * * bool empty() - * A predicate which returns "true" iff either of the product - * components is (trivially) empty, i.e., iff either component has - * no states. - * - * * unsigned long int numberOfAcceptanceSets() - * Returns the number of acceptance sets associated with a state - * or a transition in the product. - * - * * const Graph::Node& firstComponent - * (Graph::size_type), - * const Graph::Node& secondComponent - * (Graph::size_type) - * Functions for accessing the states in the individual product - * components such that firstComponent(i) (secondComponent(i)) - * returns a reference to the i'th state of the first (second) - * component in the product. - * - * * void mergeAcceptanceInformation - * (const Graph::Node&, - * const Graph::Node&, - * BitArray&) - * Updates the acceptance information of a product state - * (determined by a state of the first and the second component, - * respectively) into a BitArray that is guaranteed to have room - * for at least numberOfAcceptanceSets() bits. The function - * should not clear bits in the array. - * - * * void mergeAcceptanceInformation - * (const Graph::Edge&, - * const Graph::Edge&, - * BitArray& - * Updates the acceptance information of a product transition - * (corresponding to a pair of transitions of the first and second - * product component) into a BitArray (guaranteed to have room for - * at least numberOfAcceptanceSets() bits). The function should - * not clear bits in the array. - * - * * void validateEdgeIterators - * (const Graph::Node& node_1, - * const Graph::Node& node_2, - * GraphEdgeContainer::const_iterator iterator_1&, - * GraphEdgeContainer::const_iterator iterator_2&) - * Checks whether a pair of edges determined from a pair of - * iterators corresponds to an edge starting from a given state - * (node_1, node_2) in the product. If yes, the function should - * leave the iterators intact; otherwise the iterators should be - * updated such that they point to a pair of edges corresponding - * to an edge in the product (or to `node_1.edges().end()' and - * `node_2.edges().end()' if this is not possible). - * Calling the function with the iterators initialized to - * `node_1.edges().begin()' and `node_2.edges().begin()' should - * update the iterators such that repeated calls to - * `incrementEdgeIterators' (see below) result in an enumeration - * of all product edges beginning from the product state - * (node_1, node_2). - * - * * void incrementEdgeIterators - * (const Graph::Node& node_1, - * const Graph::Node& node_2, - * GraphEdgeContainer::const_iterator iterator_1&, - * GraphEdgeContainer::const_iterator iterator_2&) - * Updates a pair of edge iterators to point to the "next" edge - * starting from a given state (node_1, node_2) in the product - * (or to (node_1.edges().end(), node_2.edges().end()) if this is - * not possible). - * - * See the files BuchiProduct.h and StateSpaceProduct.h for examples of classes - * used for instantiating the template. - * - * Given a class suitable for instantiating the Product template, a product is - * built with the constructor - * Product::Product - * (const Graph& graph_1, - * const Graph& graph_2). - * The product can be then analyzed by calling one of the emptiness checking - * functions described above. - * - * Note: All emptiness checking functions fail by throwing an exception of type - * Product::SizeException if - * `graph_1.size() * graph_2.size()' exceeds the maximum integer - * representables using Graph::size_type. The - * implementation does not support such products. - * - * Note: Operations in the Product class are not re-entrant. - * - *****************************************************************************/ - -template -class Product -{ -public: - Product /* Constructor. */ - (const Graph& g1, - const Graph& g2); - - ~Product(); /* Destructor. */ - - typedef typename Graph /* Type of product state */ - ::size_type size_type; /* identifiers. */ - - class ProductState; /* A class for accessing - * states in the product. - */ - - const ProductState operator[] /* Indexing operator. */ - (const size_type index) const; - - size_type stateId /* Constructs a product */ - (const size_type state_1, /* state identifier from */ - const size_type state_2) const; /* the identifiers of - * the state components. - */ - - const Graph::Node& /* Functions for */ - firstComponent(const size_type state) const; /* accessing the */ - const Graph::Node& /* components of a */ - secondComponent(const size_type state) const; /* product state. */ - - bool empty() const; /* Tells whether the - * product is (trivially) - * empty. - */ - - struct Witness /* Structure for */ - { /* representing witness */ - pair::Path, /* paths for */ - Graph::Path> /* the nonemptiness of */ - prefix; /* the product. */ - pair::Path, - Graph::Path> - cycle; - }; - - bool localEmptinessCheck /* Checks whether the */ - (const typename Graph /* subproduct rooted at */ - ::size_type s1_id, /* a product state */ - const typename Graph /* determined by a pair */ - ::size_type s2_id); /* of component state - * identifiers is empty. - */ - - const pair /* Checks a set of */ - globalEmptinessCheck /* subproducts for */ - (const typename Graph /* emptiness (see */ - ::size_type state_id, /* above). */ - Bitset& result, - const unsigned long int emptiness_check_size); - - void findWitness - (const size_type s1_id, const size_type s2_id, /* Checks whether the */ - Witness& witness); /* subproduct rooted at - * a product state - * determined by a pair - * of component state - * identifiers is empty. - * If this is the case, - * constructs also a - * witness for the - * nonemptiness. - */ - - /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - - class ProductEdge; /* Classes for */ - class ProductEdgePointer; /* representing - * transitions in the - * product and - * "pointer-like" - * objects to them. - */ - - /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - - class ProductEdgeCollection /* A class that mimics - * a container for - * transitions starting - * from a product state. - * (The container does - * not actually store the - * transitions; instead, - * it provides functions - * for constructing - * iterators that can be - * used to generate the - * transitions.) - */ - { - public: - explicit ProductEdgeCollection /* Constructor. */ - (const size_type state); - - /* default copy constructor */ - - ~ProductEdgeCollection(); /* Destructor. */ - - /* default assignment operator */ - - class const_iterator /* Iterator for generating - * the transitions starting - * from a product state. - */ - { - public: - const_iterator(); /* Default constructor. */ - - const_iterator - (const size_type state, /* Constructor. */ - const GraphEdgeContainer::const_iterator& - e1, - const GraphEdgeContainer::const_iterator& - e2); - - /* default copy constructor */ - - ~const_iterator(); /* Destructor. */ - - /* default assignment operator */ - - bool operator==(const const_iterator& it) /* Equality test between */ - const; /* iterators. */ - - bool operator!=(const const_iterator& it) /* Inequality test */ - const; /* between iterators. */ - - const ProductEdgePointer operator*() const; /* Dereferencing */ - const ProductEdge operator->() const; /* operators. */ - - const ProductEdgePointer operator++(); /* Prefix and postfix */ - const ProductEdgePointer operator++(int); /* increment operators. */ - - private: - size_type product_state; /* Product state */ - /* associated with the - * iterator. - */ - - GraphEdgeContainer::const_iterator edge_1; /* Pair of iterators */ - GraphEdgeContainer::const_iterator edge_2; /* from which product - * edges are determined. - */ - }; - - const const_iterator begin() const; /* Returns an iterator to - * the "beginning" of the - * list of transitions - * starting from the - * product state - * `this->product_state'. - */ - - const const_iterator end() const; /* Returns an iterator to - * the "end" of the list of - * transitions starting - * from the product state - * `this->product_state'. - */ - - private: - size_type product_state; /* Product state associated - * with the transition - * container. - */ - }; - - /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - - class SizeException : public Exception /* An exception class to */ - /* be used in cases */ - /* where `size_type' */ - /* cannot hold values */ - /* large enough to */ - /* accommodate the */ - /* largest identifier */ - /* for a product state. */ - { - public: - SizeException(); /* Constructor. */ - - /* default copy constructor */ - - ~SizeException() throw(); /* Destructor. */ - - SizeException& operator= /* Assignment operator. */ - (const SizeException& e); - - /* `what' inherited from class Exception */ - }; - - /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - - typedef ProductEdge Edge; /* Type definitions */ - typedef ProductEdgeCollection EdgeContainerType; /* required for making */ - /* Product */ - struct PathElement; /* suitable for */ - typedef deque Path; /* instantiating the - * SccCollection - * template (see - * SccCollection.h). - */ - - /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -private: - Product(const Product&); /* Prevent copying and */ - Product& operator=(const Product&); /* assignment of Product - * objects. - */ - - class AcceptanceTracker; /* Callback operations */ - class SimpleEmptinessChecker; /* used when searching */ - class AcceptanceReachabilityTracker; /* the product for */ - class AcceptingComponentFinder; /* strongly connected - * components. - */ - - void addCycleSegment /* Helper function for */ - (pair::Path, /* constructing a */ - Graph::Path >& cycle, /* segment of the cycle */ - size_type source_state_id, Edge transition, /* in a witness for the */ - const size_type root_id, /* nonemptiness of the */ - const map& /* product. */ - predecessor) const; - - Operations operations; /* Operations for - * building the product - * on the fly. - */ - - bool too_large; /* Will be set to true - * if `size_type' cannot - * hold the maximum value - * that may be required for - * product state - * identifiers. Calling - * one of the emptiness - * checking operations on - * such a product results - * in a run-time exception. - */ - - const size_type state_id_multiplier; /* Size of the "second" - * component of the - * product. - */ - - static Product* product; /* Pointer to the "current" - * product (i.e., the - * product for which one - * of the emptiness - * checking operations was - * last called) to allow - * accessing it from - * member classes. - */ -}; - - - -/****************************************************************************** - * - * A template class for providing a Graph<>::Node-like interface to the states - * in a product (needed for accessing the transitions leaving from a state). - * - *****************************************************************************/ - -template -class Product::ProductState -{ -public: - ProductState(const size_type state); /* Constructor. */ - - /* default copy constructor */ - - ~ProductState(); /* Destructor. */ - - /* default assignment operator */ - - const EdgeContainerType& edges() const; /* Returns an object for - * generating the - * transitions starting - * from the state. - */ - -private: - EdgeContainerType outgoing_edges; /* Object for generating - * the transitions starting - * from the state. - */ -}; - - - -/****************************************************************************** - * - * A template class for providing a Graph<>::Edge-like interface to the - * transitions in a product. - * - *****************************************************************************/ - -template -class Product::ProductEdge -{ -public: - ProductEdge /* Constructor. */ - (const GraphEdgeContainer::const_iterator& e1, - const GraphEdgeContainer::const_iterator& e2); - - /* default copy constructor */ - - ~ProductEdge(); /* Destructor. */ - - /* default assignment operator */ - - const Graph::Edge& /* Functions for */ - firstComponent() const; /* accessing the */ - const Graph::Edge& /* components of a */ - secondComponent() const; /* product transition. */ - - size_type targetNode() const; /* Returns the target state - * of the transition. - */ - -private: - GraphEdgeContainer::const_iterator edge_1; /* Components of the */ - GraphEdgeContainer::const_iterator edge_2; /* transition. */ -}; - - - -/****************************************************************************** - * - * A template class for providing a constant pointer -like interface to - * ProductEdge objects. - * - *****************************************************************************/ - -template -class Product::ProductEdgePointer -{ -public: - ProductEdgePointer /* Constructor. */ - (const GraphEdgeContainer::const_iterator& e1, - const GraphEdgeContainer::const_iterator& e2); - - /* default copy constructor */ - - ~ProductEdgePointer(); /* Destructor. */ - - /* default assignment operator */ - - const ProductEdge& operator*() const; /* Dereferencing */ - const ProductEdge* operator->() const; /* operators. */ - -private: - ProductEdge edge; /* The product transition. - */ -}; - - - -/****************************************************************************** - * - * A template class for representing (product state, product transition) pairs - * in a path in the product. - * - *****************************************************************************/ - -template -struct Product::PathElement -{ - PathElement(const size_type s, const Edge& t); /* Constructor. */ - - /* default copy constructor */ - - ~PathElement(); /* Destructor. */ - - /* default assignment operator */ - - size_type state; /* Product state and */ - Edge transition; /* transition. */ -}; - - - -/****************************************************************************** - * - * A template class for tracking acceptance information in strongly connected - * product components by (essentially) recording the information into roots of - * the components. This is done using the method described by Couvreur in - * [J.-M. Couvreur. On-the-fly verification of linear temporal logic. - * In Proceedings of the FM'99 World Congress on Formal Methods in the - * Development of Computing Systems, Volume I, LNCS 1708, pp. 253--271. - * Springer-Verlag, 1999]. - * - *****************************************************************************/ - -template -class Product::AcceptanceTracker : - public VisitorInterface > -{ -public: - explicit AcceptanceTracker /* Constructor. */ - (const unsigned long int num_accept_sets); - - virtual ~AcceptanceTracker(); /* Destructor. */ - - /* `enter' inherited */ - - /* `backtrack' inherited */ - - /* `touch' inherited */ - - /* `leave' inherited */ - - virtual void addEdgeToComponent /* Adds the acceptance */ - (const Edge& t, const size_type scc_id); /* sets associated with - * a product transition - * to a nontrivial - * strongly connected - * component of the - * product. - */ - - virtual void addNodeToComponent /* Adds the acceptance */ - (const size_type state_id, /* sets associated with */ - const size_type scc_id); /* a product state to a */ - /* nontrivial strongly - * connected component - * of the product. - */ - - /* `beginComponent' inherited */ - - /* `insert' inherited */ - - virtual void endComponent /* Removes the */ - (const size_type scc_id); /* association between a - * nontrivial strongly - * connected product - * component and a set - * of acceptance sets - * when the component is - * not needed any - * longer. - */ - -protected: - typedef pair /* Association between */ - AcceptanceStackElement; /* a strongly connected - * component identifier - * and a collection of - * acceptance sets. - */ - - typedef deque /* Stack formed from */ - AcceptanceStack; /* the above - * associations. - */ - - AcceptanceStack acceptance_stack; /* Stack for storing the - * dfs numbers of roots - * of strongly connected - * components and - * acceptance sets - * associated with them. - */ - - BitArray* acceptance_sets; /* Used for manipulating - * the stack. - */ - - const unsigned long int /* Number of acceptance */ - number_of_acceptance_sets; /* sets in the product. */ - -private: - AcceptanceTracker(const AcceptanceTracker&); /* Prevent copying and */ - AcceptanceTracker& operator= /* assignment of */ - (const AcceptanceTracker&); /* AcceptanceTracker - * objects. - */ -}; - - - -/****************************************************************************** - * - * A template class for checking a product for emptiness. - * - *****************************************************************************/ - -template -class Product::SimpleEmptinessChecker : public AcceptanceTracker -{ -public: - explicit SimpleEmptinessChecker /* Constructor. */ - (const unsigned long int num_accept_sets); - - ~SimpleEmptinessChecker(); /* Destructor. */ - - typedef int SccType; /* Dummy type definition - * required for supporting - * the expected class - * interface. - */ - - const SccType& operator()() const; /* Dummy function required - * for supporting the - * expected class - * interface. - */ - - /* `enter' inherited */ - - /* `backtrack' inherited */ - - /* `touch' inherited */ - - /* `leave' inherited */ - - void addEdgeToComponent /* Adds the acceptance */ - (const Edge& t, const size_type scc_id); /* sets associated with - * a product transition - * to a nontrivial - * strongly connected - * component of the - * product and aborts - * the emptiness check - * if an accepting - * strongly connected - * component is - * detected. - */ - - void addNodeToComponent /* Adds the acceptance */ - (const size_type state, /* sets associated with */ - const size_type scc_id); /* a product state to a - * nontrivial strongly - * connected component - * of the product and - * aborts the emptiness - * check if an accepting - * strongly connected - * component is - * detected. - */ - - /* `beginComponent' inherited */ - - /* `insert' inherited */ - - /* `endComponent' inherited */ - -private: - SimpleEmptinessChecker /* Prevent copying and */ - (const SimpleEmptinessChecker&); /* assignment of */ - SimpleEmptinessChecker& /* SimpleEmptiness- */ - operator=(const SimpleEmptinessChecker&); /* Checker objects. */ - - void abortIfNonempty() const; /* Aborts the search when - * an accepting strongly - * connected component is - * found. - */ - - SccType dummy; /* Dummy variable needed - * for implementing the - * operator() function. - */ -}; - - - -/****************************************************************************** - * - * A template class for tracking the reachability of accepting strongly - * connected components in a product. - * - *****************************************************************************/ - -template -class Product::AcceptanceReachabilityTracker - : public Product::AcceptanceTracker -{ -public: - explicit AcceptanceReachabilityTracker /* Constructor. */ - (const unsigned long int num_accept_sets); - - ~AcceptanceReachabilityTracker(); /* Destructor. */ - - typedef int SccType; /* Dummy type definition - * required for supporting - * the expected class - * interface. - */ - - const SccType& operator()() const; /* Dummy function required - * for supporting the - * expected class - * interface. - */ - - void enter(const size_type); /* Function called when - * entering a new product - * state. - */ - - void backtrack /* Function called when */ - (const size_type source, const Edge&, /* backtracking from a */ - const size_type target); /* product state. */ - - void touch /* Function called when */ - (const size_type source, const Edge& edge, /* processing an edge */ - const size_type target); /* with a target state - * that has already been - * visited during the - * search. - */ - - /* `leave' inherited */ - - /* `addEdgeToComponent' inherited */ - - /* `addNodeToComponent' inherited */ - - void beginComponent /* Tests whether the */ - (const size_type, const size_type state_id); /* strongly connected - * component about to - * be extracted from the - * product is an - * accepting component, - * or if it contains a - * state from which such - * a component is known - * to be reachable. - */ - - void insert(const size_type state); /* Function used for - * updating accepting - * component reachability - * information while - * extracting states from - * a product component. - */ - - /* `endComponent' inherited */ - - bool isMarked(const size_type state) const; /* Tests whether an - * accepting component is - * known to be reachable - * from a product state. - */ - - size_type numberOfStates() const; /* Tells the number of - * product states explored - * during the search. - */ - - unsigned long int numberOfTransitions() const; /* Tells the number of - * product transitions - * explored during the - * search. - */ - -private: - AcceptanceReachabilityTracker /* Prevent copying and */ - (const AcceptanceReachabilityTracker&); /* assignment of */ - AcceptanceReachabilityTracker& /* AcceptanceSet- */ - operator= /* ReachabilityTracker */ - (const AcceptanceReachabilityTracker&); /* objects. */ - - void markState(const size_type state); /* Adds a product state to - * the set of states from - * which an accepting - * component is known to be - * reachable. - */ - - set reachability_info; /* Set of states from - * which an accepting - * component is known to - * be reachable in the - * product. - */ - - size_type number_of_states; /* Number of states - * explored during the - * search. - */ - - unsigned long int number_of_transitions; /* Number of transitions - * explored during the - * search. - */ - - bool mark_scc; /* Used for determining - * whether to insert states - * into `this-> - * reachability_info' while - * extracting a strongly - * connected component from - * the product. - */ - - SccType dummy; /* Dummy variable needed - * for implementing the - * operator() function. - */ -}; - - - -/****************************************************************************** - * - * A template class for finding accepting maximal strongly connected components - * in a product. - * - *****************************************************************************/ - -template -class Product::AcceptingComponentFinder : - public Product::AcceptanceTracker -{ -public: - explicit AcceptingComponentFinder /* Constructor. */ - (const unsigned long int num_accept_sets); - - ~AcceptingComponentFinder(); /* Destructor. */ - - typedef set SccType; /* Type definition for - * the set of product - * state identifiers in - * an accepting - * strongly connected - * component. - */ - - const SccType& operator()() const; /* Returns the last - * accepting maximal - * strongly connected - * component found in the - * product. - */ - - /* `enter' inherited */ - - /* `backtrack' inherited */ - - /* `touch' inherited */ - - /* `leave' inherited */ - - /* `addEdgeToComponent' inherited */ - - /* `addNodeToComponent' inherited */ - - void beginComponent /* Tests whether the */ - (const size_type, const size_type); /* maximal strongly - * connected component - * that is about to be - * extracted from the - * product is an - * accepting component. - */ - - void insert(const size_type state); /* Inserts a state to an - * accepting component. - */ - - /* `endComponent' inherited */ - -private: - AcceptingComponentFinder /* Prevent copying and */ - (const AcceptingComponentFinder&); /* assignment of */ - AcceptingComponentFinder& /* AcceptingComponent- */ - operator=(const AcceptingComponentFinder&); /* Finder objects. */ - - SccType scc; /* Set of product state - * identifiers forming the - * last accepting strongly - * connected component - * found in the product. - */ - - bool construct_component; /* Used for determining - * whether the states - * extracted from a - * strongly connected - * component in the product - * should be inserted into - * `this->scc'. - */ -}; - - - -/****************************************************************************** - * - * Inline function definitions for template class Product. - * - *****************************************************************************/ - -/* ========================================================================= */ -template -inline Product::Product - (const Graph& g1, const Graph& g2) - : operations(g1, g2), state_id_multiplier(g2.size()) -/* ---------------------------------------------------------------------------- - * - * Description: Constructor for class Product. - * - * Arguments: g1, g2 -- Constant references to the components of the - * product. - * - * Returns: Nothing. If `Product::size_type' cannot hold - * values large enough to accommodate the largest identifier for - * a product state, `this->too_large' is set to true to cause - * all emptiness checking operations on the product to fail by - * throwing a Product::SizeException. - * - * ------------------------------------------------------------------------- */ -{ - too_large = (!g2.empty() && - g1.size() > (static_cast(-1) / g2.size())); -} - -/* ========================================================================= */ -template -inline Product::~Product() -/* ---------------------------------------------------------------------------- - * - * Description: Destructor for class Product. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -template -inline const typename Product::ProductState -Product::operator[] - (const typename Product::size_type index) const -/* ---------------------------------------------------------------------------- - * - * Description: Indexing operator for class Product. - * - * Argument: index -- Index of a state of the product. - * - * Returns: A ProductState object corresponding to the state with the - * given index. - * - * ------------------------------------------------------------------------- */ -{ - return ProductState(index); -} - -/* ========================================================================= */ -template -inline typename Product::size_type Product - ::stateId - (const size_type state_1, const size_type state_2) const -/* ---------------------------------------------------------------------------- - * - * Description: Returns the product state identifier corresponding to - * identifiers of the state components. - * - * Arguments: state_1, state_2 -- Identifiers for the product state - * components. - * - * Returns: Identifier of the product state corresponding to the - * components. - * - * ------------------------------------------------------------------------- */ -{ - return (state_1 * state_id_multiplier) + state_2; -} - -/* ========================================================================= */ -template -inline const Graph::Node& -Product::firstComponent(const size_type state) const -/* ---------------------------------------------------------------------------- - * - * Description: Function for accessing the "first" component state of a - * product state. - * - * Arguments: state -- Identifier of a product state. - * - * Returns: A constant reference to the state corresponding to the - * "first" component of the product state. - * - * ------------------------------------------------------------------------- */ -{ - return operations.firstComponent(state / state_id_multiplier); -} - -/* ========================================================================= */ -template -inline const Graph::Node& -Product::secondComponent(const size_type state) const -/* ---------------------------------------------------------------------------- - * - * Description: Function for accessing the "second" component state of a - * product state. - * - * Arguments: state -- Identifier of a product state. - * - * Returns: A constant reference to the state corresponding to the - * "second" component of the product state. - * - * ------------------------------------------------------------------------- */ -{ - return operations.secondComponent(state % state_id_multiplier); -} - -/* ========================================================================= */ -template -inline bool Product::empty() const -/* ---------------------------------------------------------------------------- - * - * Description: Tells whether the product is (trivially) empty, i.e., if - * either of its components has no states. - * - * Arguments: None. - * - * Returns: true iff the product is trivially empty. - * - * ------------------------------------------------------------------------- */ -{ - return operations.empty(); -} - - - -/****************************************************************************** - * - * Function definitions for template class Product. - * - *****************************************************************************/ - -/* ========================================================================= */ -template -bool Product::localEmptinessCheck - (const Graph::size_type s1_id, - const Graph::size_type s2_id) -/* ---------------------------------------------------------------------------- - * - * Description: Checks whether the subproduct rooted at a product state - * determined by a pair of component state identifiers is not - * empty. - * - * Arguments: s1_id, s2_id -- Identifiers for the product state - * components. - * - * Returns: true iff the subproduct rooted at the product state - * determined by `s1_id' and `s2_id' is not empty. Throws a - * Product::SizeException if the product is too - * large to handle. - * - * ------------------------------------------------------------------------- */ -{ - if (too_large) - throw SizeException(); - - if (empty()) - return false; - - product = this; - - SimpleEmptinessChecker ec(operations.numberOfAcceptanceSets()); - typedef SccCollection, SimpleEmptinessChecker> - ProductSccCollection; - - ProductSccCollection sccs(*this, ec); - - try - { - for (typename ProductSccCollection::iterator scc - = sccs.begin(stateId(s1_id, s2_id)); - scc != sccs.end(); - ++scc) - { - if (::user_break) - throw UserBreakException(); - } - } - catch (const int) - { - return true; - } - - return false; -} - -/* ========================================================================= */ -template -const pair::size_type, unsigned long int> -Product::globalEmptinessCheck - (const Graph::size_type state_id, - Bitset& result, const unsigned long int emptiness_check_size) -/* ---------------------------------------------------------------------------- - * - * Description: Checks a set of subproducts of the product for emptiness. - * - * Arguments: state_id -- Identifier of a state in the first - * component of the product. - * result -- A reference to a Bitset for storing - * the result of the emptiness check. - * The set should have room for at - * least `emptiness_check_size' bits. - * emptiness_check_size -- Determines the scope of the - * emptiness check (see below). - * - * Returns: A pair giving the numbers of product states and transitions - * generated during the emptiness check. The result of the - * emptiness check itself is stored into `result' such that - * the i'th bit (for all 0 <= i < emptiness_check_size) in the - * bit set will be 1 iff the subproduct rooted at the product - * state determined by the pair of state identifiers - * (state_id, i) is nonempty. - * - * The function throws a Product::SizeException if - * the product may be too large to handle. - * - * ------------------------------------------------------------------------- */ -{ - if (too_large) - throw SizeException(); - - result.clear(); - - if (empty()) - return make_pair(0, 0); - - product = this; - - AcceptanceReachabilityTracker rt(operations.numberOfAcceptanceSets()); - - typedef SccCollection, AcceptanceReachabilityTracker> - ProductSccCollection; - - ProductSccCollection sccs(*this, rt); - - for (Graph::size_type state = 0; - state < emptiness_check_size; - ++state) - { - for (typename ProductSccCollection::iterator scc - = sccs.begin(stateId(state_id, state)); - scc != sccs.end(); - ++scc) - { - if (::user_break) - throw UserBreakException(); - } - } - - for (Graph::size_type state = 0; - state < emptiness_check_size; - ++state) - { - if (rt.isMarked(stateId(state_id, state))) - result.setBit(state); - } - - return make_pair(rt.numberOfStates(), rt.numberOfTransitions()); -} - -/* ========================================================================= */ -template -void Product::findWitness - (const typename Graph::size_type s1_id, - const typename Graph::size_type s2_id, - typename Product::Witness& witness) -/* ---------------------------------------------------------------------------- - * - * Description: Checks whether the subproduct rooted at a product state - * determined by a pair of component state identifiers is not - * empty. If this is the case, constructs a witness for the - * nonemptiness. - * - * Arguments: s1_id, s2_id -- Identifiers for the product state - * components. - * witness -- A reference to an object for storing a - * witness if such a witness exists. - * - * Returns: Nothing. A witness was found iff - * `!witness.cycle.first.empty() - * && !witness.cycle.second.empty()' holds after the call. - * - * The function throws a Product::SizeException if - * the product may be too large to handle. - * - * ------------------------------------------------------------------------- */ -{ - if (too_large) - throw SizeException(); - - witness.prefix.first.clear(); - witness.prefix.second.clear(); - witness.cycle.first.clear(); - witness.cycle.second.clear(); - - if (empty()) - return; - - product = this; - const unsigned long int number_of_acceptance_sets - = operations.numberOfAcceptanceSets(); - const size_type start_state = stateId(s1_id, s2_id); - - AcceptingComponentFinder acf(number_of_acceptance_sets); - typedef SccCollection, AcceptingComponentFinder> - ProductSccCollection; - - ProductSccCollection sccs(*this, acf); - - for (typename ProductSccCollection::iterator scc = sccs.begin(start_state); - scc != sccs.end(); - ++scc) - { - if (::user_break) - throw UserBreakException(); - - if (!scc->empty()) - { - /* - * The prefix of the witness consists of a path from the given product - * state to a state in an accepting strongly connected product - * component. - */ - - Path path; - scc.getPath(path); - - for (typename Path::const_iterator path_element = path.begin(); - path_element != path.end(); - ++path_element) - { - witness.prefix.first.push_back - (Graph::PathElement - (path_element->state / state_id_multiplier, - path_element->transition.firstComponent())); - witness.prefix.second.push_back - (Graph::PathElement - (path_element->state % state_id_multiplier, - path_element->transition.secondComponent())); - } - - /* - * Construct an accepting cycle by performing a breadth-first search - * in the MSCC. - */ - - const size_type search_start_state - = path.empty() ? start_state : path.back().transition.targetNode(); - - BitArray collected_acceptance_sets(number_of_acceptance_sets); - collected_acceptance_sets.clear(number_of_acceptance_sets); - operations.mergeAcceptanceInformation - (firstComponent(search_start_state), - secondComponent(search_start_state), collected_acceptance_sets); - - unsigned long int number_of_collected_acceptance_sets - = collected_acceptance_sets.count(number_of_acceptance_sets); - - deque search_queue; - set visited; - map shortest_path_predecessor; - - size_type bfs_root = search_start_state; - -continue_bfs: - search_queue.clear(); - search_queue.push_back(bfs_root); - visited.clear(); - visited.insert(bfs_root); - shortest_path_predecessor.clear(); - - while (!search_queue.empty()) - { - const EdgeContainerType transitions - = ProductState(search_queue.front()).edges(); - - for (typename EdgeContainerType::const_iterator transition - = transitions.begin(); - transition != transitions.end(); - ++transition) - { - const size_type target = (*transition)->targetNode(); - if (scc->find(target) == scc->end()) - continue; - - if (visited.find(target) == visited.end()) - { - visited.insert(target); - shortest_path_predecessor.insert - (make_pair(target, PathElement(search_queue.front(), - **transition))); - search_queue.push_back(target); - - if (number_of_collected_acceptance_sets - < number_of_acceptance_sets) - operations.mergeAcceptanceInformation - (firstComponent(target), secondComponent(target), - collected_acceptance_sets); - } - - if (number_of_collected_acceptance_sets < number_of_acceptance_sets) - { - /* - * Test whether the current product transition or the target - * state of the transition covers new acceptance sets. If - * this is the case, construct the next segment of the cycle - * and begin a new breadth-first search in the target state of - * the transition. - */ - - operations.mergeAcceptanceInformation - ((*transition)->firstComponent(), - (*transition)->secondComponent(), collected_acceptance_sets); - - const unsigned long int num - = collected_acceptance_sets.count(number_of_acceptance_sets); - if (num > number_of_collected_acceptance_sets) - { - number_of_collected_acceptance_sets = num; - - addCycleSegment(witness.cycle, search_queue.front(), - **transition, bfs_root, - shortest_path_predecessor); - - if (number_of_collected_acceptance_sets - == number_of_acceptance_sets - && target == search_start_state) - return; - - bfs_root = target; - goto continue_bfs; - } - } - else if (target == search_start_state) - { - /* - * If all acceptance sets have been collected and the current - * product transition points to the first state of the cycle, - * the cycle is complete. - */ - - addCycleSegment(witness.cycle, search_queue.front(), **transition, - bfs_root, shortest_path_predecessor); - return; - } - } - - search_queue.pop_front(); - } - - throw Exception - ("Product::findWitness(...): internal error [cycle construction " - "failed]"); - } - } -} - -/* ========================================================================= */ -template -void Product::addCycleSegment - (pair::Path, Graph::Path>& - cycle, - size_type source_state_id, Edge transition, const size_type root_id, - const map& predecessor) const -/* ---------------------------------------------------------------------------- - * - * Description: Helper function for constructing a segment of an accepting - * cycle in the product. - * - * Arguments: cycle -- A reference to a pair of paths for - * storing the result. - * source_state_id -- Identifier of the last product state in - * the cycle segment. - * transition -- Last product transition in the cycle - * segment. - * root_id -- Identifier of the first product state in - * the cycle segment. - * predecessor -- Mapping between states and their - * predecessors in the cycle segment. - * - * Returns: Nothing. The segment of the cycle is appended to `cycle'. - * - * ------------------------------------------------------------------------- */ -{ - Graph::Path first_segment; - Graph::Path second_segment; - - while (1) - { - first_segment.push_front - (Graph::PathElement - (source_state_id / state_id_multiplier, transition.firstComponent())); - second_segment.push_front - (Graph::PathElement - (source_state_id % state_id_multiplier, - transition.secondComponent())); - - if (source_state_id == root_id) - { - cycle.first.insert(cycle.first.end(), first_segment.begin(), - first_segment.end()); - cycle.second.insert(cycle.second.end(), second_segment.begin(), - second_segment.end()); - return; - } - - const PathElement& p = predecessor.find(source_state_id)->second; - source_state_id = p.state; - transition = p.transition; - } -} - - - -/****************************************************************************** - * - * Inline function definitions for template class - * Product::ProductState. - * - *****************************************************************************/ - -/* ========================================================================= */ -template -inline Product::ProductState::ProductState - (const size_type state) : outgoing_edges(state) -/* ---------------------------------------------------------------------------- - * - * Description: Constructor for class Product::ProductState. - * - * Argument: state -- Identifier of a product state. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -template -inline Product::ProductState::~ProductState() -/* ---------------------------------------------------------------------------- - * - * Description: Destructor for class Product::ProductState. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -template -inline const typename Product::EdgeContainerType& -Product::ProductState::edges() const -/* ---------------------------------------------------------------------------- - * - * Description: Returns an object for generating the transitions starting - * from a product state. - * - * Arguments: None. - * - * Returns: A constant reference to an object that can be used for - * generating the transitions starting from the state. - * - * ------------------------------------------------------------------------- */ -{ - return outgoing_edges; -} - - - -/****************************************************************************** - * - * Inline function definitions for template class - * Product::ProductEdge. - * - *****************************************************************************/ - -/* ========================================================================= */ -template -inline Product::ProductEdge::ProductEdge - (const GraphEdgeContainer::const_iterator& e1, - const GraphEdgeContainer::const_iterator& e2) - : edge_1(e1), edge_2(e2) -/* ---------------------------------------------------------------------------- - * - * Description: Constructor for class Product::ProductEdge. - * - * Arguments: e1, e2 -- Iterators pointing to the components of the - * product transition. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -template -inline Product::ProductEdge::~ProductEdge() -/* ---------------------------------------------------------------------------- - * - * Description: Destructor for class Product::ProductEdge. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -template -inline const Graph::Edge& -Product::ProductEdge::firstComponent() const -/* ---------------------------------------------------------------------------- - * - * Description: Function for accessing the "first" component of a product - * transition. - * - * Arguments: None. - * - * Returns: A constant reference to the "first" component of the - * transition. - * - * ------------------------------------------------------------------------- */ -{ - return **edge_1; -} - -/* ========================================================================= */ -template -inline const Graph::Edge& -Product::ProductEdge::secondComponent() const -/* ---------------------------------------------------------------------------- - * - * Description: Function for accessing the "second" component of a product - * transition. - * - * Arguments: None. - * - * Returns: A constant reference to the "second" component of the - * transition. - * - * ------------------------------------------------------------------------- */ -{ - return **edge_2; -} - -/* ========================================================================= */ -template -inline typename Product::size_type -Product::ProductEdge::targetNode() const -/* ---------------------------------------------------------------------------- - * - * Description: Returns the target state of a product transition. - * - * Arguments: None. - * - * Returns: Identifier of the target state of the product transition. - * - * ------------------------------------------------------------------------- */ -{ - return product->stateId((*edge_1)->targetNode(), (*edge_2)->targetNode()); -} - - - -/****************************************************************************** - * - * Inline function definitions for template class - * Product::ProductEdgePointer. - * - *****************************************************************************/ - -/* ========================================================================= */ -template -inline Product::ProductEdgePointer::ProductEdgePointer - (const GraphEdgeContainer::const_iterator& e1, - const GraphEdgeContainer::const_iterator& e2) - : edge(e1, e2) -/* ---------------------------------------------------------------------------- - * - * Description: Constructor for class - * Product::ProductEdgePointer. - * - * Arguments: e1, e2 -- Iterators pointing to the components of the - * product transition. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -template -inline Product::ProductEdgePointer::~ProductEdgePointer() -/* ---------------------------------------------------------------------------- - * - * Description: Destructor for class - * Product::ProductEdgePointer. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -template -inline const typename Product::ProductEdge& -Product::ProductEdgePointer::operator*() const -/* ---------------------------------------------------------------------------- - * - * Description: Dereferencing operator for class - * Product::ProductEdgePointer. - * - * Arguments: None. - * - * Returns: A reference to the product transition associated with the - * object. - * - * ------------------------------------------------------------------------- */ -{ - return edge; -} - -/* ========================================================================= */ -template -inline const typename Product::ProductEdge* -Product::ProductEdgePointer::operator->() const -/* ---------------------------------------------------------------------------- - * - * Description: Dereferencing operator for class - * Product::ProductEdgePointer. - * - * Arguments: None. - * - * Returns: A pointer to the product transition associated with the - * object. - * - * ------------------------------------------------------------------------- */ -{ - return &edge; -} - - - -/****************************************************************************** - * - * Inline function definitions for template class - * Product::ProductEdgeCollection. - * - *****************************************************************************/ - -/* ========================================================================= */ -template -inline Product::ProductEdgeCollection::ProductEdgeCollection - (const size_type state) : product_state(state) -/* ---------------------------------------------------------------------------- - * - * Description: Constructor for class - * Product::ProductEdgeCollection. - * - * Argument: state -- Identifier of a product state. The - * ProductEdgeCollection object will mimic a - * container for the product transitions starting - * from this state. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -template -inline Product::ProductEdgeCollection::~ProductEdgeCollection() -/* ---------------------------------------------------------------------------- - * - * Description: Destructor for class - * Product::ProductEdgeCollection. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -template -inline const typename Product::ProductEdgeCollection - ::const_iterator -Product::ProductEdgeCollection::begin() const -/* ---------------------------------------------------------------------------- - * - * Description: Returns an iterator for generating the transitions starting - * from the product state identified by `this->product_state'. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - return const_iterator - (product_state, - product->firstComponent(product_state).edges().begin(), - product->secondComponent(product_state).edges().begin()); -} - -/* ========================================================================= */ -template -inline const typename Product::ProductEdgeCollection - ::const_iterator -Product::ProductEdgeCollection::end() const -/* ---------------------------------------------------------------------------- - * - * Description: Returns an iterator pointing to the "end" of the collection - * of transitions starting from the product state identified by - * `this->product_state'. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - return const_iterator - (product_state, - product->firstComponent(product_state).edges().end(), - product->secondComponent(product_state).edges().end()); -} - - - -/****************************************************************************** - * - * Inline function definitions for template class - * Product::ProductEdgeCollection::const_iterator. - * - *****************************************************************************/ - -/* ========================================================================= */ -template -inline Product::ProductEdgeCollection::const_iterator - ::const_iterator() : product_state(0) -/* ---------------------------------------------------------------------------- - * - * Description: Default constructor for class - * Product::ProductEdgeCollection::const_iterator. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -template -inline Product::ProductEdgeCollection::const_iterator - ::const_iterator - (const size_type state, - const GraphEdgeContainer::const_iterator& e1, - const GraphEdgeContainer::const_iterator& e2) : - product_state(state), edge_1(e1), edge_2(e2) -/* ---------------------------------------------------------------------------- - * - * Description: Constructor for class - * Product::ProductEdgeCollection::const_iterator. - * - * Arguments: state -- Identifier of a product state to associate with - * the iterator. - * e1, e1 -- Constant references to a pair of iterators - * pointing to a pair of transitions starting from - * the component states of the product state. These - * iterators are used to determine where to start - * iterating over the product transitions. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - product->operations.validateEdgeIterators - (product->firstComponent(product_state), - product->secondComponent(product_state), - edge_1, edge_2); -} - -/* ========================================================================= */ -template -inline Product::ProductEdgeCollection::const_iterator - ::~const_iterator() -/* ---------------------------------------------------------------------------- - * - * Description: Destructor for class - * Product::ProductEdgeCollection::const_iterator. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -template -inline bool Product::ProductEdgeCollection::const_iterator - ::operator== - (const const_iterator& it) const -/* ---------------------------------------------------------------------------- - * - * Description: Equality test between two - * Product::ProductEdgeCollection::const_iterators. - * - * Argument: it -- A constant reference to an iterator to compare for - * equality. It is assumed that the iterators are - * associated with the same product state; the result of - * a comparison between iterators associated with - * different product states is undefined. - * - * Returns: true iff `it' and `*this' point to the same transition in the - * product. - * - * ------------------------------------------------------------------------- */ -{ - return (it.edge_1 == edge_1 && it.edge_2 == edge_2); -} - -/* ========================================================================= */ -template -inline bool Product::ProductEdgeCollection::const_iterator - ::operator!= - (const const_iterator& it) const -/* ---------------------------------------------------------------------------- - * - * Description: Inequality test between two - * Product::ProductEdgeCollection::const_iterators. - * - * Argument: it -- A constant reference to an iterator to compare for - * equality. It is assumed that the iterators are - * associated with the same product state; the result of - * a comparison between iterators associated with - * different product states is undefined. - * - * Returns: true iff `it' and `*this' point to different transitions in - * the product. - * - * ------------------------------------------------------------------------- */ -{ - return (it.edge_1 != edge_1 || it.edge_2 != edge_2); -} - -/* ========================================================================= */ -template -inline const typename Product::ProductEdgePointer -Product::ProductEdgeCollection::const_iterator::operator*() const -/* ---------------------------------------------------------------------------- - * - * Description: Dereferencing operator for class - * Product::ProductEdgeCollection::const_iterator. - * - * Arguments: None. - * - * Returns: An object of type Product::ProductEdgePointer - * that allows access to the product transition pointed to by - * the iterator. - * - * ------------------------------------------------------------------------- */ -{ - return ProductEdgePointer(edge_1, edge_2); -} - -/* ========================================================================= */ -template -inline const typename Product::ProductEdge -Product::ProductEdgeCollection::const_iterator::operator->() const -/* ---------------------------------------------------------------------------- - * - * Description: Dereferencing operator for class - * Product::ProductEdgeCollection::const_iterator. - * - * Arguments: None. - * - * Returns: A Product::ProductEdge corresponding to the - * product transition pointed to by the iterator. - * - * ------------------------------------------------------------------------- */ -{ - return ProductEdge(edge_1, edge_2); -} - -/* ========================================================================= */ -template -inline const typename Product::ProductEdgePointer -Product::ProductEdgeCollection::const_iterator::operator++() -/* ---------------------------------------------------------------------------- - * - * Description: Prefix increment operator for class - * Product::ProductEdgeCollection::const_iterator. - * - * Arguments: None. - * - * Returns: An object of type Product::ProductEdgePointer - * that behaves like a pointer to the product transition - * obtained by advancing the iterator in the sequence of product - * transitions. - * - * ------------------------------------------------------------------------- */ -{ - product->operations.incrementEdgeIterators - (product->firstComponent(product_state), - product->secondComponent(product_state), - edge_1, edge_2); - return ProductEdgePointer(edge_1, edge_2); -} - -/* ========================================================================= */ -template -inline const typename Product::ProductEdgePointer -Product::ProductEdgeCollection::const_iterator::operator++(int) -/* ---------------------------------------------------------------------------- - * - * Description: Postfix increment operator for class - * Product::ProductEdgeCollection::const_iterator. - * - * Arguments: None. - * - * Returns: An object of type Product::ProductEdgePointer - * that behaves like a pointer to the product transition pointed - * to by the iterator before advancing it in the sequence of - * product transitions. - * - * ------------------------------------------------------------------------- */ -{ - const typename Product::ProductEdgePointer edge(edge_1, edge_2); - product->operations.incrementEdgeIterators - (product->firstComponent(product_state), - product->secondComponent(product_state), - edge_1, edge_2); - return edge; -} - - - -/****************************************************************************** - * - * Inline function definitions for template class - * Product::PathElement. - * - *****************************************************************************/ - -/* ========================================================================= */ -template -inline Product::PathElement::PathElement - (const size_type s, const Edge& t) : state(s), transition(t) -/* ---------------------------------------------------------------------------- - * - * Description: Constructor for class Product::PathElement. - * - * Arguments: s, t -- Product state and transition associated with the - * element. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -template -inline Product::PathElement::~PathElement() -/* ---------------------------------------------------------------------------- - * - * Description: Destructor for class Product::PathElement. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - - - -/****************************************************************************** - * - * Inline function definitions for template class - * Product::SizeException. - * - *****************************************************************************/ - -/* ========================================================================= */ -template -inline Product::SizeException::SizeException() : - Exception("product may be too large") -/* ---------------------------------------------------------------------------- - * - * Description: Constructor for class Product::SizeException. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -template -inline Product::SizeException::~SizeException() throw() -/* ---------------------------------------------------------------------------- - * - * Description: Destructor for class Product::SizeException. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -template -inline typename Product::SizeException& -Product::SizeException::operator= - (const typename Product::SizeException& e) -/* ---------------------------------------------------------------------------- - * - * Description: Assignment operator for class - * Product::SizeException. Assigns the value of - * another Product::SizeException to `this' one. - * - * Arguments: e -- A reference to a constant object of type - * ProductSizeException. - * - * Returns: A reference to the object whose value was changed. - * - * ------------------------------------------------------------------------- */ -{ - Exception::operator=(e); - return *this; -} - - - -/****************************************************************************** - * - * Inline function definitions for template class - * Product::AcceptanceTracker. - * - *****************************************************************************/ - -/* ========================================================================= */ -template -inline Product::AcceptanceTracker::AcceptanceTracker - (const unsigned long int num_accept_sets) - : number_of_acceptance_sets(num_accept_sets) -/* ---------------------------------------------------------------------------- - * - * Description: Constructor for class Product::AcceptanceTracker. - * - * Arguments: num_accept_sets -- Number of acceptance sets in the - * product. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - /* Initialize `acceptance_stack' with a sentinel element. */ - acceptance_stack.push_front(make_pair(0, new BitArray(0))); -} - -/* ========================================================================= */ -template -inline Product::AcceptanceTracker::~AcceptanceTracker() -/* ---------------------------------------------------------------------------- - * - * Description: Destructor for class Product::AcceptanceTracker. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - for (AcceptanceStack::iterator a = acceptance_stack.begin(); - a != acceptance_stack.end(); - ++a) - delete a->second; -} - -/* ========================================================================= */ -template -inline void Product::AcceptanceTracker::addEdgeToComponent - (const typename Product::Edge& t, - const typename Product::size_type scc_id) -/* ---------------------------------------------------------------------------- - * - * Description: Adds the acceptance sets of the product transition `t' - * (inside a strongly connected product component) to the - * collection of acceptance sets associated with the strongly - * connected component identifier (a dfs number of a product - * state in Tarjan's algorithm). (The component is therefore - * nontrivial, because it contains a transition.) This is done - * as described by Couvreur - * [J.-M. Couvreur. On-the-fly verification of linear - * temporal logic. In Proceedings of the FM'99 World - * Congress on Formal Methods in the Development of - * Computing Systems, Volume I, LNCS 1708, pp. 253--271. - * Springer-Verlag, 1999] - * by first collapsing all elements in the top part of - * `this->acceptance_stack' (*) with strongly connected - * component identifiers greater than or equal to `scc_id' into - * a single element by taking the union of their acceptance sets - * and then merging the acceptance sets of the transition `t' - * with this element. - * After the call, the top element of `this->acceptance_stack' - * will have the scc id `scc_id', and `this->acceptance_sets' - * points to the acceptance sets associated with this stack - * element. - * - * (*) It is assumed that the contents of - * `this->acceptance_stack' form (from top to bottom) a sequence - * of elements (id1,a1), (id2,a2), (id3,a3), ..., where - * id1 > id2 > id3 > ... . The function maintains this - * invariant. - * - * Arguments: t -- A constant reference to the product transition. - * scc_id -- Identifier of the strongly connected component - * (assumed to be >= 1). - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - acceptance_sets = 0; - while (acceptance_stack.front().first >= scc_id) - { - if (acceptance_sets != 0) - { - acceptance_stack.front().second->bitwiseOr - (*acceptance_sets, number_of_acceptance_sets); - delete acceptance_sets; - } - acceptance_sets = acceptance_stack.front().second; - if (acceptance_stack.front().first == scc_id) - goto merge_sets; - - acceptance_stack.pop_front(); - } - - if (acceptance_sets == 0) - { - acceptance_sets = new BitArray(number_of_acceptance_sets); - acceptance_sets->clear(number_of_acceptance_sets); - } - acceptance_stack.push_front(make_pair(scc_id, acceptance_sets)); -merge_sets: - product->operations.mergeAcceptanceInformation - (t.firstComponent(), t.secondComponent(), *acceptance_sets); -} - -/* ========================================================================= */ -template -inline void Product::AcceptanceTracker::addNodeToComponent - (const typename Product::size_type state_id, - const typename Product::size_type scc_id) -/* ---------------------------------------------------------------------------- - * - * Description: Adds the acceptance sets of the product state `state_id' to - * the collection of acceptance sets associated with a - * nontrivial strongly connected component identifier (a dfs - * number of a product state in Tarjan's algorithm). - * - * Arguments: state_id -- Identifier of the product state. - * scc_id -- Identifier of the strongly connected component - * (assumed to be >= 1). - * - * Returns: Nothing. Upon return, `this->acceptance_sets' either points - * to the acceptance sets associated with the topmost element of - * `this->acceptance_sets', or, if the component is a - * trivial strongly connected component, - * `this->acceptance_sets == 0'. - * - * ------------------------------------------------------------------------- */ -{ - /* - * When this function gets called, then depth-first search guarantees that - * the strongly connected component identifier of the topmost element (if - * such an element exists) of `this->acceptance_stack' is <= 'scc_id'. - * Furthermore, the strongly connected is nontrivial only if equality holds - * in the above test. - */ - - if (acceptance_stack.front().first < scc_id) - { - acceptance_sets = 0; - return; - } - - acceptance_sets = acceptance_stack.front().second; - product->operations.mergeAcceptanceInformation - (product->firstComponent(state_id), product->secondComponent(state_id), - *acceptance_sets); -} - -/* ========================================================================= */ -template -inline void Product::AcceptanceTracker::endComponent - (const typename Product::size_type scc_id) -/* ---------------------------------------------------------------------------- - * - * Description: Removes the association between a nontrivial strongly - * connected component identifier and a collection of acceptance - * sets when the component is not needed any longer. (This - * function gets called after extracting a maximal strongly - * connected component from the product. It is safe to remove - * the association at this point, because the search will not - * enter the component afterwards, nor can any state visited - * in the future belong to the strongly connected component - * identified by `scc_id'.) - * - * Argument: scc_id -- Identifier of the strongly connected component. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - /* - * Because the depth-first search made a call to `addNodeToComponent' before - * extracting the component from the product, the topmost element (if any) - * of `this->acceptance_stack' is guaranteed to have scc id <= `scc_id' at - * this point. - */ - - if (acceptance_stack.front().first == scc_id) - { - delete acceptance_stack.front().second; - acceptance_stack.pop_front(); - } -} - - - -/****************************************************************************** - * - * Inline function definitions for template class - * Product::SimpleEmptinessChecker. - * - *****************************************************************************/ - -/* ========================================================================= */ -template -inline Product::SimpleEmptinessChecker::SimpleEmptinessChecker - (const unsigned long int num_accept_sets) - : AcceptanceTracker(num_accept_sets), dummy(0) -/* ---------------------------------------------------------------------------- - * - * Description: Constructor for class - * Product::SimpleEmptinessChecker. - * - * Arguments: num_accept_sets -- Number of acceptance sets in the - * product. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -template -inline Product::SimpleEmptinessChecker::~SimpleEmptinessChecker() -/* ---------------------------------------------------------------------------- - * - * Description: Destructor for class - * Product::SimpleEmptinessChecker. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -template -inline const typename Product::SimpleEmptinessChecker::SccType& -Product::SimpleEmptinessChecker::operator()() const -/* ---------------------------------------------------------------------------- - * - * Description: Dummy function required for supporting the expected class - * interface. - * - * Arguments: None. - * - * Returns: A constant reference to `this->dummy'. - * - * ------------------------------------------------------------------------- */ -{ - return dummy; -} - -/* ========================================================================= */ -template -inline void Product::SimpleEmptinessChecker::addEdgeToComponent - (const typename Product::Edge& t, - const typename Product::size_type scc_id) -/* ---------------------------------------------------------------------------- - * - * Description: Adds a transition to a nontrivial strongly connected product - * component and aborts the search if the addition of the - * transition in the component makes the component accepting. - * - * Arguments: t -- A constant reference to the product transition to - * be added to the component. - * scc_id -- Identifier of the strongly connected component. - * - * Returns: Nothing; aborts the search by throwing the constant 0 if the - * addition of the transition in the component makes the - * component accepting. - * - * ------------------------------------------------------------------------- */ -{ - AcceptanceTracker::addEdgeToComponent(t, scc_id); - /* `this->acceptance_sets' points to the acceptance sets associated with - * the nontrivial SCC `scc_id' at this point. */ - abortIfNonempty(); -} - -/* ========================================================================= */ -template -inline void Product::SimpleEmptinessChecker::addNodeToComponent - (const typename Product::size_type state, - const typename Product::size_type scc_id) -/* ---------------------------------------------------------------------------- - * - * Description: Adds a state to a nontrivial strongly connected product - * component and aborts the search if the addition of the state - * in the component makes the component accepting. - * - * Arguments: state -- Identifier of a product state to be added to the - * component. - * scc_id -- Identifier of the strongly connected component. - * - * Returns: Nothing; aborts the search by throwing the constant 0 if the - * addition of the state in the component makes the component - * accepting. - * - * ------------------------------------------------------------------------- */ -{ - AcceptanceTracker::addNodeToComponent(state, scc_id); - /* If `this->acceptance_sets != 0', then `this->acceptance_sets' points to - * the acceptance sets associated with the nontrivial SCC `scc_id'; - * otherwise the component `scc_id' is a trivial SCC. */ - if (this->acceptance_sets != 0) - abortIfNonempty(); -} - -/* ========================================================================= */ -template -inline void Product::SimpleEmptinessChecker::abortIfNonempty() - const -/* ---------------------------------------------------------------------------- - * - * Description: Tests whether the strongly connected component with - * acceptance sets pointed to by `this->acceptance_sets' is an - * accepting component. This holds if all bits in the - * acceptance set bit vector pointed to by - * `this->acceptance_sets' are set to 1. - * - * Arguments: None. - * - * Returns: Nothing; throws the constant 0 if the component with - * acceptance sets pointed to by `this->acceptance_sets' is an - * accepting strongly connected component. - * - * ------------------------------------------------------------------------- */ -{ - if (this->acceptance_sets->count(this->number_of_acceptance_sets) - == this->number_of_acceptance_sets) - throw 0; -} - - - -/****************************************************************************** - * - * Inline function definitions for template class - * Product::AcceptanceReachabilityTracker. - * - *****************************************************************************/ - -/* ========================================================================= */ -template -inline Product::AcceptanceReachabilityTracker - ::AcceptanceReachabilityTracker - (const unsigned long int num_accept_sets) : - AcceptanceTracker(num_accept_sets), number_of_states(0), - number_of_transitions(0), mark_scc(false), dummy(0) -/* ---------------------------------------------------------------------------- - * - * Description: Constructor for class - * Product::AcceptanceReachabilityTracker. - * - * Arguments: num_accept_sets -- Number of acceptance sets in the - * product. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -template -inline Product::AcceptanceReachabilityTracker - ::~AcceptanceReachabilityTracker() -/* ---------------------------------------------------------------------------- - * - * Description: Destructor for class - * Product::AcceptanceReachabilityTracker. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -template -inline -const typename Product::AcceptanceReachabilityTracker::SccType& -Product::AcceptanceReachabilityTracker::operator()() const -/* ---------------------------------------------------------------------------- - * - * Description: Dummy function required for supporting the expected class - * interface. - * - * Arguments: None. - * - * Returns: A constant reference to `this->dummy'. - * - * ------------------------------------------------------------------------- */ -{ - return dummy; -} - -/* ========================================================================= */ -template -inline void Product::AcceptanceReachabilityTracker::enter - (const typename Product::size_type) -/* ---------------------------------------------------------------------------- - * - * Description: Function called when entering a new state in the product. - * Increments the number of product states that have been - * explored. - * - * Arguments: The single argument is required to support the expected class - * interface. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - ++number_of_states; -} - -/* ========================================================================= */ -template -inline void Product::AcceptanceReachabilityTracker::backtrack - (const typename Product::size_type source, - const typename Product::Edge&, - const typename Product::size_type target) -/* ---------------------------------------------------------------------------- - * - * Description: Function called when backtracking from a state in the - * product. Increments the number of product edges that have - * been explored. Additionally, if the state from which the - * search backtracks belongs to the set of states from which an - * accepting strongly connected component is known to be - * reachable in the product, adds also the state to which the - * search backtracks into this set of states. - * - * Arguments: (source, target) describe the endpoints of the product - * transition along which the backtrack occurs (i.e., `source' - * is the state _to_ which the search backtracks). The second - * argument is only needed to support the expected function call - * interface. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - ++number_of_transitions; - if (isMarked(target)) - markState(source); -} - -/* ========================================================================= */ -template -inline void Product::AcceptanceReachabilityTracker::touch - (const typename Product::size_type source, - const typename Product::Edge& edge, - const typename Product::size_type target) -/* ---------------------------------------------------------------------------- - * - * Description: Function called when the search encounters an edge with a - * target node that has already been explored. Increments the - * number of explored product transitions and updates accepting - * strongly connected reachability information by calling - * `this->backtrack()'. (This function is needed for supporting - * the expected class interface.) - * - * Arguments: (source, edge, target) describe the product transition that - * "touches" the state `target'. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - backtrack(source, edge, target); -} - -/* ========================================================================= */ -template -inline void Product::AcceptanceReachabilityTracker::beginComponent - (const typename Product::size_type, - const typename Product::size_type state_id) -/* ---------------------------------------------------------------------------- - * - * Description: Tests whether the maximal strongly connected component that - * is about to be extracted from the product is an accepting - * component, or if the component contains a state from which - * such a component is known to be reachable. If either of - * these properties holds, `this->mark_scc' is set to true to - * cause all states referred to in subsequent calls to - * `this->insert' that occur before the next call to - * `this->endComponent' to be added into the set of states from - * which an accepting strongly connected component in the - * product is known to be reachable. - * - * A component is accepting iff `this->acceptance_sets' points - * to a bit vector in which all bits are set to 1. - * - * Arguments: state_id -- Identifier of a product state (in the - * component) that was encountered first during - * the search. - * The first argument is needed to support the expected function - * interface. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - if (isMarked(state_id)) /* If the component itself is not accepting, but */ - mark_scc = true; /* it contains a state from which such a component */ - /* is reachable, then the fact that `state_id' is */ - /* the first state of the component encountered */ - /* during the search and the operation of the */ - /* backtrack and touch functions guarantee that */ - /* `isMarked(state_id) == true' holds at this */ - /* point (the search is about to backtrack from */ - /* this state when this function gets called). */ - else /* test whether the component is an accepting component */ - { - /* - * The dfs search guarantees (by having made a call to - * AcceptanceTracker::addNodeToComponent before calling this function) that - * `this->acceptance_sets' is either equal to 0 (in which case the - * component to be extracted is trivial), or it points to the acceptance - * sets associated with the component to be extracted. - */ - mark_scc = (this->acceptance_sets != 0 - && this->acceptance_sets->count - (this->number_of_acceptance_sets) - == this->number_of_acceptance_sets); - } -} - -/* ========================================================================= */ -template -inline void Product::AcceptanceReachabilityTracker::insert - (const typename Product::size_type state) -/* ---------------------------------------------------------------------------- - * - * Description: If `this->mark_scc == true', inserts a product state - * identifier to the set of states from which an accepting - * strongly connected component is known to be reachable in the - * product. Discards the state otherwise. - * - * Argument: state -- Identifier of a product state. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - if (mark_scc) - markState(state); -} - -/* ========================================================================= */ -template -inline bool Product::AcceptanceReachabilityTracker::isMarked - (const typename Product::size_type state) const -/* ---------------------------------------------------------------------------- - * - * Description: Tells whether an accepting strongly connected component is - * known to be reachable from a state in the product. - * - * Argument: state -- Identifier of the product state to test. - * - * Returns: true iff an accepting strongly connected component is known - * to be reachable from the product state. - * - * ------------------------------------------------------------------------- */ -{ - return (reachability_info.find(state) != reachability_info.end()); -} - -/* ========================================================================= */ -template -inline typename Product::size_type -Product::AcceptanceReachabilityTracker::numberOfStates() const -/* ---------------------------------------------------------------------------- - * - * Description: Tells the number of product states explored during the - * search. - * - * Arguments: None. - * - * Returns: Number of product states explored. - * - * ------------------------------------------------------------------------- */ -{ - return number_of_states; -} - -/* ========================================================================= */ -template -inline unsigned long int -Product::AcceptanceReachabilityTracker::numberOfTransitions() const -/* ---------------------------------------------------------------------------- - * - * Description: Tells the number of product transitions explored during the - * search. - * - * Arguments: None. - * - * Returns: Number of transitions explored. - * - * ------------------------------------------------------------------------- */ -{ - return number_of_transitions; -} - -/* ========================================================================= */ -template -inline void Product::AcceptanceReachabilityTracker::markState - (const typename Product::size_type state) -/* ---------------------------------------------------------------------------- - * - * Description: Adds a product state to the set of states from which an - * accepting strongly connected component is known to be - * reachable in the product. - * - * Argument: state -- Identifier of a product state. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - reachability_info.insert(state); -} - - - -/****************************************************************************** - * - * Inline function definitions for template class - * Product::AcceptingComponentFinder. - * - *****************************************************************************/ - -/* ========================================================================= */ -template -inline Product::AcceptingComponentFinder::AcceptingComponentFinder - (const unsigned long int num_accept_sets) - : AcceptanceTracker(num_accept_sets), construct_component(false) -/* ---------------------------------------------------------------------------- - * - * Description: Constructor for class - * Product::AcceptingComponentFinder. - * - * Arguments: num_accept_sets -- Number of acceptance sets in the - * product. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -template -inline Product::AcceptingComponentFinder - ::~AcceptingComponentFinder() -/* ---------------------------------------------------------------------------- - * - * Description: Destructor for class - * Product::AcceptingComponentFinder. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -template -inline const typename Product::AcceptingComponentFinder::SccType& -Product::AcceptingComponentFinder::operator()() const -/* ---------------------------------------------------------------------------- - * - * Description: Returns the latest accepting maximal strongly connected - * component found in the product. - * - * Arguments: None. - * - * Returns: A constant reference to a set of states containing the - * identifiers of product states forming an accepting maximal - * strongly connected component in the product. This set is - * empty if no such component has yet been found during the - * emptiness check. - * - * ------------------------------------------------------------------------- */ -{ - return scc; -} - -/* ========================================================================= */ -template -inline void Product::AcceptingComponentFinder::beginComponent - (const typename Product::size_type, - const typename Product::size_type) -/* ---------------------------------------------------------------------------- - * - * Description: Tests whether the maximal strongly connected component that - * is about to be extracted from the product is an accepting - * component. If this is the case, `this->construct_component' - * is set to true to cause all states referred to in subsequent - * calls to `this->insert' that occur before the next call to - * `this->endComponent' to be inserted into `this->scc'. - * - * A component is accepting iff `this->acceptance_sets' points - * to a bit vector in which all bits are set to 1. - * - * Arguments: The arguments are required to support the expected class - * interface. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - scc.clear(); - /* - * The dfs search guarantees (by having made a call to - * AcceptanceTracker::addNodeToComponent before calling this function) that - * `this->acceptance_sets' is either equal to 0 (in which case the component - * to be extracted is trivial), or it points to the acceptance sets - * associated with the component to be extracted. - */ - construct_component = (this->acceptance_sets != 0 - && this->acceptance_sets->count - (this->number_of_acceptance_sets) - == this->number_of_acceptance_sets); -} - -/* ========================================================================= */ -template -inline void Product::AcceptingComponentFinder::insert - (const typename Product::size_type state) -/* ---------------------------------------------------------------------------- - * - * Description: If `this->construct_component == true', inserts a product - * state identifier to the set of identifiers representing an - * accepting maximal strongly connected component. Discards the - * state otherwise. - * - * Argument: state -- Identifier of a product state. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - if (construct_component) - scc.insert(state); -} - -} - -#endif /* !PRODUCT_H */ diff --git a/lbtt/src/ProductAutomaton.cc b/lbtt/src/ProductAutomaton.cc deleted file mode 100644 index c733e57d7..000000000 --- a/lbtt/src/ProductAutomaton.cc +++ /dev/null @@ -1,1063 +0,0 @@ -/* - * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 - * Heikki Tauriainen - * - * 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 -#include "ProductAutomaton.h" -#include "SccIterator.h" - -namespace Graph -{ - -/****************************************************************************** - * - * Function definitions for class ProductAutomaton. - * - *****************************************************************************/ - -/* ========================================================================= */ -void ProductAutomaton::clear() -/* ---------------------------------------------------------------------------- - * - * Description: Makes the automaton empty. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - buchi_automaton = 0; - statespace_size = 0; - -#ifdef HAVE_OBSTACK_H - for (vector::iterator state = nodes.begin(); - state != nodes.end(); - ++state) - static_cast(*state)->~ProductState(); - - if (!nodes.empty()) - { - store.free(*nodes.begin()); - nodes.clear(); - nodes.reserve(0); - } - -#endif /* HAVE_OBSTACK_H */ - - Graph::clear(); -} - -/* ========================================================================= */ -ProductAutomaton::size_type ProductAutomaton::expand(size_type node_count) -/* ---------------------------------------------------------------------------- - * - * Description: Inserts states to a ProductAutomaton. - * - * Argument: node_count -- Number of states to be inserted. - * - * Returns: The index of the last state inserted. - * - * ------------------------------------------------------------------------- */ -{ - nodes.reserve(nodes.size() + node_count); - - while (node_count > 0) - { -#ifdef HAVE_OBSTACK_H - void* state_storage = store.alloc(sizeof(ProductState)); - ProductState* new_product_state = new(state_storage) ProductState(); -#else - ProductState* new_product_state = new ProductState(); -#endif /* HAVE_OBSTACK_H */ - - try - { - nodes.push_back(new_product_state); - } - catch (...) - { -#ifdef HAVE_OBSTACK_H - new_product_state->~ProductState(); - store.free(state_storage); -#else - delete new_product_state; -#endif /* HAVE_OBSTACK_H */ - throw; - } - node_count--; - } - - return size() - 1; -} - -/* ========================================================================= */ -void ProductAutomaton::connect(const size_type father, const size_type child) -/* ---------------------------------------------------------------------------- - * - * Description: Connects two states of the product automaton. - * - * Arguments: father, child -- State identifiers. - * - * 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 ProductAutomaton::disconnect - (const size_type father, const size_type child) -/* ---------------------------------------------------------------------------- - * - * Description: Disconnects two states of the product automaton. - * - * 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 ProductAutomaton::print - (ostream& stream, const int indent, const GraphOutputFormat) const -/* ---------------------------------------------------------------------------- - * - * Description: Writes information about a product automaton to a stream. - * - * Arguments: stream -- A reference to an output stream. - * indent -- Number of spaces to leave to the left of output. - * - * The third (dummy) parameter is needed to support the - * function interface defined in the base class. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - Exceptional_ostream estream(&stream, ios::failbit | ios::badbit); - - if (nodes.empty()) - estream << string(indent, ' ') + "The product automaton is empty.\n"; - else - { - pair statistics = stats(); - bool first_printed; - - estream << string(indent, ' ') + "The product automaton consists of\n" - + string(indent + 4, ' ') - << statistics.first - << " states and\n" + string(indent + 4, ' ') - << statistics.second - << " transitions.\n"; - - size_type s = nodes.size(); - for (size_type state = 0; state < s; ++state) - { - estream << string(indent, ' ') + "State " << state << ":\n" - + string(indent + 4, ' ') + "Automaton state: " - << buchiState(state) - << " (acceptance sets: {"; - - for (unsigned long int acceptance_set = 0; - acceptance_set < buchi_automaton->numberOfAcceptanceSets(); - acceptance_set++) - { - if ((*buchi_automaton)[buchiState(state)].acceptanceSets(). - test(acceptance_set)) - { - if (first_printed) - estream << ", "; - else - first_printed = true; - estream << acceptance_set; - } - } - - estream << "}\n" + string(indent + 4, ' ') + "System state: " - << systemState(state) - << '\n'; - - operator[](state).print(stream, indent + 4); - } - } - - estream.flush(); -} - -/* ========================================================================= */ -void ProductAutomaton::computeProduct - (const BuchiAutomaton& automaton, const StateSpace& statespace, - const bool global_product) -/* ---------------------------------------------------------------------------- - * - * Description: Initializes the synchronous product of a Büchi automaton and - * a state space. - * - * Arguments: automaton -- A reference to a constant BuchiAutomaton. - * statespace -- A reference to a constant StateSpace. - * global_product -- Controls whether the synchronous product - * of the automaton and the statespace is - * computed `globally' (i.e., with respect - * to all states in the state space) or - * `locally' (i.e., with respect only to the - * initial state of the state space). - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - clear(); - - buchi_automaton = &automaton; - statespace_size = statespace.size(); - - /* - * If either the Büchi automaton or the state space is empty, their product - * is also empty. - */ - - if (automaton.empty() || statespace.empty()) - return; - - /* - * If the (worst-case) product of the size of the automaton and the state - * space size exceeds the maximum size of a product automaton, throw an - * exception (if this holds, the simple product state hashing technique - * used below will not work correctly). - */ - - if (automaton.size() > (nodes.max_size() / statespace.size())) - throw ProductSizeException(); - - /* - * Product states will be numerically encoded using the equation - * - * #P = #S + |S| * #B - * - * where - * |S| is the number of states in the state space, - * #P is an identifier of a product state, - * #S is an identifier of a state in the state space (0...|S|-1), - * #B is an identifier of a state in the Büchi automaton (0...|B|-1) - * and - * - * From this encoding we obtain - * #S = #P % |S|, and - * #B = #P / |S|. - */ - - map, ALLOC(size_type) > - product_state_mapping; - - /* - * Initialize the product automaton. If the product is to be computed - * globally, initialize the result with state pairs (q_0, s) where q_0 is - * the initial state of the Büchi automaton and s goes through all states - * in the state space. (These states will have the lowest indices in the - * product automaton, i.e. covering the index interval - * 0 ... [statespace.size() - 1] .) In the case of a local product, - * initialize the result with the single state (q_0, s_0), a pair consisting - * of the initial states of the two other structures. - * - * The final product automaton is obtained by computing the closure of this - * set of states under the product transition relation. For this purpose, - * a depth-first search will be used (with `mapping_stack' as the search - * stack; initially, it contains the same states as described above). - */ - - expand(global_product ? statespace.size() : 1); - - stack > mapping_stack; - - pair state_map_entry - = make_pair(automaton.initialState() * statespace_size, 0); - - for (state_map_entry.second = 0; - state_map_entry.second < (global_product ? statespace_size : 1); - ++state_map_entry.first, ++state_map_entry.second) - { - product_state_mapping.insert(state_map_entry); - mapping_stack.push(state_map_entry.first); - - operator[](state_map_entry.second).hashValue() = state_map_entry.first; - } - - /* - * Compute the product automaton by using a depth-first search. - */ - - const GraphEdgeContainer* automaton_transitions; - const GraphEdgeContainer* system_transitions; - - BuchiAutomaton::size_type current_automaton_state; - StateSpace::size_type current_system_state; - size_type current_product_state; - bool current_product_state_valid; - size_type current_mapping; - - try - { - while (!mapping_stack.empty()) - { - if (::user_break) - throw UserBreakException(); - - /* - * Pop a state mapping off the stack. - */ - - current_product_state_valid = false; - current_mapping = mapping_stack.top(); - mapping_stack.pop(); - - current_automaton_state = current_mapping / statespace_size; - current_system_state = current_mapping % statespace_size; - - /* - * Go through the transitions of the original Büchi automaton. For all - * transitions enabled in the current state of the state space: - * - * - Compute all product states that can be reached by firing the - * transition. These are the states (q', s') where q' is the - * state of the automaton after firing the transition and s' - * is a successor of the current state of the system. - * - * - If there is no corresponding product state for the state pair - * (q', s'), create a new product state and insert it into the - * product automaton. Push the mapping also on the stack so that - * the newly created product state will be eventually processed. - * - * - Connect the target product state to the current product state - * (in effect, storing information only about the _predecessors_ of - * each product state). This will result in a product space in - * which all edges are reversed. However, this is all that is - * needed since no information is needed about the successors of - * any product state when searching for the accepting cycles in the - * product graph (this will be performed using a backward search, - * see the functions `emptinessCheck' and - * `findAcceptingExecution'). - */ - - automaton_transitions = &automaton[current_automaton_state].edges(); - - for (GraphEdgeContainer::const_iterator - automaton_transition = automaton_transitions->begin(); - automaton_transition != automaton_transitions->end(); - ++automaton_transition) - { - if ((static_cast - (*automaton_transition))-> - enabled(statespace[current_system_state].positiveAtoms(), - statespace.numberOfPropositions())) - { - if (!current_product_state_valid) - { - current_product_state = product_state_mapping[current_mapping]; - current_product_state_valid = true; - system_transitions = &statespace[current_system_state].edges(); - } - - pair, ALLOC(size_type) > - ::iterator, - bool> - check_state; - - for (GraphEdgeContainer::const_iterator - system_transition = system_transitions->begin(); - system_transition != system_transitions->end(); - ++system_transition) - { - /* - * Compute a hash value for the target product state and test - * whether it has already been included in the product. - */ - - state_map_entry.first = - (*system_transition)->targetNode() - + statespace_size * (*automaton_transition)->targetNode(); - - check_state = product_state_mapping.insert(state_map_entry); - - if (check_state.second) /* insertion occurred */ - { - /* - * Create a new product state and adjust its hash value. - * `state_map_entry.second' holds the next free identifier for a - * new product state. - */ - - expand(); - - operator[](state_map_entry.second).hashValue() - = state_map_entry.first; - - connect(state_map_entry.second, current_product_state); - state_map_entry.second++; - - mapping_stack.push(state_map_entry.first); - } - else - { - size_type existing_state = (check_state.first)->second; - connect(existing_state, current_product_state); - } - } - } - } - } - } - catch (...) - { - clear(); - throw; - } -} - -/* ========================================================================= */ -void ProductAutomaton::emptinessCheck(Bitset& result) const -/* ---------------------------------------------------------------------------- - * - * Description: Performs an emptiness check on the product automaton, i.e. - * finds the set of system states starting an execution - * sequence accepted by the Büchi automaton. - * - * Argument: result -- A reference to the Bitset in which the result - * is stored. The Bitset must have enough space for - * as many states as there are in the state space. - * A `0' bit in some position n in the result means - * that no accepting executions begin from system - * state n; a `1' bit means the opposite. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - BitArray visited(nodes.size()); - visited.clear(nodes.size()); - - result.clear(); - - /* - * Scan the maximal strongly connected components of the product space to - * find any fair MSCCs (nontrivial MSCCs containing an accepting cycle of - * the Büchi automaton used for constructing the product). Note that - * although the product space contains only back edges (i.e., we are - * actually scanning the product space with all edges reversed), the - * reversal of the edges does not affect the MSCCs of the product space. - */ - - for (SccIterator - strongly_connected_component(*this); - !strongly_connected_component.atEnd(); - ++strongly_connected_component) - { - if (::user_break) - throw UserBreakException(); - - if (strongly_connected_component->fair(*this)) - { - /* - * Search for a previously unvisited state in the strongly connected - * component. - */ - - ProductScc::const_iterator st; - for (st = strongly_connected_component->begin(); - st != strongly_connected_component->end() && visited[*st]; - ++st) - ; - - if (st != strongly_connected_component->end()) - { - /* - * Starting from the unvisited state, perform a backward depth-first - * search to find all states (q_0, s) such that q_0 is the initial - * state of the automaton (the product states (q_0, s) are recognized - * by the product state numbering scheme, in which these states have - * the lowest indices). Add the corresponding system states to the - * result (these are the system states from which the nontrivial MSCC - * containing the accepting cycle can be reached). - */ - - size_type state = *st; - stack > - backward_search_stack; - const GraphEdgeContainer* predecessors; - - visited.setBit(state); - backward_search_stack.push(state); - - while (!backward_search_stack.empty()) - { - state = backward_search_stack.top(); - backward_search_stack.pop(); - - if (state < result.capacity() && state < statespace_size) - result.setBit(systemState(state)); - - predecessors = &(operator[](state).edges()); /* note that only back - * edges are stored in - * the product! */ - - for (GraphEdgeContainer::const_iterator predecessor - = predecessors->begin(); - predecessor != predecessors->end(); - ++predecessor) - { - if (!visited[(*predecessor)->targetNode()]) - { - backward_search_stack.push((*predecessor)->targetNode()); - visited.setBit((*predecessor)->targetNode()); - } - } - } - } - } - } -} - -/* ========================================================================= */ -void ProductAutomaton::findAcceptingExecution - (const StateSpace::size_type initial_state, - pair, - deque >& execution) const -/* ---------------------------------------------------------------------------- - * - * Description: Extracts an execution (beginning from a given system - * state) accepted by the Büchi automaton from the product - * space. The function behaves basically like - * ProductAutomaton::emptinessCheck, but it keeps additional - * information about the path of processed states during the - * backward search. This information is then used to extract - * the desired system execution from the graph. - * - * Arguments: initial_state -- Identifier of the system state. - * execution -- A reference to a pair of deques for - * storing the result. The `first' component - * of the pair represents an execution - * `prefix' (a sequence of - * - * pairs) leading from `initial_state' - * to an accepting cycle. The `second' - * component of the pair contains the cycle - * itself. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - BitArray visited(nodes.size()); - visited.clear(nodes.size()); - - deque& prefix = execution.first; - deque& cycle = execution.second; - - prefix.clear(); - cycle.clear(); - - /* - * Scan the non-trivial maximal strongly connected components of the - * product space to find the fair MSCCs (non-trivial MSCCs containing an - * accepting cycle of the Büchi automaton used for constructing the - * product). Note that although the product space contains only back edges - * (i.e., we are actually scanning the product space with all edges - * reversed), the reversal of the edges does not affect the MSCCs of the - * product space. - */ - - for (SccIterator nmscc(*this); - !nmscc.atEnd(); - ++nmscc) - { - if (nmscc->fair(*this)) - { - const unsigned long int num_accept_sets - = buchi_automaton->numberOfAcceptanceSets(); - - /* - * Search the fair non-trivial maximal strongly connected component for - * a state belonging to some acceptance set of the Büchi automaton from - * which the product was constructed (or if the automaton has no - * acceptance sets, any state in the non-trivial MSCC). - */ - - ProductScc::const_iterator st = nmscc->begin(); - - if (buchi_automaton->numberOfAcceptanceSets() > 0) - { - while (st != nmscc->end()) - { - if ((*buchi_automaton)[buchiState(*st)].acceptanceSets(). - find(num_accept_sets) - < num_accept_sets) - break; - - ++st; - } - } - - if (st != nmscc->end()) - { - /* - * Try to find a (backward) path from the state in the MSCC back to - * the caller-given `initial state'. - */ - - size_type search_start_state = *st; - - if (search_start_state != initial_state) - { - typedef pair - BackwardSearchStackElement; - - deque - backward_search_stack; - - visited.clear(nodes.size()); - visited.setBit(search_start_state); - backward_search_stack.push_back - (make_pair(search_start_state, - operator[](search_start_state).edges().begin())); - - size_type predecessor; - - while (!backward_search_stack.empty()) - { - /* - * If it may be possible to find a shorter path to the initial - * state by still extending the current path (or if no path to - * the initial state has yet been found), scan through the - * predecessors of the `current' state (the last state inserted - * onto `backward_search_stack'). - */ - - while ((backward_search_stack.size() < prefix.size() - || prefix.empty()) - && backward_search_stack.back().second - != operator[](backward_search_stack.back().first) - .edges().end()) - { - predecessor - = (*backward_search_stack.back().second)->targetNode(); - - backward_search_stack.back().second++; - - /* - * If the given `initial state' is a predecessor of the current - * state, extract the path from the initial state to the state - * from where the backward search was started. - */ - - if (buchiState(predecessor) == buchi_automaton->initialState() - && systemState(predecessor) == initial_state) - { - prefix.clear(); - for (deque - ::const_iterator - state = backward_search_stack.begin(); - state != backward_search_stack.end(); - ++state) - { - prefix.push_front(make_pair(buchiState((*state).first), - systemState((*state).first))); - } - prefix.push_front(make_pair(buchiState(predecessor), - systemState(predecessor))); - } - - /* - * If some predecessor of the current state has not yet been - * visited, push it onto the backward search stack, then proceed - * with checking its predecessors. - */ - - else if (!visited[predecessor]) - { - visited.setBit(predecessor); - backward_search_stack.push_back - (make_pair(predecessor, - operator[](predecessor).edges().begin())); - } - } - - /* - * If all predecessors of a state have been processed, backtrack - * to the previous state on the path. - */ - - backward_search_stack.pop_back(); - } - } - - /* - * If a path was found from the `initial state' to the state in the - * MSCC, construct an accepting cycle by performing a breadth-first - * search in the MSCC. - */ - - if (!prefix.empty() || search_start_state == initial_state) - { - BitArray in_nmscc(nodes.size()); - in_nmscc.clear(nodes.size()); - - for (ProductScc::const_iterator state = nmscc->begin(); - state != nmscc->end(); - ++state) - in_nmscc.setBit(*state); - - BitArray collected_acc_sets; - collected_acc_sets.copy - ((*buchi_automaton)[buchiState(search_start_state)] - .acceptanceSets(), - num_accept_sets); - bool all_acceptance_sets_on_path - = (collected_acc_sets.count(num_accept_sets) == num_accept_sets); - - deque backward_search_queue; - map, ALLOC(size_type) > - shortest_path_predecessor; - - size_type bfs_root = search_start_state; - const GraphEdgeContainer* predecessors; - size_type state; - - visited.clear(nodes.size()); - visited.setBit(bfs_root); - backward_search_queue.push_back(bfs_root); - - bool cycle_finished = false; - - while (!cycle_finished) - { - predecessors = &operator[](backward_search_queue.front()).edges(); - - for (GraphEdgeContainer::const_iterator - predecessor = predecessors->begin(); - predecessor != predecessors->end(); - ++predecessor) - { - state = (*predecessor)->targetNode(); - - if (in_nmscc[state]) - { - /* - * If all acceptance sets have been collected and the search - * finds the first state of the cycle again, the cycle is - * complete. - */ - - if (all_acceptance_sets_on_path && state == search_start_state) - { - cycle_finished = true; - state = backward_search_queue.front(); - break; - } - else if (!visited[state]) - { - /* - * Update information about the breadth-first predecessor of - * an unvisited state. - */ - - shortest_path_predecessor[state] - = backward_search_queue.front(); - - /* - * If the unvisited state does not cover any `new' - * acceptance conditions, prepare to continue the search in - * that state by inserting the state into the search queue. - */ - - if (all_acceptance_sets_on_path - || (*buchi_automaton)[buchiState(state)].acceptanceSets() - .subset(collected_acc_sets, num_accept_sets)) - { - visited.setBit(state); - backward_search_queue.push_back(state); - } - - /* - * If the search finds an unvisited state which covers new - * acceptance sets, begin a new breadth-first search in - * that state. - */ - - else - { - all_acceptance_sets_on_path = true; - - for (unsigned long int accept_set = 0; - accept_set - < buchi_automaton->numberOfAcceptanceSets(); - accept_set++) - { - if ((*buchi_automaton)[buchiState(state)] - .acceptanceSets().test(accept_set)) - collected_acc_sets.setBit(accept_set); - else if (!collected_acc_sets.test(accept_set)) - all_acceptance_sets_on_path = false; - } - - deque cycle_fragment; - while (state != bfs_root) - { - cycle_fragment.push_back(make_pair(buchiState(state), - systemState(state))); - state = shortest_path_predecessor[state]; - } - cycle.insert(cycle.begin(), cycle_fragment.begin(), - cycle_fragment.end()); - - bfs_root = (*predecessor)->targetNode(); - visited.clear(nodes.size()); - visited.setBit(bfs_root); - backward_search_queue.clear(); - backward_search_queue.push_back(bfs_root); - backward_search_queue.push_back(bfs_root); - - break; - } - } - } - } - - backward_search_queue.pop_front(); - } - - deque cycle_fragment; - while (state != bfs_root) - { - cycle_fragment.push_back(make_pair(buchiState(state), - systemState(state))); - state = shortest_path_predecessor[state]; - } - - cycle.insert(cycle.begin(), cycle_fragment.begin(), - cycle_fragment.end()); - cycle.push_back(make_pair(buchiState(search_start_state), - systemState(search_start_state))); - - /* - * "Synchronize" the prefix of the witness execution with its cycle - * by removing from the end of the prefix the longest subsequence of - * states which occurs in the end of the cycle. The states in the - * cycle must be "rotated" accordingly to align the first state of - * the cycle correctly. - */ - - while (!prefix.empty() && prefix.back() == cycle.back()) - { - cycle.push_front(cycle.back()); - prefix.pop_back(); - cycle.pop_back(); - } - - return; - } - } - } - } - - /* - * The result will be empty if no accepting execution beginning from the - * given initial state could be found. - */ -} - - - -/****************************************************************************** - * - * Function definitions for class ProductAutomaton::ProductState. - * - *****************************************************************************/ - -/* ========================================================================= */ -void ProductAutomaton::ProductState::print - (ostream& stream, const int indent, const GraphOutputFormat) const -/* ---------------------------------------------------------------------------- - * - * Description: Writes information about the ProductState to a stream. - * - * Arguments: stream -- A reference to an output stream. - * indent -- Number of spaces to leave to the left of output. - * - * The third (dummy) argument is needed to support the function - * interface defined in the base class. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - Exceptional_ostream estream(&stream, ios::failbit | ios::badbit); - - if (edges().empty()) - estream << string(indent,' ') + "The product state has no predecessors.\n"; - else - { - bool first_printed = false; - estream << string(indent, ' ') + "Predecessor states: {"; - - for (GraphEdgeContainer::const_iterator predecessor = edges().begin(); - predecessor != edges().end(); ++predecessor) - { - if (first_printed) - estream << ", "; - else - first_printed = true; - estream << (*predecessor)->targetNode(); - } - estream << "}\n"; - } - - estream.flush(); -} - - - -/****************************************************************************** - * - * Function definitions for class ProductAutomaton::ProductScc. - * - *****************************************************************************/ - -/* ========================================================================= */ -bool ProductAutomaton::ProductScc::fair - (const ProductAutomaton& product_automaton) const -/* ---------------------------------------------------------------------------- - * - * Description: Tests whether a strongly connected component is fair in - * a product automaton. A strongly connected component is - * fair if and only if it is nontrivial (i.e. empty or - * containing a single state with a self-loop) and contains a - * state corresponding to a state from every acceptance set of - * the Büchi automaton used for constructing the given product. - * - * Arguments: product_automaton -- A constant reference to a - * ProductAutomaton. - * - * Returns: A truth value telling whether the strongly connected - * component is fair. - * - * ------------------------------------------------------------------------- */ -{ - /* - * A maximal strongly connected component is not fair if it is trivial. - */ - - if (empty() - || (size() == 1 && !product_automaton.connected(*begin(), *begin()))) - return false; - - /* - * Check whether the strongly connected component contains a state from each - * acceptance set of the Büchi automaton used for constructing the product - * (in this case, the component contains an accepting cycle of the - * automaton and is therefore fair). - */ - - const BuchiAutomaton* buchi_automaton = product_automaton.buchi_automaton; - const BitArray* acceptance_sets; - const unsigned long int number_of_acceptance_sets - = buchi_automaton->numberOfAcceptanceSets(); - - BitArray acceptance_sets_in_scc(number_of_acceptance_sets); - acceptance_sets_in_scc.clear(number_of_acceptance_sets); - - unsigned long int accept_set; - unsigned long int acceptance_set_counter = 0; - - for (const_iterator st = begin(); - st != end() && acceptance_set_counter < number_of_acceptance_sets; - ++st) - { - acceptance_sets = &(*buchi_automaton)[product_automaton.buchiState(*st)]. - acceptanceSets(); - - accept_set = acceptance_set_counter; - while (accept_set < number_of_acceptance_sets) - { - if (acceptance_sets->test(accept_set)) - { - acceptance_sets_in_scc.setBit(accept_set); - if (accept_set == acceptance_set_counter) - { - do - acceptance_set_counter++; - while (acceptance_set_counter < number_of_acceptance_sets - && acceptance_sets_in_scc[acceptance_set_counter]); - accept_set = acceptance_set_counter; - continue; - } - } - - accept_set++; - } - } - - return (acceptance_set_counter == number_of_acceptance_sets); -} - -} diff --git a/lbtt/src/ProductAutomaton.h b/lbtt/src/ProductAutomaton.h deleted file mode 100644 index 060491c7d..000000000 --- a/lbtt/src/ProductAutomaton.h +++ /dev/null @@ -1,596 +0,0 @@ -/* - * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 - * Heikki Tauriainen - * - * 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 -#include -#include -#include -#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 -{ -private: - /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - - class ProductState : /* A class for */ - public Graph::Node /* representing the */ - { /* states of the product - * automaton. - */ - public: - explicit ProductState /* Constructor. */ - (const size_type hash_val = 0); - - ~ProductState(); /* Destructor. */ - - /* `edges' inherited from Graph::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 /* 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 */ - - /* `empty' inherited from Graph */ - - 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 */ - - /* `stats' inherited from Graph */ - - /* `subgraphStats' inherited from Graph */ - - 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, /* product automaton. */ - deque >& - 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(*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(Graph::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::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 */ diff --git a/lbtt/src/Random.h b/lbtt/src/Random.h deleted file mode 100644 index bd69ec27c..000000000 --- a/lbtt/src/Random.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 - * Heikki Tauriainen - * - * 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 -#include - -#ifdef HAVE_RAND48 -#define rand lrand48 -#define srand srand48 -static const double MAXRAND = static_cast(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(DRAND() * (max - min)); -} - -#ifdef HAVE_RAND48 -#undef rand -#undef srand -#endif /* HAVE_RAND48 */ - -#endif /* !RANDOM_H */ diff --git a/lbtt/src/SccCollection.h b/lbtt/src/SccCollection.h deleted file mode 100644 index 32c5fc294..000000000 --- a/lbtt/src/SccCollection.h +++ /dev/null @@ -1,1172 +0,0 @@ -/* - * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 - * Heikki Tauriainen - * - * 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 SCCCOLLECTION_H -#define SCCCOLLECTION_H - -#include -#include -#include -#include -#include -#include -#include "EdgeContainer.h" -#include "LbttAlloc.h" -#include "Graph.h" - -using namespace std; - -namespace Graph -{ - -/****************************************************************************** - * - * Interface for a "node visitor" object that provides implementations of - * callback functions to be used during a depth-first search for strongly - * connected components. The VisitorInterface class provides empty - * implementations for the operations; visitor objects can be defined by making - * them inherit the VisitorInterface and then overriding some (or all) of the - * interface functions. - * - * A "node visitor" object must always implement the following type definition - * and operation: - * - * SccType - * A type definition for storing data associated with a maximal strongly - * connected component. This data type should support copying and - * assignment; no other assumptions are made about the internals of this - * data type. It is intended that a node visitor object has a member of - * type SccType (which need not be public); this member can then be - * manipulated freely during the search for strongly connected - * components by giving implementations for the other interface - * functions listed below. - * - * const SccType& operator()() - * Function for accessing the data associated with a maximal strongly - * connected component. This function is called when dereferencing a - * strongly connected component iterator (see below). - * - * In addition, a node visitor can overload the default (empty) implementations - * for the following operations: - * - * void enter(typename GraphType::size_type node_id) - * This function is called whenever the search enters a new node of the - * graph, using the identifier of the node as a parameter. - * - * void backtrack - * (typename GraphType::size_type source_id, - * const typename GraphType::Edge& edge, - * typename GraphType::size_type target_id) - * This function is called when the search backtracks from a node with - * the identifier `target_id' to the node `source_id'. `edge' is a - * reference to the edge between graph nodes identified by `source_id' - * and `target_id'. - * - * void touch - * (typename GraphType::size_type source_id, - * const typename GraphType::Edge& edge, - * typename GraphType::size_type target_id) - * This function is called when the search (in node `source_id') - * encounters an edge (`edge') with a target node (with identifier - * `target_id') that has already been visited during the search. - * - * void leave(typename GraphType::size_type node_id) - * This function is called when the search leaves a node with the - * identifier `node_id'. - * - * void addEdgeToComponent - * (const typename GraphType::Edge& edge, - * typename GraphType::size_type component_id) - * This function is called when the search finds an edge belonging to a - * strongly connected component of the graph (i.e., an edge between two - * states in the component). The function is called with a constant - * reference to the edge and a strongly connected component identifier - * as parameters. - * - * void addNodeToComponent - * (typename GraphType::size_type node_id, - * typename GraphType::size_type component_id) - * This function is called when the search finds a state belonging to a - * strongly connected component of the graph. - * - * void beginComponent - * (typename GraphType::size_type component_id, - * typename GraphType::size_type component_root_id) - * This function is called when the SCC algorithm is about to extract a - * new maximal strongly connected component from the graph. Here, - * `component_id' corresponds to the identifier of the component, and - * `component_root_id' is the identifier of the node in the component - * which was first encountered during the search (the depth-first search - * is about to backtrack from this node). - * - * void insert(typename GraphType::size_type node_id) - * After a call to `beginComponent', the SCC search algorithm will call - * `insert' for each identifier of a node in the maximal strongly - * connected component. - * - * void endComponent(typename GraphType::size_type component_id) - * This function is called after the SCC algorithm has finished - * `insert''ing nodes into a maximal strongly connected component. The - * component identifier is given as a parameter. - * - *****************************************************************************/ - -template -class VisitorInterface -{ -public: - VisitorInterface(); /* Constructor. */ - - /* default copy constructor */ - - virtual ~VisitorInterface(); /* Destructor. */ - - /* default assignment operator */ - - virtual void enter /* Interface operations. */ - (const typename GraphType::size_type); - - virtual void backtrack - (const typename GraphType::size_type, - const typename GraphType::Edge&, - const typename GraphType::size_type); - - virtual void touch - (const typename GraphType::size_type, - const typename GraphType::Edge&, - const typename GraphType::size_type); - - virtual void leave - (const typename GraphType::size_type); - - virtual void addEdgeToComponent - (const typename GraphType::Edge&, - const typename GraphType::size_type); - - virtual void addNodeToComponent - (const typename GraphType::size_type, - const typename GraphType::size_type); - - virtual void beginComponent - (const typename GraphType::size_type, - const typename GraphType::size_type); - - virtual void insert - (const typename GraphType::size_type); - - virtual void endComponent - (const typename GraphType::size_type); -}; - - - -/****************************************************************************** - * - * A template class defining a node visitor for collecting the identifiers of - * nodes in a maximal strongly connected component into a set. - * - *****************************************************************************/ - -template -class SccCollector : public VisitorInterface -{ -public: - SccCollector(); /* Constructor. */ - - /* default copy constructor */ - - ~SccCollector(); /* Destructor. */ - - /* default assignment operator */ - - typedef set /* Type definition for */ - SccType; /* a set of node id's. */ - - const SccType& operator()() const; /* Returns the set of node - * identifiers in a - * maximal strongly - * connected component. - */ - - /* `enter' inherited */ - - /* `backtrack' inherited */ - - /* `touch' inherited */ - - /* `leave' inherited */ - - /* `addEdgeToComponent' inherited */ - - /* `addNodeToComponent' inherited */ - - void beginComponent /* Function called */ - (const typename GraphType::size_type, /* before inserting */ - const typename GraphType::size_type); /* nodes in a component. */ - - void insert /* Function for */ - (const typename GraphType::size_type node_id); /* inserting nodes into - * a component. - */ - - /* `endComponent' inherited */ - -private: - SccType scc; /* A set of node - * identifiers representing - * a maximal strongly - * connected component. - */ -}; - - - -/****************************************************************************** - * - * A template class for defining a "container" of maximal strongly connected - * components of a graph. The template should be instantiated with two classes - * GraphType and NodeVisitor, where the NodeVisitor type should support the - * interface required of a node visitor (see the above documentation of - * VisitorInterface), and GraphType (which defaults to - * Graph) should support the following type definitions and - * operations: - * - * size_type - * A type that can be used for identifying nodes (uniquely) in the - * graph. This type should have a constructor taking no parameters, - * and it should support copying, assignment, and comparison using the - * `less than' operator. - * - * EdgeContainerType - * A type that represents a container of objects behaving similarly to - * pointers to edges in the graph. This type is expected to have an - * STL-like container interface with `begin()' and `end()' operations - * and a const_iterator with a constructor having no parameters and - * copying and assignment operations. - * - * The objects in the container should behave similarly to pointers - * that can be dereferenced using the * and -> operators to get access - * to objects (the edges in the graph, e.g., - * Graph::Edge) that support the operation - * size_type targetNode() - * that returns the identifier of an edge's target node in the graph. - * - * PathElement - * An object for representing (node_id, edge) pairs of the graph. - * The object should provide a constructor that can be called with two - * parameters: a parameter of type `size_type' and another parameter - * corresponding to the type obtained by dereferencing a pointer-like - * object stored in an object of type EdgeContainerType. - * - * Path - * A type that supports the `clear' operation (with no arguments) and - * the `push_front' operation with an argument of type PathElement. - * - * operator[](size_type node_id) - * This function should return an object that provides access to the - * edges starting from the graph node identified by `node_id' through - * the member function - * const EdgeContainerType& edges(), - * which returns the collection of (pointer-like objects to) edges - * beginning from the graph node with the identifier `node_id'. - * - * bool empty() - * This function should return true iff the graph contains no nodes. - * - * The NodeVisitor type defaults to SccCollector. - * - * The SccCollection class provides the following operations: - * - * SccCollection(const GraphType& g, NodeVisitor& node_visitor) - * Constructor that binds the SccCollection object to the graph `g' - * using the operations defined by `node_visitor' when visiting nodes - * of the graph during the search for strongly connected components. - * - * iterator begin(const typename GraphType::size_type initial_node_id) - * Returns an iterator to the strongly connected components of the - * graph. The function returns an iterator that points to the "first" - * maximal strongly connected component of the graph when starting the - * search for maximal strongly connected components from the node with - * the identifier `initial_node_id'. - * - * Note: If `initial_node_id' belongs to a strongly connected component - * of the graph which has alredy been visited by an iterator obtained - * by a previous call to `begin', the returned iterator is equal to - * `end()'. If this is not desired (i.e., if you wish to repeat the - * search for strongly connected components in a part of the graph, - * initialize a new SccCollection to the graph). - * - * iterator end() - * Returns an iterator pointing "past the end" of the collection of - * strongly connected components. - * - * The class `SccCollection::iterator' provides standard dereferencing and - * prefix and postfix increment operators. It also supports comparison for - * equality and inequality. See below for more detailed information. - * - *****************************************************************************/ - -template , - class NodeVisitor = SccCollector > -class SccCollection -{ -public: - SccCollection /* Constructor. */ - (const GraphType& g, - NodeVisitor& node_visitor); - - ~SccCollection(); /* Destructor. */ - - /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - - typedef map /* mapping between node */ - DfsOrdering; /* identifiers and the - * order in which they - * were encountered in - * the search for - * strongly connected - * components. - */ - - /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - - class iterator /* Iterator for */ - { /* accessing the maximal - * strongly connected - * components. - */ - public: - iterator(); /* Default constructor. */ - - /* default copy constructor */ - - ~iterator(); /* Destructor. */ - - /* default assignment operator */ - - bool operator==(const iterator& it) const; /* Comparison functions. */ - bool operator!=(const iterator& it) const; - - const typename NodeVisitor::SccType& /* Dereferencing */ - operator*() const; /* operators. */ - const typename NodeVisitor::SccType* - operator->() const; - - const typename NodeVisitor::SccType& /* Prefix and postfix */ - operator++(); /* increment operators. */ - const typename NodeVisitor::SccType - operator++(int); - - void getPath(typename GraphType::Path& path); /* Function for accessing - * the path from the - * initial node of the - * search to a node in - * the most recently found - * strongly connected - * component. - */ - - private: - iterator /* Constructor. */ - (const GraphType& g, - NodeVisitor& node_visitor, - DfsOrdering& ordering); - - void initialize /* Instructs the */ - (const typename GraphType::size_type /* iterator to continue */ - node_id); /* the search for - * strongly connected - * components from a - * given node. - */ - - const GraphType& graph; /* Reference to the graph - * with which the iterator - * is associated. - */ - - NodeVisitor& visitor; /* Reference to an object - * that provides - * implementations for the - * functions listed in the - * VisitorInterface class. - */ - - DfsOrdering& dfs_ordering; /* Mapping between node - * identifiers and their - * dfs numbers. - */ - - typename GraphType::size_type initial_node; /* Node from which the - * search was started. - */ - - typename GraphType::size_type dfs_number; /* Number of graph nodes - * processed by the - * iterator. - */ - - struct NodeStackElement /* Structure for */ - { /* storing information */ - typename GraphType::size_type id; /* needed for */ - typename GraphType::EdgeContainerType /* backtracking during */ - ::const_iterator edge; /* the search. */ - typename GraphType::size_type lowlink; - }; - - deque node_stack; /* Depth-first search - * backtracking stack. - */ - - - NodeStackElement* current_node; /* Pointer to the top - * element of the - * backtracking stack. - */ - - deque scc_stack; /* Stack used for - * collecting the nodes - * in a strongly - * connected component, - * excluding the root - * nodes of the - * components. - */ - - void computeNextScc(); /* Updates the iterator to - * point to the next - * strongly connected - * component. - */ - - friend class SccCollection; - }; - - /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - - iterator begin /* Returns an iterator */ - (const typename GraphType::size_type /* pointing to the */ - node_id); /* "first" maximal - * strongly connected - * component reachable - * from a given node. - */ - - const iterator& end() const; /* Returns an iterator - * pointing past the "end" - * of the maximal strongly - * connected components. - */ - -private: - SccCollection(const SccCollection&); /* Prevent copying and */ - SccCollection& operator=(const SccCollection&); /* assignment of - * SccCollection - * objects. - */ - - const GraphType& graph; /* Reference to the graph - * associated with the - * container. - */ - - NodeVisitor& visitor; /* Reference to an object - * that provides - * implementations for - * callback operations - * needed during the - * search for strongly - * connected components. - */ - - const iterator end_iterator; /* Iterator pointing past - * the "end" of the - * collection of strongly - * connected components in - * the graph. This - * iterator is special by - * having both - * `initial_node' and - * `dfs_number' set to 0. - */ - - DfsOrdering dfs_ordering; /* Mapping between node - * identifiers and their - * visiting order during - * the search for strongly - * connected components. - */ -}; - - - -/****************************************************************************** - * - * Inline function definitions for template class VisitorInterface. This class - * provides default empty implementations for node visitor operations. - * - *****************************************************************************/ - -template -inline VisitorInterface::VisitorInterface() -{ -} - -template -inline VisitorInterface::~VisitorInterface() -{ -} - -template -inline void VisitorInterface::enter - (const typename GraphType::size_type) -{ -} - -template -inline void VisitorInterface::backtrack - (const typename GraphType::size_type, const typename GraphType::Edge&, - const typename GraphType::size_type) -{ -} - -template -inline void VisitorInterface::touch - (const typename GraphType::size_type, const typename GraphType::Edge&, - const typename GraphType::size_type) -{ -} - -template -inline void VisitorInterface::leave - (const typename GraphType::size_type) -{ -} - -template -inline void VisitorInterface::addEdgeToComponent - (const typename GraphType::Edge&, const typename GraphType::size_type) -{ -} - -template -inline void VisitorInterface::addNodeToComponent - (const typename GraphType::size_type, const typename GraphType::size_type) -{ -} - -template -inline void VisitorInterface::beginComponent - (const typename GraphType::size_type, const typename GraphType::size_type) -{ -} - -template -inline void VisitorInterface::insert - (const typename GraphType::size_type) -{ -} - -template -inline void VisitorInterface::endComponent - (const typename GraphType::size_type) -{ -} - - - -/****************************************************************************** - * - * Inline function definitions for template class SccCollector. - * - *****************************************************************************/ - -/* ========================================================================= */ -template -inline SccCollector::SccCollector() -/* ---------------------------------------------------------------------------- - * - * Description: Constructor for class SccCollector. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -template -inline SccCollector::~SccCollector() -/* ---------------------------------------------------------------------------- - * - * Description: Destructor for class SccCollector. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -template -inline const typename SccCollector::SccType& -SccCollector::operator()() const -/* ---------------------------------------------------------------------------- - * - * Description: Returns the set of identifiers of nodes in the maximal - * strongly connected component. - * - * Arguments: None. - * - * Returns: A constant reference to the set of identifiers of nodes in - * the component. - * - * ------------------------------------------------------------------------- */ -{ - return scc; -} - -/* ========================================================================= */ -template -inline void SccCollector::beginComponent - (const typename GraphType::size_type, const typename GraphType::size_type) -/* ---------------------------------------------------------------------------- - * - * Description: Clears the set of node identifiers to make it empty before - * filling it with (identifiers of) nodes of a new maximal - * strongly connected component. - * - * Arguments: The arguments are needed to support the expected function - * calling interface. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - scc.clear(); -} - -/* ========================================================================= */ -template -inline void SccCollector::insert - (const typename GraphType::size_type node_id) -/* ---------------------------------------------------------------------------- - * - * Description: Inserts an identifier into the set of node identifiers in a - * maximal strongly connected component. - * - * Arguments: node_id -- Node identifier. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - scc.insert(node_id); -} - - - -/****************************************************************************** - * - * Inline function definitions for template class SccCollection. - * - *****************************************************************************/ - -/* ========================================================================= */ -template -inline SccCollection::SccCollection - (const GraphType& g, NodeVisitor& node_visitor) : - graph(g), visitor(node_visitor), end_iterator(g, node_visitor, dfs_ordering) -/* ---------------------------------------------------------------------------- - * - * Description: Constructor for class SccCollection. - * - * Arguments: g -- A constant reference to an object of type - * GraphType. See above for the description - * of the interface that this object should - * support. - * node_visitor -- A reference to an object that provides - * node visiting operations. See the - * documentation of VisitorInterface for more - * information. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -template -inline SccCollection::~SccCollection() -/* ---------------------------------------------------------------------------- - * - * Description: Destructor for class SccCollection. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -template -inline typename SccCollection::iterator -SccCollection::begin - (const typename GraphType::size_type node_id) -/* ---------------------------------------------------------------------------- - * - * Description: Returns an iterator pointing to the "first" strongly - * connected component reachable from a given node of - * `this->graph'. - * - * Argument: node_id -- Identifier of the node. - * - * Returns: An iterator pointing to the "first" strongly connected - * component reachable from the node, or an iterator equal to - * `this->end()' if the node with the identifier `node_id' has - * already been included in a strongly connected component - * returned by another iterator to the same collection of - * strongly connected components. - * - * ------------------------------------------------------------------------- */ -{ - iterator it(graph, visitor, dfs_ordering); - it.initialize(node_id); - return it; -} - -/* ========================================================================= */ -template -inline const typename SccCollection::iterator& -SccCollection::end() const -/* ---------------------------------------------------------------------------- - * - * Description: Returns an iterator pointing past the "end" of the collection - * of strongly connected components in `this->graph'. - * - * Arguments: None. - * - * Returns: A constant reference to `this->end_iterator'. - * - * ------------------------------------------------------------------------- */ -{ - return end_iterator; -} - - - -/****************************************************************************** - * - * Inline function definitions for template class SccCollection::iterator. - * - *****************************************************************************/ - -/* ========================================================================= */ -template -inline SccCollection::iterator::iterator - (const GraphType& g, NodeVisitor& node_visitor, - SccCollection::DfsOrdering& ordering) : - graph(g), visitor(node_visitor), dfs_ordering(ordering), initial_node(0), - dfs_number(0) -/* ---------------------------------------------------------------------------- - * - * Description: Constructor for class - * SccCollection::iterator. 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. - * node_visitor -- A reference to a object that implements - * callback functions to be invoked during the - * search for strongly connected components. - * ordering -- A reference to a mapping between node - * identifiers and their dfs numbers. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -template -inline SccCollection::iterator::~iterator() -/* ---------------------------------------------------------------------------- - * - * Description: Destructor for class - * SccCollection::iterator. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -template -inline bool SccCollection::iterator::operator== - (const SccCollection::iterator& it) const -/* ---------------------------------------------------------------------------- - * - * Description: Equality comparison between two SccCollection::iterators. Two - * iterators are equal iff they have the same initial state and - * they have visited the same amount of graph nodes. - * - * Argument: it -- A constant reference to an iterator. - * - * Returns: true iff the iterators are equal. - * - * ------------------------------------------------------------------------- */ -{ - return (it.initial_node == initial_node && it.dfs_number == dfs_number); -} - -/* ========================================================================= */ -template -inline bool SccCollection::iterator::operator!= - (const SccCollection::iterator& it) const -/* ---------------------------------------------------------------------------- - * - * Description: Inequality comparison between two SccCollection::iterators. - * Two iterators are not equal iff they have different initial - * states or if they have visited different numbers of graph - * nodes. - * - * Argument: it -- A constant reference to an iterator. - * - * Returns: true iff the iterators are not equal. - * - * ------------------------------------------------------------------------- */ -{ - return (it.initial_node != initial_node || it.dfs_number != dfs_number); -} - -/* ========================================================================= */ -template -inline const typename NodeVisitor::SccType& -SccCollection::iterator::operator*() const -/* ---------------------------------------------------------------------------- - * - * Description: Dereferencing operator for class - * SccCollection::iterator. Returns the - * data associated with the maximal strongly connected component - * currently pointed to by the iterator. - * - * Arguments: None. - * - * Returns: A constant reference to the data associated with the strongly - * connected component. - * - * ------------------------------------------------------------------------- */ -{ - return visitor(); -} - -/* ========================================================================= */ -template -inline const typename NodeVisitor::SccType* -SccCollection::iterator::operator->() const -/* ---------------------------------------------------------------------------- - * - * Description: Dereferencing operator for class - * SccCollection::iterator. Returns a - * pointer to the data associated with the maximal strongly - * connected component currently pointed to by the iterator. - * - * Arguments: None. - * - * Returns: A constant pointer to the data associated with the strongly - * connected component. - * - * ------------------------------------------------------------------------- */ -{ - return &visitor(); -} - -/* ========================================================================= */ -template -inline const typename NodeVisitor::SccType& -SccCollection::iterator::operator++() -/* ---------------------------------------------------------------------------- - * - * Description: Prefix increment operator for class - * SccCollection::iterator. Computes - * the next maximal strongly connected component of - * `this->graph' and then returns the data associated with it. - * - * Arguments: None. - * - * Returns: A reference to the data associated with the maximal strongly - * connected component found by incrementing the iterator. - * - * ------------------------------------------------------------------------- */ -{ - computeNextScc(); - return visitor(); -} - -/* ========================================================================= */ -template -inline const typename NodeVisitor::SccType -SccCollection::iterator::operator++(int) -/* ---------------------------------------------------------------------------- - * - * Description: Postfix increment operator for class - * SccCollection::iterator. Computes - * the next strongly connected component of - * `this->graph', but returns the data associated with the - * strongly connected component that the iterator pointed to - * _before_ this operation. - * - * Arguments: None (the `int' is only required to distinguish this operator - * from the prefix increment operator). - * - * Returns: The data associated with the maximal strongly connected - * component pointed to by the iterator before incrementing it. - * - * ------------------------------------------------------------------------- */ -{ - const typename NodeVisitor::SccType old_scc = visitor(); - computeNextScc(); - return old_scc; -} - - - -/****************************************************************************** - * - * Function definitions for template class - * SccCollection. - * - *****************************************************************************/ - -/* ========================================================================= */ -template -void SccCollection::iterator::getPath - (typename GraphType::Path& path) -/* ---------------------------------------------------------------------------- - * - * Description: Constructs a path from the initial state of the search for - * the strongly connected components to a node in the most - * recently found maximal strongly connected graph component. - * - * Argument: path -- A reference to a GraphType::Path object for storing - * the (node_id, edge) pairs in the path. - * - * Returns: Nothing. Assuming that `path' is a standard STL container - * type object with the `push_front' operation, `*path.begin()' - * will correspond to the first element on the path after the - * call. - * - * ------------------------------------------------------------------------- */ -{ - path.clear(); - - /* - * When this function is called after extracting a maximal strongly connected - * component from the graph, `node_stack.front()' corresponds to the root - * node of the component. This node will not be included in the path - * (that is, the edge component of `path.back()' will point to this node - * when exiting from this function). - */ - - typename deque::const_iterator n = node_stack.begin(); - if (n != node_stack.end()) - { - for (++n; n != node_stack.end(); ++n) - { - const typename GraphType::PathElement element(n->id, **n->edge); - path.push_front(element); - } - } -} - -/* ========================================================================= */ -template -void SccCollection::iterator::initialize - (const typename GraphType::size_type node_id) -/* ---------------------------------------------------------------------------- - * - * Description: Initializes a - * SccCollection::iterator for scanning - * the maximal strongly connected components of `this->graph'. - * - * Argument: node_id -- Identifier of a graph node from which to start - * the search for maximal strongly connected - * components. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - node_stack.clear(); - scc_stack.clear(); - - /* - * If `node_id' is an identifier of a node that has not yet been visited, - * make the iterator point to the next strongly connected component of - * `this->graph'. - */ - - if (!graph.empty() && dfs_ordering.find(node_id) == dfs_ordering.end()) - { - initial_node = node_id; - visitor.enter(node_id); - dfs_ordering[node_id] = dfs_number = 1; - const NodeStackElement element - = { node_id, graph[node_id].edges().begin(), 1 }; - node_stack.push_front(element); - current_node = &node_stack.front(); - computeNextScc(); - } -} - -/* ========================================================================= */ -template -void SccCollection::iterator::computeNextScc() -/* ---------------------------------------------------------------------------- - * - * Description: Makes an SccCollection::iterator - * point to the "next" maximal strongly connected component of - * `this->graph', using an algorithm based on the depth-first - * search algorithm of Tarjan - * [R. J. Tarjan. Depth-first search and linear graph - * algorithms. SIAM Journal on Computing 1(2):146--160, - * 1972] - * for computing the maximal strongly connected components of - * the graph. - * - * The implementation includes the optimization in the first - * improved algorithm found in - * [E. Nuutila and E. Soisalon-Soininen. On finding the - * strongly connected components in a directed graph. - * Information Processing Letters 49(1):9--14, 1994]. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - if (current_node->lowlink == 0) - { - /* Backtrack from the root of an SCC that was extracted from the graph */ - const typename GraphType::size_type child_node = current_node->id; - node_stack.pop_front(); - if (node_stack.empty()) - { - initial_node = dfs_number = 0; - return; - } - current_node = &node_stack.front(); - visitor.backtrack(current_node->id, **current_node->edge, child_node); - ++current_node->edge; /* prepare to process the next edge */ - } - -next_edge: - while (current_node->edge != graph[current_node->id].edges().end()) - { - const typename GraphType::size_type child_node - = (*current_node->edge)->targetNode(); - const typename DfsOrdering::const_iterator child_dfs_number_finder - = dfs_ordering.find(child_node); - - if (child_dfs_number_finder == dfs_ordering.end()) /* child not visited */ - { - ++dfs_number; - dfs_ordering[child_node] = dfs_number; - visitor.enter(child_node); - const NodeStackElement element - = { child_node, graph[child_node].edges().begin(), dfs_number }; - node_stack.push_front(element); - current_node = &node_stack.front(); - goto next_edge; - } - - visitor.touch(current_node->id, **current_node->edge, child_node); - if (child_dfs_number_finder->second != 0) /* child in the same SCC */ - { - if (child_dfs_number_finder->second < current_node->lowlink) - current_node->lowlink = child_dfs_number_finder->second; - visitor.addEdgeToComponent(**current_node->edge, current_node->lowlink); - } - - ++current_node->edge; - } - - visitor.addNodeToComponent(current_node->id, current_node->lowlink); - visitor.leave(current_node->id); - - if (dfs_ordering.find(current_node->id)->second != current_node->lowlink) - { - scc_stack.push_front(current_node->id); - - /* Backtrack from a node into a node in the same SCC */ - const typename GraphType::size_type child_node = current_node->id; - const typename GraphType::size_type child_lowlink = current_node->lowlink; - node_stack.pop_front(); - current_node = &node_stack.front(); - if (current_node->lowlink > child_lowlink) - current_node->lowlink = child_lowlink; - visitor.backtrack(current_node->id, **current_node->edge, child_node); - visitor.addEdgeToComponent(**current_node->edge, current_node->lowlink); - ++current_node->edge; /* prepare to process the next edge */ - goto next_edge; - } - - /* - * `current_node' is a root of a maximal strongly connected graph component. - * Extract the component from the graph. - */ - - visitor.beginComponent(current_node->lowlink, current_node->id); - visitor.insert(current_node->id); - dfs_ordering.find(current_node->id)->second = 0; - while (!scc_stack.empty()) - { - const typename GraphType::size_type node = scc_stack.front(); - typename GraphType::size_type& node_dfs_number - = dfs_ordering.find(node)->second; - if (node_dfs_number > current_node->lowlink) - { - scc_stack.pop_front(); - visitor.insert(node); - node_dfs_number = 0; - } - else - break; - } - visitor.endComponent(current_node->lowlink); - current_node->lowlink = 0; -} - -} - -#endif /* !SCCCOLLECTION_H */ diff --git a/lbtt/src/SccIterator.h b/lbtt/src/SccIterator.h deleted file mode 100644 index fceaceeea..000000000 --- a/lbtt/src/SccIterator.h +++ /dev/null @@ -1,752 +0,0 @@ -/* - * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 - * Heikki Tauriainen - * - * 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 -#include -#include -#include -#include -#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. - * - * 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::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::size_type s) - * [inserts an element into the - * container] - * - * If the container class is left unspecified, - * it defaults to - * set::size_type, - * less::size_type>, - * ALLOC(Graph::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::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 - * class, which does not restrict the set of - * nodes in any way. - * - *****************************************************************************/ - -template -class NullSccFilter; - -template::size_type, - less::size_type>, - ALLOC(typename Graph::size_type) >, - class Filter = NullSccFilter > -class SccIterator -{ -public: - SccIterator(const Graph& g); /* Constructor. */ - - /* default copy constructor */ - - ~SccIterator(); /* Destructor. */ - - /* default assignment operator */ - - bool operator== /* Equality test for */ - (const SccIterator& it) const; - - bool operator!= /* Inequality test for */ - (const SccIterator& it) const; - - bool operator< /* `Less than' relation */ - (const SccIterator& it) const; - - bool operator<= /* `Less than or equal' */ - (const SccIterator& it) const; - - bool operator> /* `Greater than' */ - (const SccIterator& it) const; - - bool operator>= /* `Greater than or */ - (const SccIterator& 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& graph; /* Reference to the graph - * with which the iterator - * is associated. - */ - - typename Graph::size_type /* Number of graph */ - dfs_number; /* nodes processed by - * the iterator. - */ - - vector::size_type, /* dfs_ordering[i] */ - ALLOC(typename Graph /* 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::size_type, /* lowlink[i] indicates */ - ALLOC(typename Graph /* 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::size_type, - typename EdgeContainer::const_iterator> - NodeStackElement; - - stack > - node_stack; - - typename Graph::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::size_type, /* Stack used for */ - deque /* collecting the nodes */ - ::size_type, /* in a strongly */ - ALLOC(typename Graph /* 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 NullSccFilter -{ -public: - bool operator()(const typename Graph::Node*) const; -}; - - - -/****************************************************************************** - * - * Inline function definitions for template class - * SccIterator. - * - *****************************************************************************/ - -/* ========================================================================= */ -template -inline SccIterator::SccIterator - (const Graph& g) : - graph(g), dfs_ordering(graph.size()), lowlink(graph.size()) -/* ---------------------------------------------------------------------------- - * - * Description: Constructor for class - * SccIterator. - * 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 object). - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - reset(); - computeNextScc(); -} - -/* ========================================================================= */ -template -inline SccIterator::~SccIterator() -/* ---------------------------------------------------------------------------- - * - * Description: Destructor for class - * SccIterator. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ -} - -/* ========================================================================= */ -template -inline bool SccIterator::operator== - (const SccIterator& 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 -inline bool SccIterator::operator!= - (const SccIterator& 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 -inline bool SccIterator::operator< - (const SccIterator& 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 -inline bool SccIterator::operator<= - (const SccIterator& 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 -inline bool SccIterator::operator> - (const SccIterator& 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 -inline bool SccIterator::operator>= - (const SccIterator& 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 -inline const SccContainer& -SccIterator::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 -inline const SccContainer* -SccIterator::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 -inline const SccContainer& -SccIterator::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 -inline const SccContainer -SccIterator::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 -inline bool SccIterator::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. - * - *****************************************************************************/ - -/* ========================================================================= */ -template -void SccIterator::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::size_type, - ALLOC(typename Graph::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 -void SccIterator::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::size_type, - ALLOC(typename Graph::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::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::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. - * - *****************************************************************************/ - -/* ========================================================================= */ -template -inline bool NullSccFilter::operator() - (const typename Graph::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::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 */ diff --git a/lbtt/src/SharedTestData.h b/lbtt/src/SharedTestData.h deleted file mode 100644 index 6820d310d..000000000 --- a/lbtt/src/SharedTestData.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 - * Heikki Tauriainen - * - * 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 -#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 test_results; /* Test results for each - * implementation. - */ - -extern vector final_statistics; /* Overall test - * statistics for each - * implementation. - */ -} - -#endif /* !SHAREDTESTDATA_H */ diff --git a/lbtt/src/SpinWrapper.cc b/lbtt/src/SpinWrapper.cc deleted file mode 100644 index f98d59792..000000000 --- a/lbtt/src/SpinWrapper.cc +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 - * Heikki Tauriainen - * - * 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 -#ifdef HAVE_SSTREAM -#include -#else -#include -#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, - AtomWriter, - UnaryOperatorWriter, - UnaryOperatorWriter, - UnaryOperatorWriter, - UnaryOperatorWriter, - BinaryOperatorInfixWriter, - BinaryOperatorInfixWriter, - BinaryOperatorInfixWriter, - BinaryOperatorInfixWriter, - WriterErrorReporter, - BinaryOperatorInfixWriter, - BinaryOperatorInfixWriter, - 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()); -} diff --git a/lbtt/src/SpinWrapper.h b/lbtt/src/SpinWrapper.h deleted file mode 100644 index 1e4a7ed52..000000000 --- a/lbtt/src/SpinWrapper.h +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 - * Heikki Tauriainen - * - * 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 -#include -#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 */ diff --git a/lbtt/src/SpotWrapper.cc b/lbtt/src/SpotWrapper.cc deleted file mode 100644 index abf881e75..000000000 --- a/lbtt/src/SpotWrapper.cc +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (C) 2003, 2004, 2010 - * Heikki Tauriainen - * - * Derived from SpinWrapper.cc by Alexandre Duret-Lutz . - * - * 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 -#ifdef HAVE_SSTREAM -#include -#else -#include -#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, - AtomWriter, - UnaryOperatorWriter, - UnaryOperatorWriter, - UnaryOperatorWriter, - UnaryOperatorWriter, - BinaryOperatorInfixWriter, - BinaryOperatorInfixWriter, - BinaryOperatorInfixWriter, - BinaryOperatorInfixWriter, - BinaryOperatorInfixWriter, - BinaryOperatorInfixWriter, - BinaryOperatorInfixWriter, - BinaryOperatorInfixWriter, - BinaryOperatorInfixWriter, - 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 */ -} diff --git a/lbtt/src/SpotWrapper.h b/lbtt/src/SpotWrapper.h deleted file mode 100644 index 206c5f601..000000000 --- a/lbtt/src/SpotWrapper.h +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (C) 2003, 2004 - * Heikki Tauriainen - * - * Derived from SpinWrapper.h by Alexandre Duret-Lutz . - * - * 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 -#include -#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 */ diff --git a/lbtt/src/StatDisplay.cc b/lbtt/src/StatDisplay.cc deleted file mode 100644 index 97c38eadf..000000000 --- a/lbtt/src/StatDisplay.cc +++ /dev/null @@ -1,1636 +0,0 @@ -/* - * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 - * Heikki Tauriainen - * - * 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 -#include -#include "DispUtil.h" -#include "Exception.h" -#include "IntervalList.h" -#include "SharedTestData.h" -#include "StatDisplay.h" -#include "StringUtil.h" -#include "TestRoundInfo.h" -#include "Graph.h" - -namespace StatDisplay -{ - -using namespace ::DispUtil; -using namespace ::SharedTestData; -using namespace ::StringUtil; - -/* ========================================================================= */ -void printStatTableHeader(ostream& stream, int indent) -/* ---------------------------------------------------------------------------- - * - * Description: Displays a table header for test statistics (used in - * verbosity mode 2). - * - * Arguments: stream -- A reference to the output stream to which the - * header should be written. - * indent -- Number of spaces to leave on the left of the - * output. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - Exceptional_ostream estream(&stream, ios::failbit | ios::badbit); - - int num_dashes = 39; - estream << string(indent, ' ') + " # F Elapsed Büchi Büchi Acc."; - if (configuration.global_options.do_cons_test - || configuration.global_options.do_comp_test) - { - num_dashes += 31; - estream << " Product Product Acc."; - if (configuration.global_options.do_cons_test) - { - num_dashes += 3; - estream << " CC"; - } - } - estream << '\n' + string(indent + 10, ' ') - + "time states trans. sets"; - if (configuration.global_options.do_cons_test - || configuration.global_options.do_comp_test) - estream << " states trans. cycles"; - estream << "\n" + string(indent, ' ') + string(num_dashes, '-') + '\n'; - estream.flush(); -} - - -/* ========================================================================= */ -void printBuchiAutomatonStats - (ostream& stream, int indent, - vector::size_type algorithm, - int result_id) -/* ---------------------------------------------------------------------------- - * - * Description: Displays information about a Büchi automaton, extracting the - * information from a TestStatistics structure stored in the - * UserInterface object. - * - * Arguments: stream -- A reference to the output stream to which the - * information should be written. - * indent -- Number of spaces to leave on the left of the - * output in verbosity modes >= 3. - * algorithm -- Identifier of the algorithm used for - * generating the automaton. - * result_id -- Selects between the automata constructed from - * a formula and its negation. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - Exceptional_ostream estream(&stream, ios::failbit | ios::badbit); - - const AutomatonStats& automaton_stats = - test_results[algorithm].automaton_stats[result_id]; - - if (configuration.global_options.verbosity <= 2) - { - if (!automaton_stats.buchiAutomatonComputed()) - estream << " N/A N/A N/A N/A N/A"; - else - { - if (automaton_stats.buchi_generation_time >= 0.0) - { - changeStreamFormatting(stream, 9, 2, ios::fixed | ios::right); - estream << automaton_stats.buchi_generation_time; - restoreStreamFormatting(stream); - } - else - estream << " N/A"; - estream << ' '; - changeStreamFormatting(stream, 9, 0, ios::right); - estream << automaton_stats.number_of_buchi_states; - restoreStreamFormatting(stream); - estream << ' '; - changeStreamFormatting(stream, 9, 0, ios::right); - estream << automaton_stats.number_of_buchi_transitions; - restoreStreamFormatting(stream); - estream << ' '; - changeStreamFormatting(stream, 4, 0, ios::right); - estream << automaton_stats.number_of_acceptance_sets; - restoreStreamFormatting(stream); - changeStreamFormatting(stream, 9, 0, ios::right); - estream << automaton_stats.nondeterminism_index; - restoreStreamFormatting(stream); - } - estream << ' '; - } - else - { - estream << string(indent, ' '); - - if (!automaton_stats.buchiAutomatonComputed()) - estream << "not computed"; - else - { - estream << "number of states:" + string(6, ' ') - + toString(automaton_stats.number_of_buchi_states) - + '\n' + string(indent, ' ') + "number of transitions: " - + toString(automaton_stats.number_of_buchi_transitions) - + '\n' + string(indent, ' ') + "acceptance sets:" - + string(7, ' ') - + toString(automaton_stats.number_of_acceptance_sets) - + '\n' + string(indent, ' ') + "is deterministic:" - + string(6, ' ') - + (automaton_stats.is_deterministic?"Yes":"No") - + '\n' + string(indent, ' ') + "nondeterminism index: " - + toString(automaton_stats.nondeterminism_index) - + '\n' + string(indent, ' ') + "computation time:" - + string(6, ' '); - - if (automaton_stats.buchi_generation_time != -1.0) - { - changeStreamFormatting(stream, 9, 2, ios::fixed | ios::left); - estream << automaton_stats.buchi_generation_time; - restoreStreamFormatting(stream); - - estream << " seconds (user time)"; - } - else - estream << "N/A"; - } - - estream << '\n'; - } - - estream.flush(); -} - -/* ========================================================================= */ -void printProductAutomatonStats - (ostream& stream, int indent, - vector::size_type algorithm, - int result_id) -/* ---------------------------------------------------------------------------- - * - * Description: Displays information about a product automaton, extracting - * the information from a TestStatistics structure stored in the - * UserInterface object. - * - * Arguments: stream -- A reference to the output stream to which the - * information should be written. - * indent -- Number of spaces to leave on the left of the - * output in verbosity modes >= 3. - * algorithm -- Identifier of the algorithm used for - * generating the product automaton. - * result_id -- Selects between the automata constructed from - * a formula and its negation. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - Exceptional_ostream estream(&stream, ios::failbit | ios::badbit); - - const AutomatonStats& automaton_stats = - test_results[algorithm].automaton_stats[result_id]; - - if (configuration.global_options.verbosity <= 2) - { - if (!automaton_stats.productAutomatonComputed()) - estream << " N/A N/A"; - else - { - changeStreamFormatting(stream, 11, 0, ios::right); - estream << automaton_stats.number_of_product_states; - restoreStreamFormatting(stream); - estream << ' '; - changeStreamFormatting(stream, 11, 0, ios::right); - estream << automaton_stats.number_of_product_transitions; - restoreStreamFormatting(stream); - } - estream << ' '; - } - else - { - estream << string(indent, ' '); - - if (!automaton_stats.productAutomatonComputed()) - estream << "not computed"; - else - { - estream << "number of states:" + string(6, ' '); - - changeStreamFormatting(stream, 9, 0, ios::left); - estream << automaton_stats.number_of_product_states; - restoreStreamFormatting(stream); - - estream << " ["; - - if (automaton_stats.number_of_product_states != 0) - { - changeStreamFormatting(stream, 0, 2, ios::fixed); - estream << static_cast - (automaton_stats.number_of_product_states) - / static_cast - (automaton_stats.number_of_buchi_states) - / static_cast(round_info.statespace->size()) - * 100.0; - restoreStreamFormatting(stream); - - estream << "% of worst case (" - << automaton_stats.number_of_buchi_states - * round_info.statespace->size() - << ')'; - } - else - estream << "empty automaton"; - - estream << "]\n" + string(indent, ' ') + "number of transitions: " - + toString(automaton_stats.number_of_product_transitions); - } - - estream << '\n'; - } - - estream.flush(); -} - -/* ========================================================================= */ -void printAcceptanceCycleStats - (ostream& stream, int indent, - vector::size_type algorithm, - int result_id) -/* ---------------------------------------------------------------------------- - * - * Description: Displays information about the number of system states from - * which begins an execution accepted by a Büchi automaton. The - * information is extracted from a TestStatistics structure - * stored in the UserInterface object. - * - * Arguments: stream -- A reference to the output stream to which the - * information should be written. - * indent -- Number of spaces to leave on the left of the - * output in verbosity mode >= 3. - * algorithm -- Identifier of the algorithm used for - * computing the Büchi automaton whose accepting - * cycles are to be considered. - * result_id -- Selects between the result computed for a - * formula and its negation. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - Exceptional_ostream estream(&stream, ios::failbit | ios::badbit); - - const AutomatonStats& automaton_stats = - test_results[algorithm].automaton_stats[result_id]; - - if (configuration.global_options.verbosity <= 2) - { - if (!automaton_stats.emptiness_check_performed) - estream << " N/A"; - else - { - changeStreamFormatting(stream, 6, 0, ios::right); - estream << automaton_stats.emptiness_check_result.count(); - restoreStreamFormatting(stream); - } - estream << ' '; - } - else - { - estream << string(indent, ' '); - - if (!automaton_stats.emptiness_check_performed) - estream << "not computed"; - else if (configuration.global_options.product_mode == Configuration::LOCAL) - { - estream << string("cycle "); - - if (automaton_stats.emptiness_check_result[0]) - estream << "reachable "; - else - estream << "not reachable"; - - estream << " (from the initial state)"; - } - else - { - estream << "cycle reachable from "; - - changeStreamFormatting(stream, 9, 0, ios::left); - estream << automaton_stats.emptiness_check_result.count(); - restoreStreamFormatting(stream); - - estream << " states\n" + string(indent, ' ') - + "not reachable from "; - - changeStreamFormatting(stream, 9, 0, ios::left); - estream << (round_info.real_emptiness_check_size - - automaton_stats.emptiness_check_result.count()); - restoreStreamFormatting(stream); - - estream << " states"; - } - - estream << '\n'; - } - - estream.flush(); -} - -/* ========================================================================= */ -void printConsistencyCheckStats - (ostream& stream, int indent, - vector::size_type algorithm) -/* ---------------------------------------------------------------------------- - * - * Description: Displays information about the consistency check result for - * a given algorithm, extracting the information from a - * TestStatistics structure stored in the UserInterface object. - * - * Arguments: stream -- A reference to an output stream to which the - * information should be written. - * indent -- Number of spaces to leave on the left of the - * output in verbosity mode >= 3. - * algorithm -- Identifier of the algorithm whose consistency - * check result should be displayed. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - Exceptional_ostream estream(&stream, ios::failbit | ios::badbit); - const AlgorithmTestResults& test_result = test_results[algorithm]; - - if (configuration.global_options.verbosity <= 2) - { - switch (test_result.consistency_check_result) - { - case -1 : - estream << "NA"; - break; - - case 0 : - estream << " F"; - break; - - default: - estream << " P"; - break; - } - } - else - { - estream << string(indent, ' '); - - if (test_result.consistency_check_result == -1) - estream << "not performed"; - else - { - estream << "result:" + string(18, ' '); - - if (test_result.consistency_check_result == 0) - { - estream << "failed [" - + toString(test_result.failed_consistency_check_comparisons) - + " ("; - - changeStreamFormatting(stream, 0, 2, ios::fixed); - estream << ((test_result.consistency_check_comparisons == 0) - ? 0.0 - : static_cast - (test_result.failed_consistency_check_comparisons) - / test_result.consistency_check_comparisons * 100.0); - restoreStreamFormatting(stream); - - estream << "%) of " - + toString(test_result.consistency_check_comparisons) - + " test cases]"; - } - else - estream << "passed"; - } - - estream << '\n'; - } - - estream.flush(); -} - -/* ========================================================================= */ -void printCrossComparisonStats - (ostream& stream, int indent, const IntervalList& algorithms) -/* ---------------------------------------------------------------------------- - * - * Description: Displays information about the model checking result cross- - * comparison check, extracting the information from a vector of - * TestStatistics structures stored in the UserInterface object. - * - * Arguments: stream -- A reference to an output stream to which the - * information should be written. - * indent -- Number of spaces to leave on the left of the - * output. - * algorithms -- A reference to a constant IntervalList - * storing the numeric identifiers of the - * algorithms for which the statistics should - * be shown. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - Exceptional_ostream estream(&stream, ios::failbit | ios::badbit); - bool no_errors_to_report = true, nothing_to_report = true; - - const AutomatonStats* alg_1_pos_results; - const AutomatonStats* alg_1_neg_results; - - for (IntervalList::const_iterator alg_1 = algorithms.begin(); - alg_1 != algorithms.end(); - ++alg_1) - { - alg_1_pos_results = &test_results[*alg_1].automaton_stats[0]; - alg_1_neg_results = &test_results[*alg_1].automaton_stats[1]; - - for (vector::size_type alg_2 = 0; - alg_2 < round_info.number_of_translators; - alg_2++) - { - if (*alg_1 != alg_2 - && (alg_2 > *alg_1 || !algorithms.covers(alg_2)) - && configuration.algorithms[*alg_1].enabled - && configuration.algorithms[alg_2].enabled) - { - bool pos_test, neg_test; - - if (nothing_to_report) - { - nothing_to_report = false; - estream << string(indent, ' ') + "result:"; - } - - for (int counter = 0; counter < 2; counter++) - { - if (counter == 0) - { - pos_test = !alg_1_pos_results->crossComparisonPerformed(alg_2); - neg_test = !alg_1_neg_results->crossComparisonPerformed(alg_2); - } - else - { - pos_test = (alg_1_pos_results->cross_comparison_stats[alg_2]. - second > 0); - neg_test = (alg_1_neg_results->cross_comparison_stats[alg_2]. - second > 0); - } - - if (pos_test || neg_test) - { - estream << '\n' + string(indent + 2, ' '); - no_errors_to_report = false; - - estream << string(counter == 0 ? "N/A " : "failed") + " ("; - - if (pos_test) - estream << string("+") + (neg_test ? "-)" : ") "); - else - estream << "-) "; - - estream << " " + configuration.algorithmString(*alg_1) + ", " - + configuration.algorithmString(alg_2); - } - } - } - } - } - - if (nothing_to_report) - estream << string(indent, ' ') + "not performed"; - else if (no_errors_to_report) - estream << string(20, ' ') + "no failures detected"; - estream << "\n\n"; - estream.flush(); -} - -/* ========================================================================= */ -void printBuchiIntersectionCheckStats - (ostream& stream, int indent, const IntervalList& algorithms) -/* ---------------------------------------------------------------------------- - * - * Description: Displays information about the Büchi automaton intersection - * emptiness check results, extracting the information from a - * TestStatistics structure stored in the UserInterface object. - * - * Arguments: stream -- A reference to an output stream to which the - * information should be written. - * indent -- Number of spaces to leave on the left of the - * output. - * algorithms -- A reference to a constant IntervalList - * storing the numeric identifiers of the - * algorithms for which the statistics should - * be shown. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - Exceptional_ostream estream(&stream, ios::failbit | ios::badbit); - bool no_errors_to_report = true, nothing_to_report = true; - - const AutomatonStats* alg_1_pos_results; - const AutomatonStats* alg_1_neg_results; - - for (IntervalList::const_iterator alg_1 = algorithms.begin(); - alg_1 != algorithms.end(); - ++alg_1) - { - alg_1_pos_results = &test_results[*alg_1].automaton_stats[0]; - alg_1_neg_results = &test_results[*alg_1].automaton_stats[1]; - - for (vector::size_type alg_2 = 0; - alg_2 < round_info.number_of_translators; - alg_2++) - { - if (configuration.algorithms[*alg_1].enabled - && configuration.algorithms[alg_2].enabled - && (alg_2 >= *alg_1 || !algorithms.covers(alg_2)) - && !configuration.isInternalAlgorithm(*alg_1) - && !configuration.isInternalAlgorithm(alg_2)) - { - bool pos_test, neg_test; - - if (nothing_to_report) - { - nothing_to_report = false; - estream << string(indent, ' ') + "result:"; - } - - for (int counter = -1; counter < 1; counter++) - { - pos_test = (alg_1_pos_results->buchi_intersection_check_stats[alg_2] - == counter); - neg_test = (alg_1_neg_results->buchi_intersection_check_stats[alg_2] - == counter); - - if (pos_test || neg_test) - { - estream << '\n' + string(indent + 2, ' '); - no_errors_to_report = false; - - estream << string(counter == -1 ? "N/A " : "failed") + ' '; - - if (*alg_1 != alg_2) - { - estream << '('; - if (pos_test) - estream << string("+") + (neg_test ? "-)" : ") "); - else - estream << "-) "; - } - else - estream << " "; - - estream << ' ' + configuration.algorithmString(*alg_1); - - if (*alg_1 != alg_2) - { - estream << ", ("; - if (pos_test) - estream << string("-") + (neg_test ? "+" : ""); - else - estream << '+'; - - estream << ") " + configuration.algorithmString(alg_2); - } - } - } - } - } - } - - if (nothing_to_report) - estream << string(indent, ' ') + "not performed"; - else if (no_errors_to_report) - estream << string(20, ' ') + "no failures detected"; - estream << "\n"; - estream.flush(); -} - -/* ========================================================================= */ -void printAllStats - (ostream& stream, int indent, - vector::size_type algorithm) -/* ---------------------------------------------------------------------------- - * - * Description: Displays all test information (Büchi automaton and product - * automaton statistics, acceptance cycle information, - * consistency check result) for an algorithm. - * - * Arguments: stream -- A reference to an output stream to which the - * information should be written. - * indent -- Number of spaces to leave on the left of the - * output. - * algorithm -- Identifier of an algorithm. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - Exceptional_ostream estream(&stream, ios::failbit | ios::badbit); - - if (configuration.global_options.verbosity >= 3) - estream << string(indent, ' ') + configuration.algorithmString(algorithm) - + '\n'; - - for (int counter = 0; counter < 2; counter++) - { - if (configuration.global_options.verbosity <= 2) - { - if (counter == 1) - estream << '\n'; - estream << string(indent, ' '); - changeStreamFormatting(stream, 2, 0, ios::right); - estream << algorithm << ' '; - restoreStreamFormatting(stream); - estream << (counter == 0 ? '+' : '-') << ' '; - } - else - { - estream << string(indent + 2, ' ') - + (counter == 0 ? "Positive" : "Negated") + " formula:\n" - + string(indent + 4, ' ') + "Büchi automaton:\n"; - } - printBuchiAutomatonStats(stream, indent + 6, algorithm, counter); - - if (configuration.global_options.do_comp_test - || configuration.global_options.do_cons_test) - { - if (configuration.global_options.verbosity >= 3) - estream << string(indent + 4, ' ') + "Product automaton:\n"; - printProductAutomatonStats(stream, indent + 6, algorithm, counter); - if (configuration.global_options.verbosity >= 3) - estream << string(indent + 4, ' ') + "Accepting cycles:\n"; - printAcceptanceCycleStats(stream, indent + 6, algorithm, counter); - } - } - - if (configuration.global_options.do_cons_test) - { - if (configuration.global_options.verbosity >= 3) - estream << string(indent + 2, ' ') + "Result consistency check:\n"; - printConsistencyCheckStats(stream, indent + 4, algorithm); - } - - estream << '\n'; - estream.flush(); -} - -/* ========================================================================= */ -void printCollectiveCrossComparisonStats - (ostream& stream, - vector::size_type algorithm_y, - vector::size_type algorithm_x, - int data_type) -/* ---------------------------------------------------------------------------- - * - * Description: Called by printCollectiveStats in order to fill a single cell - * of the result cross-comparison table. - * - * Arguments: stream -- A reference to an output - * stream. - * algorithm_x, algorithm_y -- Identifiers of the algorithms - * whose cross-comparison results - * should be displayed. - * data_type -- Determines the type of data to - * be displayed in the cell: - * 0 -- Model checking result - * cross-comparison - * statistics. - * 1 -- Model checking result - * cross-comparison - * statistics (initial - * state only). - * 2 -- Büchi automaton - * intersection check - * statistics. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - Exceptional_ostream estream(&stream, ios::failbit | ios::badbit); - - estream << ' '; - - if (algorithm_x == algorithm_y && data_type != 2) - estream << string(21, ' '); - else - { - unsigned long int num_comparisons, num_mismatches; - const TestStatistics& stats = final_statistics[algorithm_y]; - - switch (data_type) - { - case 0 : - num_comparisons = stats.cross_comparisons_performed[algorithm_x]; - num_mismatches = stats.cross_comparison_mismatches[algorithm_x]; - break; - - case 1 : - num_comparisons = stats.cross_comparisons_performed[algorithm_x]; - num_mismatches - = stats.initial_cross_comparison_mismatches[algorithm_x]; - break; - - default : - if (configuration.isInternalAlgorithm(algorithm_x) - || configuration.isInternalAlgorithm(algorithm_y)) - { - estream << string(21, ' '); - return; - } - - num_comparisons - = stats.buchi_intersection_checks_performed[algorithm_x]; - num_mismatches = stats.buchi_intersection_check_failures[algorithm_x]; - break; - } - - if (num_comparisons > 0) - { - changeStreamFormatting(stream, 5, 0, ios::right); - estream << num_mismatches; - restoreStreamFormatting(stream); - - estream << '/'; - - changeStreamFormatting(stream, 5, 0, ios::left); - estream << num_comparisons; - restoreStreamFormatting(stream); - - estream << " ("; - - double percentage = static_cast(num_mismatches) - / static_cast(num_comparisons) - * 100.0; - - changeStreamFormatting(stream, 0, 2, ios::fixed); - estream << percentage; - restoreStreamFormatting(stream); - - estream << "%)"; - - if (percentage < 100.0) - estream << ' '; - if (percentage < 10.0) - estream << ' '; - } - else - estream << " N/A" + string(14, ' '); - } -} - -/* ========================================================================= */ -void printCollectiveStats(ostream& stream, int indent) -/* ---------------------------------------------------------------------------- - * - * Description: Displays average information about a series of tests for each - * tested algorithm: - * - average sizes of the Büchi and product automata - * - number of failed attempts to generate a Büchi automaton - * - number of failed consistency checks - * - number of failed path checks - * - cross-comparison mismatches - * - Büchi automata intersection emptiness check failures - * - * Arguments: stream -- A reference to an output stream. - * indent -- Number of spaces to leave on the left of the - * output. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - Exceptional_ostream estream(&stream, ios::failbit | ios::badbit); - const string ind(indent, ' '); - - /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * Display state space statistics. - */ - - estream << '\n' + ind + "Statistics after round " - + toString(round_info.current_round) + '\n' - + ind + string(toString(round_info.current_round).length() + 23, - '*') - + "\n\n\n"; - - if (configuration.global_options.do_comp_test - || configuration.global_options.do_cons_test) - { - estream << ind + " State space statistics\n" - + ind + " " + string(22, '=') + "\n\n" - + ind + " " + toString(round_info.num_generated_statespaces) - + " state spaces generated\n" - + ind + " " + toString(round_info.total_statespace_states) - + " states generated"; - - if (round_info.num_generated_statespaces > 0) - { - estream << " (" - + toString(static_cast - (round_info.total_statespace_states) - / static_cast - (round_info.num_generated_statespaces), - 2) - + " states per state space)"; - } - - estream << '\n' + ind + " " - + toString(round_info.total_statespace_transitions) - + " transitions generated"; - - if (round_info.num_generated_statespaces > 0) - { - estream << " (" - + toString(static_cast - (round_info.total_statespace_transitions) - / static_cast - (round_info.num_generated_statespaces), - 2) - + " transitions per state space)"; - } - - estream << "\n\n\n"; - } - - /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * Display LTL formula statistics. - */ - - estream << ind + " LTL formula statistics\n" - + ind + " " + string(22, '=') + "\n\n" - + ind + " " + toString(round_info.num_processed_formulae) - + " LTL formulas " - + (!configuration.global_options.formula_input_filename.empty() - ? "process" - : "generat") - + "ed\n"; - - if (round_info.num_processed_formulae > 0 - && configuration.global_options.formula_input_filename.empty()) - { - const map& - proposition_statistics - = configuration.formula_options.formula_generator. - propositionStatistics(); - - const map - symbol_statistics - = configuration.formula_options.formula_generator.symbolStatistics(); - - estream << '\n' + ind + " Atomic symbol distribution:\n"; - string symbol_name_string; - string symbol_number_string; - string symbol_distribution_string; - int number_of_symbols_printed = 0; - - if (symbol_statistics.find(::Ltl::LTL_TRUE) != symbol_statistics.end()) - { - const unsigned long int num - = symbol_statistics.find(::Ltl::LTL_TRUE)->second; - symbol_name_string += "true "; - const string number_string = toString(num); - symbol_number_string += number_string - + string(12 - number_string.length(), ' '); - const string distribution_string - = toString(static_cast(num) - / static_cast(round_info.num_processed_formulae), - 3); - symbol_distribution_string += distribution_string - + string(12 - distribution_string.length(), - ' '); - number_of_symbols_printed++; - } - - if (symbol_statistics.find(::Ltl::LTL_FALSE) != symbol_statistics.end()) - { - const unsigned long int num - = symbol_statistics.find(::Ltl::LTL_FALSE)->second; - symbol_name_string += "false "; - const string number_string = toString(num); - symbol_number_string += number_string - + string(12 - number_string.length(), ' '); - const string distribution_string - = toString(static_cast(num) - / static_cast(round_info.num_processed_formulae), - 3); - symbol_distribution_string += distribution_string - + string(12 - distribution_string.length(), - ' '); - number_of_symbols_printed++; - } - - for (map::const_iterator - proposition = proposition_statistics.begin(); - proposition != proposition_statistics.end(); - ++proposition) - { - const string name_string = "p" + toString(proposition->first); - symbol_name_string += name_string; - const string number_string = toString(proposition->second); - symbol_number_string += number_string; - const string distribution_string - = toString(static_cast(proposition->second) - / static_cast(round_info.num_processed_formulae), - 3); - symbol_distribution_string += distribution_string; - - number_of_symbols_printed++; - - if (number_of_symbols_printed % 5 == 0) - { - estream << ind + " symbol " + symbol_name_string + '\n' - + ind + " # " + symbol_number_string + '\n' - + ind + " #/formula " + symbol_distribution_string - + "\n\n"; - symbol_name_string = symbol_number_string = symbol_distribution_string - = ""; - } - else - { - symbol_name_string += string(12 - name_string.length(), ' '); - symbol_number_string += string(12 - number_string.length(), ' '); - symbol_distribution_string += string(12 - distribution_string.length(), - ' '); - } - } - - if (number_of_symbols_printed % 5 != 0) - { - estream << ind + " symbol " + symbol_name_string + '\n' - + ind + " # " + symbol_number_string + '\n' - + ind + " #/formula " + symbol_distribution_string - + "\n\n"; - } - - estream << ind + " Operator distribution:\n"; - symbol_name_string = symbol_number_string = symbol_distribution_string - = ""; - number_of_symbols_printed = 0; - - for (map::const_iterator - op = symbol_statistics.begin(); - op != symbol_statistics.end(); - ++op) - { - if (op->first == ::Ltl::LTL_ATOM || op->first == ::Ltl::LTL_TRUE - || op->first == ::Ltl::LTL_FALSE) - continue; - - const string name_string = ::Ltl::infixSymbol(op->first); - symbol_name_string += name_string; - const string number_string = toString(op->second); - symbol_number_string += number_string; - const string distribution_string - = toString(static_cast(op->second) - / static_cast(round_info.num_processed_formulae), - 3); - symbol_distribution_string += distribution_string; - - number_of_symbols_printed++; - - if (number_of_symbols_printed % 5 == 0) - { - if (number_of_symbols_printed > 5) - estream << '\n'; - estream << ind + " operator " + symbol_name_string + '\n' - + ind + " # " + symbol_number_string + '\n' - + ind + " #/formula " + symbol_distribution_string - + '\n'; - symbol_name_string = symbol_number_string = symbol_distribution_string - = ""; - } - else - { - symbol_name_string += string(12 - name_string.length(), ' '); - symbol_number_string += string(12 - number_string.length(), ' '); - symbol_distribution_string += string(12 - distribution_string.length(), - ' '); - } - } - - if (number_of_symbols_printed % 5 != 0) - { - if (number_of_symbols_printed > 5) - estream << '\n'; - estream << ind + " operator " + symbol_name_string + '\n' - + ind + " # " + symbol_number_string + '\n' - + ind + " #/formula " + symbol_distribution_string - + '\n'; - } - } - - /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * Display the following information for each algorithm: - * 0. Automata statistics. - * 1. Number of failures to compute Büchi automata. - * 2. Number of model checking result consistency check failures. - */ - - string algorithm_name; - - for (int i = 0; i <= 2; i++) - { - estream << '\n' + string(2 + indent, ' '); - - switch (i) - { - case 1 : - estream << "Failures to compute Büchi automaton\n" - + string(2 + indent, ' ') + string(35, '=') + '\n'; - break; - case 2 : - if (!configuration.global_options.do_cons_test) - continue; - - estream << "Model checking result consistency check failures\n" - + string(2 + indent, ' ') + string(48, '=') + '\n'; - break; - default : - break; - } - - for (unsigned long int algorithm = 0; - algorithm < round_info.number_of_translators; - ++algorithm) - { - if (configuration.isInternalAlgorithm(algorithm)) - continue; - - estream << '\n' + string((i > 0 ? 4 : 2) + indent, ' ') - + configuration.algorithms[algorithm].name + '\n'; - - switch (i) - { - /* - * Display a table of automaton statistics. - */ - - case 0 : - { - unsigned long int failures_to_compute_automaton; - unsigned long int automaton_count; - unsigned long int number_of_successful_instances; - BIGUINT total_number_of_states; - BIGUINT total_number_of_transitions; - BIGUINT total_nondeterminism_index; - int total_deterministic_count; - - const TestStatistics& stats = final_statistics[algorithm]; - - estream << string(2 + indent, ' ') - + string(configuration.algorithms[algorithm].name. - length(), '='); - - for (int k = 0; k < 2; k++) - { - if (k == 1 && !configuration.global_options.do_comp_test - && !configuration.global_options.do_cons_test) - continue; - - estream << "\n\n" + string(8 + indent, ' ') - + (k == 0 ? "BÜCHI " : "PRODUCT") + string(7, ' ') - + "| Number of | Number of |" - " Number of |\n" - + string(8 + indent, ' ') - + "AUTOMATA" + string(6, ' ') - + "| automata | states |" - " transitions |\n" - + string(7 + indent, ' ') + string(15, '-') + '+'; - - for (int j = 0; j < 3; j++) - estream << string(17, '-') + '+'; - - estream << '\n'; - - for (int j = 0; j < 3; j++) - { - estream << string(8 + indent, ' '); - switch (j) - { - case 0 : estream << "Pos. formulae"; break; - case 1 : estream << "Neg. formulae"; break; - default : estream << "All formulae "; break; - } - - estream << " | "; - - if (j < 2) - { - if (k == 0) - { - failures_to_compute_automaton - = stats.failures_to_compute_buchi_automaton[j]; - automaton_count = stats.buchi_automaton_count[j]; - total_number_of_states - = stats.total_number_of_buchi_states[j]; - total_number_of_transitions - = stats.total_number_of_buchi_transitions[j]; - } - else - { - failures_to_compute_automaton - = stats.failures_to_compute_product_automaton[j]; - automaton_count = stats.product_automaton_count[j]; - total_number_of_states - = stats.total_number_of_product_states[j]; - total_number_of_transitions - = stats.total_number_of_product_transitions[j]; - } - } - else - { - if (k == 0) - { - failures_to_compute_automaton = - stats.failures_to_compute_buchi_automaton[0] - + stats.failures_to_compute_buchi_automaton[1]; - automaton_count = stats.buchi_automaton_count[0] - + stats.buchi_automaton_count[1]; - total_number_of_states - = stats.total_number_of_buchi_states[0] - + stats.total_number_of_buchi_states[1]; - total_number_of_transitions - = stats.total_number_of_buchi_transitions[0] - + stats.total_number_of_buchi_transitions[1]; - } - else - { - failures_to_compute_automaton = - stats.failures_to_compute_product_automaton[0] - + stats.failures_to_compute_product_automaton[1]; - automaton_count = stats.product_automaton_count[0] - + stats.product_automaton_count[1]; - total_number_of_states - = stats.total_number_of_product_states[0] - + stats.total_number_of_product_states[1]; - total_number_of_transitions - = stats.total_number_of_product_transitions[0] - + stats.total_number_of_product_transitions[1]; - } - } - - number_of_successful_instances = - automaton_count - failures_to_compute_automaton; - - for (int z = 0; z < 2; z++) - { - if (z == 0) - { - changeStreamFormatting(stream, 15, 2, ios::right); - estream << number_of_successful_instances; - restoreStreamFormatting(stream); - } - else - estream << string(indent + 15, ' ') + "(avg.) |" - + string(16, ' '); - - estream << " | "; - - if (number_of_successful_instances == 0) - estream << string(15, ' '); - else - { - changeStreamFormatting(stream, 15, 2, - ios::fixed | ios::right); - if (z == 0) - estream << total_number_of_states; - else - estream << total_number_of_states - / static_cast - (number_of_successful_instances); - restoreStreamFormatting(stream); - } - - estream << " | "; - - if (number_of_successful_instances == 0) - estream << string(15, ' '); - else - { - changeStreamFormatting(stream, 15, 2, - ios::fixed | ios::right); - if (z == 0) - estream << total_number_of_transitions; - else - estream << total_number_of_transitions - / static_cast - (number_of_successful_instances); - restoreStreamFormatting(stream); - } - - estream << " |\n"; - } - } - - if (k == 0) - { - BIGUINT total_number_of_acceptance_sets; - double buchi_generation_time; - - estream << '\n' + string(22 + indent, ' ') - + "| Number of | Time consumed |" - + " Number of | Nondeterminism |\n" - + string(22 + indent, ' ') - + "| acceptance sets | (seconds) |" - + " determ. aut | index |\n" - + string(7 + indent, ' ') + string(15, '-') + '+'; - - for (int j = 0; j < 3; j++) - estream << string(17, '-') + '+'; - - estream << string(16, '-') + '+'; - - for (int j = 0; j < 3; j++) - { - estream << '\n' + string(8 + indent, ' '); - switch (j) - { - case 0 : estream << "Pos. formulae"; break; - case 1 : estream << "Neg. formulae"; break; - default : estream << "All formulae "; break; - } - - estream << " | "; - - if (j < 2) - { - failures_to_compute_automaton = - stats.failures_to_compute_buchi_automaton[j]; - - automaton_count = stats.buchi_automaton_count[j]; - - buchi_generation_time = stats.total_buchi_generation_time[j]; - total_number_of_acceptance_sets - = stats.total_number_of_acceptance_sets[j]; - total_deterministic_count - = stats.total_deterministic_count[j]; - total_nondeterminism_index - = stats.total_nondeterminism_index[j]; - } - else - { - failures_to_compute_automaton = - stats.failures_to_compute_buchi_automaton[0] - + stats.failures_to_compute_buchi_automaton[1]; - - automaton_count = stats.buchi_automaton_count[0] - + stats.buchi_automaton_count[1]; - - buchi_generation_time = - (stats.total_buchi_generation_time[0] >= 0.0 - && stats.total_buchi_generation_time[1] >= 0.0 - ? stats.total_buchi_generation_time[0] - + stats.total_buchi_generation_time[1] - : -1.0); - total_number_of_acceptance_sets - = stats.total_number_of_acceptance_sets[0] - + stats.total_number_of_acceptance_sets[1]; - total_deterministic_count - = stats.total_deterministic_count[0] - + stats.total_deterministic_count[1]; - total_nondeterminism_index - = stats.total_nondeterminism_index[0] - + stats.total_nondeterminism_index[1]; - } - - number_of_successful_instances = - automaton_count - failures_to_compute_automaton; - - for (int z = 0; z < 2; z++) - { - if (number_of_successful_instances == 0) - estream << string(15, ' '); - else - { - changeStreamFormatting(stream, 15, 2, - ios::fixed | ios::right); - if (z == 0) - estream << total_number_of_acceptance_sets; - else - estream << total_number_of_acceptance_sets - / static_cast - (number_of_successful_instances); - restoreStreamFormatting(stream); - } - - estream << " | "; - - if (number_of_successful_instances == 0 - || buchi_generation_time < 0.0) - estream << string(15, ' '); - else - { - changeStreamFormatting(stream, 15, 2, - ios::fixed | ios::right); - if (z == 0) - estream << buchi_generation_time; - else - estream << buchi_generation_time - / number_of_successful_instances; - restoreStreamFormatting(stream); - } - - estream << " | "; - - if (number_of_successful_instances == 0) - estream << string(15, ' '); - else - { - changeStreamFormatting(stream, 15, 2, - ios::fixed | ios::right); - if (z == 0) - estream << total_deterministic_count; - else - estream << total_deterministic_count - / static_cast - (number_of_successful_instances); - restoreStreamFormatting(stream); - } - - estream << " | "; - - if (number_of_successful_instances == 0) - estream << string(14, ' '); - else - { - changeStreamFormatting(stream, 14, 2, - ios::fixed | ios::right); - if (z == 0) - estream << total_nondeterminism_index; - else - estream << total_nondeterminism_index - / static_cast - (number_of_successful_instances); - restoreStreamFormatting(stream); - } - - estream << " |"; - if (z == 0) - estream << '\n' + string(indent + 15, ' ') + "(avg.) | "; - } - } - - estream << '\n'; - } - } - - if (algorithm + 1 < round_info.number_of_translators) - estream << '\n'; - - break; - } - - /* - * Display the number of automaton computation failures. - */ - - case 1 : - { - unsigned long int number_of_failures; - unsigned long int total_count; - - const TestStatistics& stats = final_statistics[algorithm]; - - for (int j = 0; j < 3; j++) - { - estream << string(8 + indent, ' '); - switch (j) - { - case 0 : estream << "Positive formulae: "; break; - case 1 : estream << "Negative formulae: "; break; - default : estream << "Total:" + string(13, ' '); break; - } - - if (j < 2) - { - number_of_failures - = stats.failures_to_compute_buchi_automaton[j]; - total_count = stats.buchi_automaton_count[j]; - } - else - { - number_of_failures - = stats.failures_to_compute_buchi_automaton[0] - + stats.failures_to_compute_buchi_automaton[1]; - total_count = stats.buchi_automaton_count[0] - + stats.buchi_automaton_count[1]; - } - - changeStreamFormatting(stream, 5, 0, ios::left); - estream << number_of_failures; - restoreStreamFormatting(stream); - - estream << " ["; - - if (total_count > 0) - { - changeStreamFormatting(stream, 0, 2, ios::fixed); - estream << static_cast(number_of_failures) / total_count - * 100.0; - restoreStreamFormatting(stream); - - estream << "% of " << total_count; - } - else - estream << "no"; - - estream << " attempts]\n"; - } - - break; - } - - /* - * Display the number of consistency check failures. - */ - - case 2 : - { - const TestStatistics& stats = final_statistics[algorithm]; - - estream << string(8 + indent, ' '); - - changeStreamFormatting(stream, 5, 0, ios::left); - estream << stats.consistency_check_failures; - restoreStreamFormatting(stream); - - estream << " ["; - - if (stats.consistency_checks_performed > 0) - { - changeStreamFormatting(stream, 0, 2, ios::fixed); - estream << static_cast(stats.consistency_check_failures) - / stats.consistency_checks_performed - * 100.0; - restoreStreamFormatting(stream); - - estream << "% of " << stats.consistency_checks_performed; - } - else - estream << "no"; - - estream << " checks performed]\n"; - - break; - } - } - } - estream << '\n'; - } - - estream << '\n'; - - if ((configuration.algorithms.size() > 1 - && configuration.global_options.do_comp_test) - || configuration.global_options.do_intr_test) - { - vector::size_type - number_of_algorithms = configuration.algorithms.size(); - - int legend; - - estream << ind + " Result inconsistency statistics\n" - + ind + " " + string(31, '=') + '\n'; - - vector::size_type algorithm_x, algorithm_y; - - for (algorithm_x = 0; algorithm_x < number_of_algorithms; - algorithm_x += 2) - { - estream << '\n' + string(30 + indent, ' '); - - for (int i = 0; i < 2; ++i) - { - if (algorithm_x + i < number_of_algorithms) - { - algorithm_name = - configuration.algorithms[algorithm_x + i].name.substr(0, 20); - estream << "| " + algorithm_name - + string(21 - algorithm_name.length(), ' '); - } - } - estream << '|'; - - for (algorithm_y = 0; algorithm_y < number_of_algorithms; - algorithm_y++) - { - if (configuration.isInternalAlgorithm(algorithm_y)) - continue; - - estream << "\n " + ind + string(26, '-'); - - for (int i = 0; i < 2; ++i) - { - if (algorithm_x + i < number_of_algorithms) - estream << '+' + string(22, '-'); - } - estream << '+'; - - algorithm_name - = configuration.algorithms[algorithm_y].name.substr(0, 20); - - bool algorithm_name_printed = false; - legend = 1; - - for (int data_type = 0; data_type < 3; ++data_type) - { - if ((data_type < 2 - && configuration.global_options.do_comp_test - && number_of_algorithms > 1 - && (data_type == 0 - || configuration.global_options.product_mode - == Configuration::GLOBAL)) - || (data_type == 2 - && configuration.global_options.do_intr_test)) - { - estream << "\n " + ind - + (!algorithm_name_printed - ? algorithm_name - + string(21 - algorithm_name.length(), ' ') - : string(21, ' ')) - + " [" - + toString(legend) - + "] "; - - algorithm_name_printed = true; - legend++; - - for (int i = 0; i < 2; ++i) - { - if (algorithm_x + i < number_of_algorithms) - { - estream << '|'; - printCollectiveCrossComparisonStats(stream, algorithm_y, - algorithm_x + i, - data_type); - } - } - estream << '|'; - } - } - } - - estream << '\n'; - } - - legend = 1; - if (number_of_algorithms > 1 && configuration.global_options.do_comp_test) - { - if (configuration.global_options.product_mode == Configuration::GLOBAL) - { - estream << '\n' + string(indent + 4, ' ') - + "[1] Model checking result cross-comparison failures\n" - + string(indent + 9, ' ') - + "(number of failures / number of global " - "cross-comparisons)\n"; - legend++; - } - - estream << '\n' + string(indent + 4, ' ') + '[' + toString(legend) - + "] Model checking result cross-comparison failures " - "(initial state only)\n" - + string(indent + 9, ' ') - + "(number of failures / number of cross-comparisons)\n"; - legend++; - } - - if (configuration.global_options.do_intr_test) - estream << '\n' + string(indent + 4, ' ') + '[' + toString(legend) - + "] Büchi automata intersection emptiness check " - "failures\n" - + string(indent + 9, ' ') - + "(number of failures / number of checks performed)"; - - estream << "\n\n"; - } - - estream.flush(); -} - -} diff --git a/lbtt/src/StatDisplay.h b/lbtt/src/StatDisplay.h deleted file mode 100644 index a5cb99b45..000000000 --- a/lbtt/src/StatDisplay.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 - * Heikki Tauriainen - * - * 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 -#include -#include -#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::size_type - algorithm, - int result_id); - -void printProductAutomatonStats /* Displays information */ - (ostream& stream, /* about a product */ - int indent, /* automaton. */ - vector::size_type - algorithm, - int result_id); - -void printAcceptanceCycleStats /* Displays information */ - (ostream& stream, /* about the acceptance */ - int indent, /* cycles of a product */ - vector::size_type /* automaton. */ - algorithm, - int result_id); - -void printConsistencyCheckStats /* Displays the result */ - (ostream& stream, /* of the consistency */ - int indent, /* check for a given */ - vector::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::size_type algorithm); /* by the previous five - * functions. - */ - -void printCollectiveCrossComparisonStats /* Displays a single */ - (ostream& stream, /* `cell' of the final */ - vector::size_type algorithm_y, /* result cross- */ - vector::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 */ diff --git a/lbtt/src/StateSpace.cc b/lbtt/src/StateSpace.cc deleted file mode 100644 index 3c16064ea..000000000 --- a/lbtt/src/StateSpace.cc +++ /dev/null @@ -1,454 +0,0 @@ -/* - * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 - * Heikki Tauriainen - * - * 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 -#include -#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(), 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::iterator state = nodes.begin(); state != nodes.end(); - ++state) - static_cast(*state)->~State(); - - if (!nodes.empty()) - { - store.free(*nodes.begin()); - nodes.clear(); - nodes.reserve(0); - } -#endif /* HAVE_OBSTACK_H */ - - Graph::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 statistics = stats(); - pair 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(); -} - -} diff --git a/lbtt/src/StateSpace.h b/lbtt/src/StateSpace.h deleted file mode 100644 index cb67a6782..000000000 --- a/lbtt/src/StateSpace.h +++ /dev/null @@ -1,450 +0,0 @@ -/* - * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 - * Heikki Tauriainen - * - * 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 -#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 -{ -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::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::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 */ - - /* `empty' inherited from Graph */ - - 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 */ - - /* `stats' inherited from Graph */ - - /* `subgraphStats' inherited from Graph */ - - 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(*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(Graph::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::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::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 */ diff --git a/lbtt/src/StateSpaceProduct.h b/lbtt/src/StateSpaceProduct.h deleted file mode 100644 index 25a5c8a4b..000000000 --- a/lbtt/src/StateSpaceProduct.h +++ /dev/null @@ -1,430 +0,0 @@ -/* - * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 - * Heikki Tauriainen - * - * 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 -#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& a, - const Graph& 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::size_type /* product state */ - state_id) const; /* identifier and */ - const StateSpace::State& secondComponent /* states of the Büchi */ - (const Graph::size_type /* automaton and the */ - state_id) const; /* state space forming - * the product. - */ - - void mergeAcceptanceInformation /* Merges the acceptance */ - (const Graph::Node& state, /* sets associated with */ - const Graph::Node&, /* a state in the Büchi */ - BitArray& acceptance_sets) const; /* automaton into a - * collection of sets. - */ - - void mergeAcceptanceInformation /* Merges the acceptance */ - (const Graph::Edge& /* sets associated with */ - buchi_transition, /* a transition in the */ - const Graph::Edge&, /* Büchi automaton into */ - BitArray& acceptance_sets) const; /* a collection of sets. */ - - void validateEdgeIterators /* Ensures that a pair */ - (const Graph::Node& /* of transition */ - buchi_state, /* iterators points to a */ - const Graph::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::Node& /* transition iterators */ - buchi_state, /* to make them point to */ - const Graph::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& a, const Graph& s) : - buchi_automaton(static_cast(a)), - statespace(static_cast(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 - * object, assumed to be a BuchiAutomaton. - * s -- A constant reference to a Graph - * 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::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::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::Node& state, - const Graph::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(state).acceptanceSets(), - numberOfAcceptanceSets()); -} - -/* ========================================================================= */ -inline void StateSpaceProduct::mergeAcceptanceInformation - (const Graph::Edge& buchi_transition, - const Graph::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(buchi_transition) - .acceptanceSets(), - numberOfAcceptanceSets()); -} - -/* ========================================================================= */ -inline void StateSpaceProduct::validateEdgeIterators - (const Graph::Node& buchi_state, - const Graph::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 - (*buchi_transition)->enabled - (static_cast(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::Node& buchi_state, - const Graph::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 - (*buchi_transition)->enabled - (static_cast(system_state) - .positiveAtoms(), - statespace.numberOfPropositions())); - - system_transition = system_transitions.begin(); - } -} - -} - -#endif /* !STATESPACEPRODUCT_H */ diff --git a/lbtt/src/StateSpaceRandomizer.cc b/lbtt/src/StateSpaceRandomizer.cc deleted file mode 100644 index f836d72a1..000000000 --- a/lbtt/src/StateSpaceRandomizer.cc +++ /dev/null @@ -1,285 +0,0 @@ -/* - * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 - * Heikki Tauriainen - * - * 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 -#include -#include -#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 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; -} - -} diff --git a/lbtt/src/StateSpaceRandomizer.h b/lbtt/src/StateSpaceRandomizer.h deleted file mode 100644 index f74474490..000000000 --- a/lbtt/src/StateSpaceRandomizer.h +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 - * Heikki Tauriainen - * - * 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 -#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 */ diff --git a/lbtt/src/StringUtil.cc b/lbtt/src/StringUtil.cc deleted file mode 100644 index 45d31b2ec..000000000 --- a/lbtt/src/StringUtil.cc +++ /dev/null @@ -1,586 +0,0 @@ -/* - * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 - * Heikki Tauriainen - * - * 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 -#include -#include -#include -#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& 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 - * - * ::= "*" // 0 - * | // 1 - * | // 2 - * | // 3 - * | // 4 - * where is an unsigned long integer (not - * containing a minus sign), and 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* 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 interval_strings; - int interval_type; - - intervals.clear(); - sliceString(token, ",", interval_strings); - - for (vector::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; - } -} - -} diff --git a/lbtt/src/StringUtil.h b/lbtt/src/StringUtil.h deleted file mode 100644 index 954f936d6..000000000 --- a/lbtt/src/StringUtil.h +++ /dev/null @@ -1,352 +0,0 @@ -/* - * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 - * Heikki Tauriainen - * - * 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 -#include -#include -#ifdef HAVE_SSTREAM -#include -#else -#include -#endif /* HAVE_SSTREAM */ -#include -#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 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& 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* 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 -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 */ diff --git a/lbtt/src/TempFsysName.cc b/lbtt/src/TempFsysName.cc deleted file mode 100644 index 45f9ad676..000000000 --- a/lbtt/src/TempFsysName.cc +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (C) 2004, 2005 - * Heikki Tauriainen - * - * 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 -#include -#include -#include -#include -#include -#ifdef HAVE_FCNTL_H -#include -#endif /* HAVE_FCNTL_H */ -#include -#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; -} diff --git a/lbtt/src/TempFsysName.h b/lbtt/src/TempFsysName.h deleted file mode 100644 index d9fa07994..000000000 --- a/lbtt/src/TempFsysName.h +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (C) 2004, 2005 - * Heikki Tauriainen - * - * 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 -#include -#ifdef HAVE_UNISTD_H -#include -#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(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(0)) - return; - if (type == FILE) - remove(name); - else - rmdir(name); - delete[] name; - name = 0; -} - -#endif /* !TEMPFSYSNAME_H */ diff --git a/lbtt/src/TestOperations.cc b/lbtt/src/TestOperations.cc deleted file mode 100644 index c20277c68..000000000 --- a/lbtt/src/TestOperations.cc +++ /dev/null @@ -1,1917 +0,0 @@ -/* -*- coding: utf-8 -*- - * - * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 - * Heikki Tauriainen - * - * 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 -#include -#include -#include -#include -#include -#ifdef HAVE_SYS_STAT_H -#include -#endif /* HAVE_SYS_STAT_H */ -#ifdef HAVE_SYS_TIMES_H -#include -#endif /* HAVE_SYS_TIMES_H */ -#ifdef HAVE_SYS_TYPES_H -#include -#endif /* HAVE_SYS_TYPES_H */ -#ifdef HAVE_SYS_WAIT_H -#include -#endif /* HAVE_SYS_WAIT_H */ -#ifdef HAVE_UNISTD_H -#include -#endif /* HAVE_UNISTD_H */ -#ifdef HAVE_FCNTL_H -#include -#endif /* HAVE_FCNTL_H */ -#include "BitArray.h" -#include "BuchiAutomaton.h" -#include "BuchiProduct.h" -#include "DispUtil.h" -#include "Product.h" -#include "IntervalList.h" -#include "LtlFormula.h" -#include "PathEvaluator.h" -#include "Random.h" -#include "SccCollection.h" -#include "SharedTestData.h" -#include "PathIterator.h" -#include "StateSpace.h" -#include "StateSpaceProduct.h" -#include "StatDisplay.h" -#include "StringUtil.h" -#include "TempFsysName.h" -#include "TestOperations.h" -#include "TestRoundInfo.h" - - - -extern pid_t translator_process; - -/****************************************************************************** - * - * Implementations for the operations used in the main test loop. - * - *****************************************************************************/ - -namespace TestOperations -{ - -using namespace ::SharedTestData; -using namespace ::StatDisplay; -using namespace ::StringUtil; -using namespace ::DispUtil; - -/****************************************************************************** - * - * Timeout handler. - * - *****************************************************************************/ - -bool timeout = false; - -void timeoutHandler(int) -{ - timeout = true; -} - -/* ========================================================================= */ -void openFile - (const char* filename, ifstream& stream, ios::openmode mode, int indent) -/* ---------------------------------------------------------------------------- - * - * Description: Function for opening a file for input. - * - * Arguments: filename -- A pointer to a constant C-style string - * containing the name of the file to be opened. - * stream -- A reference to the input stream that should be - * associated with the file. - * mode -- A constant of type `ios::openmode' determining - * the open mode. - * indent -- Number of spaces to leave to the left of - * messages given to the user. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - printText(string("", 5, indent); - - stream.open(filename, mode); - - if (!stream.good()) - { - printText(" error\n", 5); - throw FileOpenException(string("`") + filename + "'"); - } - else - printText(" ok\n", 5); -} - -/* ========================================================================= */ -void openFile - (const char* filename, ofstream& stream, ios::openmode mode, int indent) -/* ---------------------------------------------------------------------------- - * - * Description: Function for opening a file for output. - * - * Arguments: filename -- A pointer to a constant C-style string with - * the name of the file to be opened. - * stream -- A reference to the output stream that should be - * associated with the file. - * mode -- A constant of type `ios::openmode' determining - * the open mode. - * indent -- Number of spaces to leave to the left of - * messages given to the user. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - printText(string("<") + (mode & ios::trunc ? "creat" : "open") + "ing `" - + filename + "'>", - 5, - indent); - - stream.open(filename, mode); - - if (!stream.good()) - { - printText(" error\n", 5); - - if (mode & ios::trunc) - throw FileCreationException(string("`") + filename + "'"); - else - throw FileOpenException(string("`") + filename + "'"); - } - else - printText(" ok\n", 5); -} - -/* ========================================================================= */ -void openFile(const char* filename, int& fd, int flags, int indent) -/* ---------------------------------------------------------------------------- - * - * Description: Function for opening a file for input/output using file - * descriptors. - * - * Arguments: filename -- A pointer to a constant C-style string with - * the name of the file to be opened. - * fd -- A reference to an int that should be associated - * with the file descriptor of the file. This - * variable will have the value -1 if the - * operation fails. - * flags -- An integer specifying the open mode. - * indent -- Number of spaces to leave to the left of - * messages given to the user. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - printText(string("<") + (flags & O_CREAT ? "creat" : "open") + "ing `" - + filename + "'>", - 5, - indent); - - if (flags & O_CREAT) - fd = open(filename, flags, S_IRUSR | S_IWUSR); - else - fd = open(filename, flags); - - if (fd == -1) - { - printText(" error\n", 5); - - if (flags & O_CREAT) - throw FileCreationException(string("`") + filename + "'"); - else - throw FileOpenException(string("`") + filename + "'"); - } - else - printText(" ok\n", 5); -} - -/* ========================================================================= */ -void truncateFile(const char* filename, int indent) -/* ---------------------------------------------------------------------------- - * - * Description: Truncates a file. - * - * Arguments: filename -- A pointer to a constant C-style string with - * the name of the file to be truncated. - * indent -- Number of spaces to leave to the left of - * messages given to the user. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - printText(string("", 5, indent); - - int fd = open(filename, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); - if (fd != -1) - { - close(fd); - printText(" ok\n", 5); - } - else - printText(" error\n", 5); -} - -/* ========================================================================= */ -void printFileContents - (ostream& stream, const char* message, const char* filename, int indent, - const char* line_prefix) -/* ---------------------------------------------------------------------------- - * - * Description: Outputs the contents of a file into a stream. - * - * Arguments: stream -- A reference to the output stream into which - * the file contents should be outputted. - * message -- A pointer to a constant C-style string - * containing a message to be outputted to the - * stream before the contents of the file. (To - * display only the file contents, use a null - * pointer for the message; an empty string - * results in an empty line to be outputted - * before the file contents.) - * filename -- A pointer to a constant C-style string - * containing the name of the input file. - * indent -- Number of spaces to leave to the left of - * output. - * line_prefix -- A pointer to a constant C-style string - * that will be prepended to each outputted - * line. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - ifstream file; - Exceptional_ostream estream(&stream, ios::failbit | ios::badbit); - - openFile(filename, file, ios::in, indent); - - bool first_line_printed = false; - string message_line; - - printText(string("\n", 5, indent); - - while (file.good()) - { - message_line = ""; - - getline(file, message_line, '\n'); - - if (!file.eof()) - { - if (!first_line_printed && message != 0) - { - first_line_printed = true; - estream << string(indent, ' ') + message + '\n'; - } - - estream << string(indent, ' ') + line_prefix + message_line + '\n'; - } - } - - estream.flush(); - - file.close(); -} - -/* ========================================================================= */ -void writeToTranscript(const string& message, bool show_formula_in_header) -/* ---------------------------------------------------------------------------- - * - * Description: Writes a message into the transcript file. (If this is the - * first message to be written to the file in the current test - * round, the message is preceded with a header showing the - * round number and the LTL formulae used in the round.) - * - * Argument: message -- A message to be written to the - * file. - * show_formula_in_header -- If false, prevents displaying - * an LTL formula in the error - * report header (e.g., when it is - * the formula generation that - * failed). - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - if (round_info.error_report_round != round_info.current_round) - { - round_info.error_report_round = round_info.current_round; - - const string roundstring = "Round " + toString(round_info.current_round); - - round_info.transcript_file << roundstring + '\n' - + string(roundstring.length(), '-') - + "\n\n"; - - if (show_formula_in_header) - { - const int formula - = (configuration.formula_options.output_mode == Configuration::NNF - ? 0 - : 2); - - try - { - round_info.transcript_file << " Formula (+): "; - round_info.formulae[formula]->print(round_info.transcript_file); - round_info.transcript_file << "\n Negated (-): "; - round_info.formulae[formula + 1]->print(round_info.transcript_file); - round_info.transcript_file << endl << endl; - } - catch (const IOException&) - { - } - } - } - - round_info.transcript_file << " " + message + '\n'; - round_info.transcript_file.flush(); -} - -/* ========================================================================= */ -void generateStateSpace() -/* ---------------------------------------------------------------------------- - * - * Description: Generates a random state space. The global variable - * `configuration.global_options.statespace_generation_mode' - * determines the type of state space to be generated. - * - * Arguments: None. - * - * Returns: Nothing. The result can be accessed through - * `round_info.statespace'. - * - * ------------------------------------------------------------------------- */ -{ - using ::Graph::StateSpace; - - if (configuration.global_options.statespace_generation_mode - == Configuration::ENUMERATEDPATH) - { - StateSpace::size_type current_size - = configuration.statespace_generator.min_size; - - /* - * If the state spaces are enumerated paths, generate the next path. - */ - - printText("Generating next state space\n", 2, 4); - - if (round_info.path_iterator != 0) - { - current_size = (*round_info.path_iterator)->size(); - ++(*round_info.path_iterator); - if (round_info.path_iterator->atEnd()) - { - delete round_info.path_iterator; - round_info.path_iterator = 0; - - if (current_size < configuration.statespace_generator.max_size) - { - current_size++; - printText("[Increasing state space size to " + toString(current_size) - + "]\n", - 2, - 6); - } - else - { - current_size = configuration.statespace_generator.min_size; - printText("[All state spaces have been enumerated. Staring over]\n", - 2, - 6); - } - } - } - - if (round_info.path_iterator == 0) - { - round_info.path_iterator - = new Graph::PathIterator - (configuration.statespace_generator.atoms_per_state, - current_size); - } - - printText("\n", 2); - - round_info.statespace = &(**round_info.path_iterator); - } - else - { - /* - * Otherwise generate a random state space. - */ - - if (round_info.statespace != 0) - { - delete round_info.statespace; - round_info.statespace = 0; - } - - if (printText("Generating random state space\n", 2, 4)) - printText("", 4, 6); - - /* - * Determine the type of the state space to be generated according to the - * configuration options, then generate it. - */ - - StateSpace* statespace; - - try - { - switch (configuration.global_options.statespace_generation_mode) - { - case Configuration::RANDOMGRAPH : - statespace = configuration.statespace_generator.generateGraph(); - break; - - case Configuration::RANDOMCONNECTEDGRAPH : - statespace = configuration.statespace_generator. - generateConnectedGraph(); - break; - - default : /* Configuration::RANDOMPATH */ - statespace = configuration.statespace_generator.generatePath(); - break; - } - } - catch (const UserBreakException&) - { - printText(" user break\n\n", 4); - - if (round_info.transcript_file.is_open()) - writeToTranscript("User break while generating state space. No tests " - "performed.\n", false); - - throw; - } - catch (const bad_alloc&) - { - if (!printText(" out of memory\n\n", 4)) - printText("[Out of memory]\n\n", 2, 6); - - if (round_info.transcript_file.is_open()) - writeToTranscript("Out of memory while generating state space. No " - "tests performed.\n", false); - - throw StateSpaceGenerationException(); - } - - round_info.statespace = statespace; - - printText(" ok\n", 4); - - if (configuration.statespace_generator.max_size - > configuration.statespace_generator.min_size) - printText("number of states: " - + toString(round_info.statespace->size()) - + '\n', - 3, - 6); - - printText("\n", 2); - } - - round_info.num_generated_statespaces++; - - pair - statespace_stats(round_info.statespace->stats()); - - round_info.total_statespace_states += statespace_stats.first; - round_info.total_statespace_transitions += statespace_stats.second; - - round_info.real_emptiness_check_size - = (configuration.global_options.product_mode == Configuration::GLOBAL - ? round_info.statespace->size() - : 1); -} - -/* ========================================================================= */ -void generateFormulae(istream* formula_input_stream) -/* ---------------------------------------------------------------------------- - * - * Description: Generates a random LTL formula according to the current - * configuration and stores the formula, its negation and their - * negated normal forms into `round_info.formulae'. - * - * Argument: formula_input_stream -- A pointer to an input stream. If - * the pointer is nonzero, no random - * formula will be generated; instead, - * a formula will be read from the - * stream. - * - * Returns: Nothing. The generated formulae can be found in the global - * array `round_info.formulae'. - * - * ------------------------------------------------------------------------- */ -{ - for (int f = 0; f < 4; f++) - { - if (round_info.formulae[f] != 0) - { - ::Ltl::LtlFormula::destruct(round_info.formulae[f]); - round_info.formulae[f] = static_cast(0); - } - } - - if (printText(string(formula_input_stream == 0 ? "Random " : "") - + "LTL formula:\n", - 3, - 4)) - printText(string("<") + (formula_input_stream == 0 ? "generat" : "read") - + "ing>", - 4, - 6); - else - printText(string(formula_input_stream == 0 - ? "Generating random" - : "Reading") - + " LTL formula\n", - 2, - 4); - - if (formula_input_stream != 0) - { - /* - * If a valid pointer to a stream was given as a parameter, try to read a - * formula from the stream. - */ - - try - { - try - { - round_info.formulae[2] - = ::Ltl::LtlFormula::read(*formula_input_stream); - } - catch (...) - { - printText(" error\n", 4); - throw; - } - } - catch (const ::Ltl::LtlFormula::ParseErrorException&) - { - printText(string("[Error parsing the ") - + (formula_input_stream == &round_info.formula_input_file - ? "formula file" - : "input formula") - + ". Aborting]\n", - 2, - 6); - - if (round_info.transcript_file.is_open()) - writeToTranscript("Error parsing input formula. Testing aborted.\n", - false); - - throw FormulaGenerationException(); - } - catch (const IOException&) - { - bool fatal_io_error - = (configuration.global_options.formula_input_filename.empty() - || !round_info.formula_input_stream->eof()); - - printText(string("[") + (fatal_io_error - ? "Error reading formula" - : "No more input formulae") - + ". Aborting]\n", - 2, - 6); - - if (round_info.transcript_file.is_open()) - writeToTranscript(fatal_io_error - ? "Error reading input formula. Testing " - "aborted.\n" - : "No more input formulae. Testing aborted.\n", - false); - - throw FormulaGenerationException(); - } - - printText(" ok\n", 4); - } - else - { - /* - * Otherwise generate a random formula. - */ - - try - { - round_info.formulae[2] - = configuration.formula_options.formula_generator.generate(); - } - catch (...) - { - printText(" error\n", 4); - throw; - } - - printText(" ok\n", 4); - - if (configuration.formula_options.formula_generator.max_size - > configuration.formula_options.formula_generator.size) - printText("parse tree size:" + string(11, ' ') - + toString(round_info.formulae[2]->size()) + '\n', - 3, - 6); - } - - ++round_info.num_processed_formulae; - - printText("", 4, 6); - - round_info.formulae[0] = round_info.formulae[2]->nnfClone(); - - if (printText(" ok\n", 4)) - printText("", 4, 6); - - round_info.formulae[3] = &(::Ltl::Not::construct(*round_info.formulae[2])); - - if (printText(" ok\n", 4)) - printText("", 4, 6); - - round_info.formulae[1] = round_info.formulae[3]->nnfClone(); - - if (configuration.global_options.verbosity >= 3) - { - printText(" ok\n", 4); - - for (int f = 0; f <= 1; f++) - { - round_info.cout << string(6, ' ') + (f == 0 ? "" : "negated ") - + "formula:" + string(19 - 8 * f, ' '); - round_info.formulae[f + 2]->print(round_info.cout); - round_info.cout << '\n'; - - if (configuration.formula_options.output_mode == Configuration::NNF) - { - round_info.cout << string(8, ' ') + "in negation normal form: "; - round_info.formulae[f]->print(round_info.cout); - round_info.cout << '\n'; - } - } - } - - printText("\n", 2); -} - -/* ========================================================================= */ -void verifyFormulaOnPath() -/* ---------------------------------------------------------------------------- - * - * Description: Model checks an LTL formula (accessed through the global - * data structure `round_info' on a path directly and stores the - * result into the test result data structure. - * - * Arguments: None. - * - * Returns: Nothing. The model checking results are stored into the test - * result data structure. - * - * ------------------------------------------------------------------------- */ -{ - if (printText("Model checking formula using internal algorithm\n", 2, 4)) - printText("", 4, 6); - - test_results[round_info.number_of_translators - 1].automaton_stats[0]. - emptiness_check_result.clear(); - test_results[round_info.number_of_translators - 1].automaton_stats[1]. - emptiness_check_result.clear(); - - try - { - int formula = (configuration.formula_options.output_mode - == Configuration::NNF - ? 0 - : 2); - - Ltl::PathEvaluator path_evaluator; - path_evaluator.evaluate(*round_info.formulae[formula], - *(round_info.statespace)); - - for (unsigned long int s = 0; s < round_info.real_emptiness_check_size; - s++) - { - if (path_evaluator.getResult(s)) - test_results[round_info.number_of_translators - 1].automaton_stats[0]. - emptiness_check_result.setBit(s); - else - test_results[round_info.number_of_translators - 1].automaton_stats[1]. - emptiness_check_result.setBit(s); - } - } - catch (const UserBreakException&) - { - if (!printText(" aborted (user break)", 4)) - printText("[User break]", 2, 6); - printText("\n\n", 2); - - if (round_info.transcript_file.is_open()) - writeToTranscript("User break while model checking formulas. No tests " - "performed.\n"); - - throw; - } - catch (const bad_alloc&) - { - if (!printText(" aborted (out of memory)", 4)) - printText("[Out of memory]", 2, 6); - printText("\n\n", 2); - - if (round_info.transcript_file.is_open()) - writeToTranscript("Out of memory while model checking formulas. No " - "tests performed.\n"); - - round_info.error = true; - return; - } - - printText(" ok\n", 4); - printText("\n", 2); - - test_results[round_info.number_of_translators - 1].automaton_stats[0]. - emptiness_check_performed = true; - test_results[round_info.number_of_translators - 1].automaton_stats[1]. - emptiness_check_performed = true; -} - -/* ========================================================================= */ -void writeFormulaeToFiles() -/* ---------------------------------------------------------------------------- - * - * Description: Writes the LTL formulae used in the tests into files in the - * output mode specified in the program configuration. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - ofstream formula_file; - - for (int f = 0; f < 2; f++) - { - Exceptional_ostream eformula_file(&formula_file, - ios::failbit | ios::badbit); - - if (!round_info.formula_in_file[f]) - { - try - { - openFile(round_info.formula_file_name[f]->get(), formula_file, - ios::out | ios::trunc, 6); - - printText(string("get() - + "'>\n", - 5, - 6); - - round_info.formulae[configuration.formula_options. - output_mode == Configuration::NNF - ? f - : f + 2]->print(eformula_file, ::Ltl::LTL_PREFIX); - - eformula_file << '\n'; - - formula_file.close(); - round_info.formula_in_file[f] = true; - } - catch (const IOException& e) - { - if (formula_file.is_open()) - formula_file.close(); - - printText(string("Error: ") + e.what() + "\n\n", 2, 6); - - round_info.error = true; - return; - } - } - } -} - -/* ========================================================================= */ -void generateBuchiAutomaton - (int f, - vector::size_type algorithm_id) -/* ---------------------------------------------------------------------------- - * - * Description: Constructs a BuchiAutomaton by invoking an external program - * that will perform the conversion of a LTL formula (stored - * into a file) into a Büchi automaton. - * - * Arguments: f -- Indicates the formula to be converted into - * an automaton. 0 corresponds to the positive - * and 1 to the negated formula. - * algorithm_id -- Identifier of the LTL-to-Büchi translator - * to use. - * - * Returns: Nothing. The result is stored in - * `test_results[algorithm_id].automaton_stats[f]. - * buchi_automaton'. - * - * ------------------------------------------------------------------------- */ -{ - using ::Graph::BuchiAutomaton; - - AutomatonStats& automaton_stats - = test_results[algorithm_id].automaton_stats[f]; - - if (automaton_stats.buchiAutomatonComputed()) - printText("Büchi automaton (cached):\n", 3, 8); - else - { - printText("Büchi automaton:\n", 3, 8); - - const Configuration::AlgorithmInformation& algorithm - = configuration.algorithms[algorithm_id]; - - final_statistics[algorithm_id].buchi_automaton_count[f]++; - - BuchiAutomaton* buchi_automaton = new BuchiAutomaton(); - - struct tms timing_information_begin, timing_information_end; - - string failure_reason; - int stdout_capture_fileno = -1, stderr_capture_fileno = -1; - int exitcode; - - struct sigaction timeout_sa; - timeout_sa.sa_handler = timeoutHandler; - sigemptyset(&timeout_sa.sa_mask); - timeout_sa.sa_flags = 0; - - truncateFile(round_info.automaton_file_name->get(), 10); - truncateFile(round_info.cout_capture_file->get(), 10); - truncateFile(round_info.cerr_capture_file->get(), 10); - - try - { - automaton_stats.buchi_generation_time = -1.0; - - /* - * Redirect standard output and standard error to files. - */ - - try - { - openFile(round_info.cout_capture_file->get(), stdout_capture_fileno, - O_CREAT | O_WRONLY | O_TRUNC, 10); - - openFile(round_info.cerr_capture_file->get(), stderr_capture_fileno, - O_CREAT | O_WRONLY | O_TRUNC, 10); - } - catch (const FileCreationException&) - { - if (stdout_capture_fileno != -1) - { - close(stdout_capture_fileno); - stdout_capture_fileno = -1; - } - printText(string(9, ' '), 4); - throw Exception(string("redirection of standard ") - + (stdout_capture_fileno == -1 ? "output" : "error") - + " failed (" - + string(strerror(errno)) + ")"); - } - - /* Execute the external program. */ - - if (!printText("", 5, 10)) - printText("", 4, 10); - - int error_number; - int error_pipe[2]; /* used for communicating errors in exec() */ - - double elapsed_time = -1.0; - - if (pipe(error_pipe) == -1) - error_number = errno; - else - { - algorithm.parameters[algorithm.num_parameters + 1] - = const_cast(round_info.formula_file_name[f]->get()); - algorithm.parameters[algorithm.num_parameters + 2] - = const_cast(round_info.automaton_file_name->get()); - - times(&timing_information_begin); - translator_process = fork(); - switch (translator_process) - { - case 0 : /* child */ - close(error_pipe[0]); - - if (setpgid(0, 0) != -1 - && dup2(stdout_capture_fileno, STDOUT_FILENO) != -1 - && dup2(stderr_capture_fileno, STDERR_FILENO) != -1) - execvp(algorithm.parameters[0], algorithm.parameters); - - /* setsid, dup2 or exec failed: write the value of errno to - * error_pipe */ - - (void) write(error_pipe[1], static_cast(&errno), - sizeof(int)); - close(error_pipe[1]); - exit(0); - - case -1 : /* fork failed */ - translator_process = 0; - error_number = errno; - close(error_pipe[0]); - close(error_pipe[1]); - break; - - default : /* parent */ - setpgid(translator_process, translator_process); - - if (configuration.global_options.handle_breaks) - { - /* If lbtt is currently in the foreground (and has a controlling - terminal), transfer the controlling terminal to the translator - process. */ - - const pid_t foreground_pgrp = tcgetpgrp(STDIN_FILENO); - if (foreground_pgrp != -1 && foreground_pgrp == getpgrp()) - { - sigset_t mask; - sigemptyset(&mask); - sigaddset(&mask, SIGTTOU); - sigprocmask(SIG_BLOCK, &mask, 0); - tcsetpgrp(STDIN_FILENO, translator_process); - sigprocmask(SIG_UNBLOCK, &mask, 0); - } - } - - /* Install handler for timeouts if necessary. */ - - if (configuration.global_options.translator_timeout > 0) - { - sigaction(SIGALRM, &timeout_sa, - static_cast(0)); - timeout = false; - alarm(configuration.global_options.translator_timeout); - } - - close(error_pipe[1]); - - if (waitpid(translator_process, &exitcode, 0) == -1) - /* waitpid failed */ - { - error_number = errno; - if (kill(translator_process, 0) == 0) /* child still running */ - { - /* - * Try to terminate the child process three times with SIGTERM - * (sleeping for one second between the tries). If the child - * fails to respond, try to terminate the child one more time - * with SIGKILL. - */ - - int sig = SIGTERM; - unsigned int delay = 1; - for (int attempts_to_terminate = 0; attempts_to_terminate < 4; - ++attempts_to_terminate) - { - kill(-translator_process, sig); - sleep(delay); - if (waitpid(translator_process, &exitcode, WNOHANG) != 0) - { - times(&timing_information_end); - translator_process = 0; - break; - } - if (attempts_to_terminate == 2) - { - sig = SIGKILL; - delay = 5; - } - } - } - else if (errno != EPERM) - translator_process = 0; - } - else /* child exited successfully */ - { - times(&timing_information_end); - translator_process = 0; - - /* - * If there is something to be read from error_pipe, then there - * was an error in replacing the child process with the external - * program (and the pipe contains the value of errno in this - * case). - */ - - if (read(error_pipe[0], static_cast(&error_number), - sizeof(int)) == 0) - error_number = 0; - } - - close(error_pipe[0]); - - /* Restore signal handlers and remove any pending alarms. */ - - if (configuration.global_options.translator_timeout > 0) - { - timeout_sa.sa_handler = SIG_DFL; - sigaction(SIGALRM, &timeout_sa, - static_cast(0)); - alarm(0); - } - - if (configuration.global_options.handle_breaks) - { - /* Put lbtt again in the foreground. */ - - if (tcgetpgrp(STDIN_FILENO) != -1) - { - sigset_t mask; - sigemptyset(&mask); - sigaddset(&mask, SIGTTOU); - sigprocmask(SIG_BLOCK, &mask, 0); - tcsetpgrp(STDIN_FILENO, getpgrp()); - sigprocmask(SIG_UNBLOCK, &mask, 0); - } - } - - if (translator_process == 0 - && timing_information_begin.tms_utime - != static_cast(-1) - && timing_information_begin.tms_cutime - != static_cast(-1) - && timing_information_end.tms_utime != static_cast(-1) - && timing_information_end.tms_cutime - != static_cast(-1)) - elapsed_time = static_cast - (timing_information_end.tms_utime - + timing_information_end.tms_cutime - - timing_information_begin.tms_utime - - timing_information_begin.tms_cutime) - / sysconf(_SC_CLK_TCK); - - break; - } - } - - close(stdout_capture_fileno); - close(stderr_capture_fileno); - - /* - * If translator_process != 0 at this point, then a timeout occurred, - * but lbtt was unable to terminate the child process. The exception - * handler will in this case throw an unexpected exception (see below) - * so that lbtt will terminate (for example, it is not safe to use the - * temporary file names any longer if the (still running) child process - * happens to write to them). - */ - - if (translator_process != 0) - { - stdout_capture_fileno = stderr_capture_fileno = -1; - throw Exception("could not terminate child process"); - } - - if (error_number != 0) /* pipe, fork, setsid, dup2, execvp or waitpid - * failed */ - { - stdout_capture_fileno = stderr_capture_fileno = -1; - ExecFailedException e; - - if (configuration.global_options.translator_timeout > 0 && timeout) - e.changeMessage("Automaton generation aborted due to timeout."); - else - e.changeMessage("Execution of `" + string(algorithm.parameters[0]) - + "' failed (" + string(strerror(error_number)) - + ")"); - throw e; - } - - automaton_stats.buchi_generation_time = elapsed_time; - - /* - * Nonzero exit codes from the external program are interpreted as - * errors. The same holds if the program was aborted by a signal. In - * these cases, throw an exception indicating that the program - * execution failed. - */ - - if (WIFSIGNALED(exitcode) - || (WIFEXITED(exitcode) && WEXITSTATUS(exitcode) != 0)) - { - ExecFailedException e; - failure_reason = "`" + string(algorithm.parameters[0]) + "' "; - - if (WIFSIGNALED(exitcode)) - { - failure_reason += "aborted by signal " - + toString(WTERMSIG(exitcode)); - -#ifdef HAVE_STRSIGNAL - const char* signame = strsignal(WTERMSIG(exitcode)); - if (signame != 0) - failure_reason += " (" + string(signame) + ")"; -#endif /* HAVE_STRSIGNAL */ - - if (WTERMSIG(exitcode) == SIGINT || WTERMSIG(exitcode) == SIGQUIT) - raise(WTERMSIG(exitcode)); - } - else - failure_reason += "exited with exit status " - + toString(WEXITSTATUS(exitcode)); - - e.changeMessage(failure_reason - + (automaton_stats.buchi_generation_time >= 0.0 - ? " after " - + toString(automaton_stats.buchi_generation_time, - 2) - + " seconds" - : string(""))); - - throw e; - } - - printText(" ok\n", 4); - - /* - * Read the automaton description into memory from the result file. - */ - - ifstream automaton_file; - openFile(round_info.automaton_file_name->get(), automaton_file, ios::in, - 10); - - printText("", 4, 10); - - try - { - automaton_file >> *buchi_automaton; - } - catch (const bad_alloc&) - { - throw Exception("out of memory"); - } - - automaton_file.close(); - - printText(" ok\n", 4); - - automaton_stats.buchi_automaton = buchi_automaton; - } - catch (...) - { - delete buchi_automaton; - - if (user_break) - { - if (!printText(" aborted (user break)", 4)) - printText("[User break]", 1, - configuration.global_options.verbosity <= 2 ? 0 : 10); - printText("\n\n", 1); - - if (round_info.transcript_file.is_open()) - writeToTranscript("User break while generating Büchi automaton (" - + configuration.algorithmString(algorithm_id) - + ", " - + (f == 0 ? "posi" : "nega") + "tive formula)\n"); - - throw UserBreakException(); - } - - if (round_info.transcript_file.is_open()) - writeToTranscript("Büchi automaton generation failed (" - + configuration.algorithmString(algorithm_id) - + ", " - + (f == 0 ? "posi" : "nega") - + "tive formula)" - + (automaton_stats.buchi_generation_time >= 0.0 - ? "\n" + string(8, ' ') + "Elapsed time: " - + toString(automaton_stats. - buchi_generation_time, - 2) - + " seconds (user time)" - : string(""))); - - try - { - throw; - } - catch (const ExecFailedException& e) - { - if (configuration.global_options.translator_timeout > 0 && timeout) - { - if (!printText(" aborted (timeout)", 4)) - printText("[Timeout]", 1, - configuration.global_options.verbosity <= 2 ? 0 : 10); - } - else - { - if (!printText(string(" error: ") + e.what(), 4)) - printText("[Failed to execute translator]", 1, - configuration.global_options.verbosity <= 2 ? 0 : 10); - } - printText("\n", 3); - if (round_info.transcript_file.is_open()) - round_info.transcript_file << string(8, ' ') + e.what() + "\n"; - } - catch (const BuchiAutomaton::AutomatonParseException& e) - { - if (!printText(string(" error parsing input: ") + e.what(), 4)) - printText("[Error parsing automaton]", 1, - configuration.global_options.verbosity <= 2 ? 0 : 10); - printText("\n", 3); - if (round_info.transcript_file.is_open()) - round_info.transcript_file << string(8, ' ') - + "Error reading automaton: " - + e.what() - + "\n"; - } - catch (const Exception& e) - { - if (!printText(string(" lbtt internal error: ") + e.what(), 4)) - printText("[lbtt internal error]", 1, - configuration.global_options.verbosity <= 2 ? 0 : 10); - printText("\n", 3); - if (round_info.transcript_file.is_open()) - round_info.transcript_file << string(8, ' ') - + "lbtt internal error: " - + e.what() - + "\n"; - } - - try - { - if (stdout_capture_fileno != -1) - { - const char* msg = "Contents of stdout"; - - if (configuration.global_options.verbosity >= 3) - printFileContents(cout, msg, round_info.cout_capture_file->get(), - 10, "> "); - if (round_info.transcript_file.is_open()) - printFileContents(round_info.transcript_file, msg, - round_info.cout_capture_file->get(), 10, "> "); - } - - if (stderr_capture_fileno != -1) - { - const char* msg = "Contents of stderr:"; - - if (configuration.global_options.verbosity >= 3) - printFileContents(cout, msg, round_info.cerr_capture_file->get(), - 10, "> "); - if (round_info.transcript_file.is_open()) - printFileContents(round_info.transcript_file, msg, - round_info.cerr_capture_file->get(), 10, "> "); - } - } - catch (const IOException&) - { - } - - if (round_info.transcript_file.is_open()) - { - round_info.transcript_file << '\n'; - round_info.transcript_file.flush(); - } - - if (translator_process != 0) /* fatal error, lbtt should be terminated */ - throw Exception - ("fatal internal error while generating Büchi automaton"); - - throw BuchiAutomatonGenerationException(); - } - - if (configuration.global_options.verbosity >= 3) - { - try - { - printFileContents(cout, "Contents of stdout:", - round_info.cout_capture_file->get(), 10, "> "); - printFileContents(cout, "Contents of stderr:", - round_info.cerr_capture_file->get(), 10, "> "); - } - catch (const IOException&) - { - } - } - - printText("", 4, 10); - - pair buchi_stats - = automaton_stats.buchi_automaton->stats(); - - automaton_stats.number_of_buchi_states = buchi_stats.first; - automaton_stats.number_of_buchi_transitions = buchi_stats.second; - automaton_stats.number_of_acceptance_sets - = automaton_stats.buchi_automaton->numberOfAcceptanceSets(); - automaton_stats.nondeterminism_index - = automaton_stats.buchi_automaton->nondeterminismIndex(); - automaton_stats.is_deterministic - = automaton_stats.buchi_automaton->isDeterministic(); - - /* - * Update Büchi automaton statistics for the given algorithm. - */ - - final_statistics[algorithm_id].total_number_of_buchi_states[f] - += automaton_stats.number_of_buchi_states; - final_statistics[algorithm_id].total_number_of_buchi_transitions[f] - += automaton_stats.number_of_buchi_transitions; - final_statistics[algorithm_id].total_number_of_acceptance_sets[f] - += automaton_stats.number_of_acceptance_sets; - final_statistics[algorithm_id].total_nondeterminism_index[f] - += automaton_stats.nondeterminism_index; - if (automaton_stats.is_deterministic) - final_statistics[algorithm_id].total_deterministic_count[f]++; - - if (final_statistics[algorithm_id].total_buchi_generation_time[f] < 0.0 - || automaton_stats.buchi_generation_time < 0.0) - final_statistics[algorithm_id].total_buchi_generation_time[f] = -1.0; - else - final_statistics[algorithm_id].total_buchi_generation_time[f] - += automaton_stats.buchi_generation_time; - - printText(" ok\n", 4); - } - - if (configuration.global_options.verbosity >= 1) - printBuchiAutomatonStats(cout, 10, algorithm_id, f); -} - -/* ========================================================================= */ -void performEmptinessCheck - (int f, - vector::size_type algorithm_id) -/* ---------------------------------------------------------------------------- - * - * Description: Performs the emptiness check on a ProductAutomaton, i.e., - * finds the states of the original state space from which an - * accepting cycle of the Büchi automaton can be reached. - * - * Arguments: f -- Indicates the formula originally used for - * constructing the given product automaton. - * 0 corresponds to the automaton obtained - * from the positive, 1 to the one obtained - * from the negated formula. - * algorithm_id -- Identifier of the LTL-to-Büchi translator - * originally used for generating the given - * product automaton. - * - * Returns: Nothing. The test state variables are updated according to - * the results. - * - * ------------------------------------------------------------------------- */ -{ - AutomatonStats& automaton_stats - = test_results[algorithm_id].automaton_stats[f]; - - const bool result_cached = automaton_stats.emptiness_check_performed; - - printText("Product automaton" - + string(result_cached ? " (cached)" : "") - + ":\n", - 3, - 8); - - if (!result_cached) - { - printText("", 4, 10); - - final_statistics[algorithm_id].product_automaton_count[f]++; - - using ::Graph::StateSpaceProduct; - using ::Graph::Product; - - try - { - Product - product(*automaton_stats.buchi_automaton, *round_info.statespace); - - const pair::size_type, unsigned long int> - product_stats = product.globalEmptinessCheck - (automaton_stats.buchi_automaton->initialState(), - automaton_stats.emptiness_check_result, - round_info.real_emptiness_check_size); - - printText(" ok\n", 4); - - automaton_stats.number_of_product_states = product_stats.first; - automaton_stats.number_of_product_transitions = product_stats.second; - - final_statistics[algorithm_id].total_number_of_product_states[f] - += automaton_stats.number_of_product_states; - final_statistics[algorithm_id].total_number_of_product_transitions[f] - += automaton_stats.number_of_product_transitions; - automaton_stats.emptiness_check_performed = true; - } - catch (const Product::SizeException&) - { - if (!printText(" aborted (product may be too large)", 4)) - printText("[Product may be too large]", 1, - configuration.global_options.verbosity <= 2 ? 0 : 10); - printText("\n", 3); - - if (round_info.transcript_file.is_open()) - writeToTranscript("Product automaton generation aborted (" - + configuration.algorithmString(algorithm_id) - + ", " - + (f == 0 ? "posi" : "nega") + "tive formula)" - + ". Product may be too large.\n"); - - throw ProductAutomatonGenerationException(); - } - catch (const UserBreakException&) - { - if (!printText(" aborted (user break)", 4)) - printText("[User break]", 1, - configuration.global_options.verbosity <= 2 ? 0 : 10); - printText("\n\n", 1); - - if (round_info.transcript_file.is_open()) - writeToTranscript("User break while generating product automaton (" - + configuration.algorithmString(algorithm_id) - + ", " - + (f == 0 ? "posi" : "nega") + "tive formula)\n"); - - throw; - } - catch (const bad_alloc&) - { - if (!printText(" aborted (out of memory)", 4)) - printText("[Out of memory]", 1, - configuration.global_options.verbosity <= 2 ? 0 : 10); - printText("\n", 3); - - if (round_info.transcript_file.is_open()) - writeToTranscript("Out of memory while generating product " - "automaton (" - + configuration.algorithmString(algorithm_id) - + ", " - + (f == 0 ? "posi" : "nega") + "tive formula)\n"); - - throw ProductAutomatonGenerationException(); - } - } - - if (configuration.global_options.verbosity >= 1) - printProductAutomatonStats(cout, 10, algorithm_id, f); - - printText("Accepting cycles" + string(result_cached ? " (cached)" : "") - + ":\n", - 3, - 8); - if (configuration.global_options.verbosity >= 1) - printAcceptanceCycleStats(cout, 10, algorithm_id, f); - -} - -/* ========================================================================= */ -void performConsistencyCheck - (vector::size_type algorithm_id) -/* ---------------------------------------------------------------------------- - * - * Description: Checks the model checking results for consistency for a - * particular LTL-to-Büchi conversion algorithm implementation, - * i.e., verifies that the model checking results for a formula - * and its negation are not contradictory. - * - * Arguments: algorithm_id -- Identifier of an algorithm for which the - * model checking result consistency check - * should be performed. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - bool result = true; - - if (test_results[algorithm_id].consistency_check_result == -1) - { - StateSpace::size_type state; - const Bitset& acceptance_vector_for_formula - = test_results[algorithm_id].automaton_stats[0].emptiness_check_result; - const Bitset& acceptance_vector_for_negation - = test_results[algorithm_id].automaton_stats[1].emptiness_check_result; - - if (printText("Result consistency check:\n", 3, 6)) - printText("", 4, 8); - - /* - * The consistency check will succeed if `result' is still true at the end - * of the following loop. - * - * The consistency check fails if there is a state in which both the - * formula and its negation are claimed to be false. - */ - - final_statistics[algorithm_id].consistency_checks_performed++; - - for (state = 0; state < round_info.real_emptiness_check_size; ++state) - { - ++test_results[algorithm_id].consistency_check_comparisons; - if (!acceptance_vector_for_formula[state] - && !acceptance_vector_for_negation[state]) - { - ++test_results[algorithm_id].failed_consistency_check_comparisons; - result = false; - } - } - - test_results[algorithm_id].consistency_check_result = (result ? 1 : 0); - } - else - result = (test_results[algorithm_id].consistency_check_result == 1); - - if (!result) - { - round_info.error = true; - - if (round_info.transcript_file.is_open()) - writeToTranscript("Model checking result consistency check failed (" - + configuration.algorithmString(algorithm_id) + ")\n"); - - final_statistics[algorithm_id].consistency_check_failures++; - } - - printText((result ? " ok\n" : " failed\n"), 4); - - if (configuration.global_options.verbosity >= 2) - printConsistencyCheckStats(cout, 8, algorithm_id); -} - -/* ========================================================================= */ -void compareResults() -/* ---------------------------------------------------------------------------- - * - * Description: Compares the model checking results obtained using different - * LTL->Büchi conversion algorithm implementations with each - * other. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - if (printText("Model checking result cross-comparison:\n", 3, 4)) - printText("", 4, 6); - else - printText("Comparing model checking results", 2, 4); - - bool result = true; - AutomatonStats* alg_1_stats; - AutomatonStats* alg_2_stats; - - for (vector::size_type alg_1 = 0; - alg_1 < test_results.size(); - ++alg_1) - { - for (int counter = 0; counter < 2; counter++) - { - alg_1_stats = &test_results[alg_1].automaton_stats[counter]; - - for (vector::size_type alg_2 = alg_1 + 1; - alg_2 < test_results.size(); - ++alg_2) - { - alg_2_stats = &test_results[alg_2].automaton_stats[counter]; - - if (configuration.algorithms[alg_1].enabled - && configuration.algorithms[alg_2].enabled - && alg_1_stats->emptiness_check_performed - && alg_2_stats->emptiness_check_performed) - { - if (!alg_1_stats->cross_comparison_stats[alg_2].first) - { - (final_statistics[alg_1].cross_comparisons_performed[alg_2])++; - (final_statistics[alg_2].cross_comparisons_performed[alg_1])++; - - unsigned long int dist - = alg_1_stats->emptiness_check_result.hammingDistance - (alg_2_stats->emptiness_check_result); - - alg_1_stats->cross_comparison_stats[alg_2].first - = alg_2_stats->cross_comparison_stats[alg_1].first - = true; - - alg_1_stats->cross_comparison_stats[alg_2].second - = alg_2_stats->cross_comparison_stats[alg_1].second - = dist; - - if (dist > 0) - { - (final_statistics[alg_1].cross_comparison_mismatches[alg_2])++; - (final_statistics[alg_2].cross_comparison_mismatches[alg_1])++; - - if (alg_1_stats->emptiness_check_result[0] - != alg_2_stats->emptiness_check_result[0]) - { - (final_statistics[alg_1]. - initial_cross_comparison_mismatches[alg_2])++; - (final_statistics[alg_2]. - initial_cross_comparison_mismatches[alg_1])++; - } - - result = false; - } - } - else if (alg_1_stats->cross_comparison_stats[alg_2].second != 0) - result = false; - } - } - } - } - - IntervalList algorithms; - algorithms.merge(0, round_info.number_of_translators - 1); - - if (!result) - { - round_info.error = true; - - if (round_info.transcript_file.is_open()) - { - writeToTranscript("Model checking result cross-comparison check failed"); - printCrossComparisonStats(round_info.transcript_file, 8, - algorithms); - } - } - - printText((result ? " ok\n" : " failed\n"), 4); - if (configuration.global_options.verbosity == 2) - { - if (!result) - round_info.cout << " [failed]"; - round_info.cout << '\n'; - round_info.cout.flush(); - } - else if (configuration.global_options.verbosity >= 3) - printCrossComparisonStats(cout, 6, algorithms); -} - -/* ========================================================================= */ -void performBuchiIntersectionCheck() -/* ---------------------------------------------------------------------------- - * - * Description: Tests the intersection of the Büchi automata constructed for - * the formula and its negation for emptiness. - * - * Arguments: None. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - if (printText("Büchi automata intersection emptiness check:\n", 3, 4)) - printText("\n", 4, 6); - else - printText("Checking Büchi automata intersections for emptiness", 2, 4); - - bool result = true; - - ::Graph::BuchiProduct::clearSatisfiabilityCache(); - - for (vector::size_type alg_1 = 0; - alg_1 < round_info.number_of_translators; - ++alg_1) - { - for (vector::size_type alg_2 = 0; - alg_2 < round_info.number_of_translators; - ++alg_2) - { - if (configuration.isInternalAlgorithm(alg_1) - || configuration.isInternalAlgorithm(alg_2)) - continue; - - try - { - if (test_results[alg_1].automaton_stats[0]. - buchi_intersection_check_stats[alg_2] == -1) - { - printText("(+) " + configuration.algorithmString(alg_1) + ", (-) " - + configuration.algorithmString(alg_2), - 4, - 8); - - /* - * Compute the intersection of two Büchi automata constructed for - * the positive and the negative formula, respectively. - */ - - if (test_results[alg_1].automaton_stats[0].buchiAutomatonComputed() - && test_results[alg_2].automaton_stats[1]. - buchiAutomatonComputed()) - { - using ::Graph::BuchiAutomaton; - using ::Graph::BuchiProduct; - using ::Graph::Product; - - /* - * Scan the nontrivial maximal strongly connected components of - * the intersection automaton to check whether the automaton has - * any accepting executions. If an MSCC with a state from every - * acceptance set is found, the intersection emptiness check - * fails. - */ - - const BuchiAutomaton& a1 - = *(test_results[alg_1].automaton_stats[0].buchi_automaton); - const BuchiAutomaton& a2 - = *(test_results[alg_2].automaton_stats[1].buchi_automaton); - - Product product(a1, a2); - - if (!product.localEmptinessCheck(a1.initialState(), - a2.initialState())) - { - test_results[alg_1].automaton_stats[0]. - buchi_intersection_check_stats[alg_2] = 1; - test_results[alg_2].automaton_stats[1]. - buchi_intersection_check_stats[alg_1] = 1; - - printText(": ok\n", 4); - } - else - { - test_results[alg_1].automaton_stats[0]. - buchi_intersection_check_stats[alg_2] = 0; - test_results[alg_2].automaton_stats[1]. - buchi_intersection_check_stats[alg_1] = 0; - - final_statistics[alg_1] - .buchi_intersection_check_failures[alg_2]++; - if (alg_1 != alg_2) - final_statistics[alg_2] - .buchi_intersection_check_failures[alg_1]++; - - result = false; - - printText(": failed\n", 4); - } - - final_statistics[alg_1]. - buchi_intersection_checks_performed[alg_2]++; - if (alg_1 != alg_2) - final_statistics[alg_2]. - buchi_intersection_checks_performed[alg_1]++; - } - else - printText(": not performed\n", 4); - } - else if (test_results[alg_1].automaton_stats[0]. - buchi_intersection_check_stats[alg_2] == 0) - result = false; - } - catch (const UserBreakException&) - { - if (!printText(": aborted (user break)", 4)) - printText(" [User break]", 2, 6); - printText("\n\n", 2); - - if (round_info.transcript_file.is_open()) - { - writeToTranscript("User break during Büchi automata intersection " - "emptiness check"); - round_info.transcript_file << string(8, ' ') + "(+) " - + configuration.algorithmString(alg_1) - + ", (-) " - + configuration.algorithmString(alg_2) - + "\n\n"; - } - - throw; - } - catch (const ::Graph::Product< ::Graph::BuchiProduct>::SizeException&) - { - if (!printText(": aborted (product may be too large)", 4)) - printText(" [Product may be too large: (+) " - + configuration.algorithmString(alg_1) - + ", (-) " - + configuration.algorithmString(alg_2) - + "]", - 2, - 6); - printText("\n", 2); - - if (round_info.transcript_file.is_open()) - { - writeToTranscript("Automata intersection emptiness check aborted " - "(product may be too large)"); - round_info.transcript_file << string(8, ' ') + "(+) " - + configuration.algorithmString(alg_1) - + ", (-) " - + configuration.algorithmString(alg_2) - + "\n\n"; - } - } - catch (const bad_alloc&) - { - if (!printText(": aborted (out of memory)", 4)) - printText(" [Out of memory: (+) " - + configuration.algorithmString(alg_1) - + ", (-) " - + configuration.algorithmString(alg_2) - + "]", - 2, - 6); - printText("\n", 2); - - if (round_info.transcript_file.is_open()) - { - writeToTranscript("Out of memory during Büchi automata " - "intersection emptiness check"); - round_info.transcript_file << string(8, ' ') + "(+) " - + configuration.algorithmString(alg_1) - + ", (-) " - + configuration.algorithmString(alg_2) - + "\n\n"; - } - } - } - } - - IntervalList algorithms; - algorithms.merge(0, round_info.number_of_translators - 1); - - if (!result) - { - round_info.error = true; - - if (round_info.transcript_file.is_open()) - { - writeToTranscript("Büchi automata intersection emptiness check failed"); - printBuchiIntersectionCheckStats - (round_info.transcript_file, 8, algorithms); - round_info.transcript_file << '\n'; - } - - if (configuration.global_options.verbosity == 2) - round_info.cout << " [failed]"; - } - - if (configuration.global_options.verbosity == 2) - { - round_info.cout << '\n'; - round_info.cout.flush(); - } - else if (configuration.global_options.verbosity >= 3) - { - printBuchiIntersectionCheckStats(cout, 6, algorithms); - round_info.cout << '\n'; - round_info.cout.flush(); - } -} - -} - - - -/****************************************************************************** - * - * Definitions for static members for specializations of the Product template. - * - *****************************************************************************/ - -namespace Graph -{ - -template <> -Product* Product::product = 0; - -template <> -Product* Product::product = 0; - -} diff --git a/lbtt/src/TestOperations.h b/lbtt/src/TestOperations.h deleted file mode 100644 index a7a6ed0bc..000000000 --- a/lbtt/src/TestOperations.h +++ /dev/null @@ -1,534 +0,0 @@ -/* -*- coding: utf-8 -*- - * - * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 - * Heikki Tauriainen - * - * 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 -#include -#include -#include -#include -#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 /* 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 /* automaton. */ - ::size_type - algorithm_id); - -void performConsistencyCheck /* Performs a */ - (vector /* 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 */ diff --git a/lbtt/src/TestRoundInfo.h b/lbtt/src/TestRoundInfo.h deleted file mode 100644 index 8b396b9d7..000000000 --- a/lbtt/src/TestRoundInfo.h +++ /dev/null @@ -1,251 +0,0 @@ -/* - * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 - * Heikki Tauriainen - * - * 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 -#include -#include -#include -#include -#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 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 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(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 */ diff --git a/lbtt/src/TestStatistics.cc b/lbtt/src/TestStatistics.cc deleted file mode 100644 index 55663b7c1..000000000 --- a/lbtt/src/TestStatistics.cc +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 - * Heikki Tauriainen - * - * 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 -#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::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::iterator it - = automaton_stats[i].buchi_intersection_check_stats.begin(); - it != automaton_stats[i].buchi_intersection_check_stats.end(); - ++it) - *it = -1; - } -} diff --git a/lbtt/src/TestStatistics.h b/lbtt/src/TestStatistics.h deleted file mode 100644 index 5bb19c108..000000000 --- a/lbtt/src/TestStatistics.h +++ /dev/null @@ -1,581 +0,0 @@ -/* - * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 - * Heikki Tauriainen - * - * 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 -#include -#include -#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 - ::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::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 - CrossComparisonStats; - - vector /* 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 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 - ::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 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::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 /* Number of failed */ - cross_comparison_mismatches; /* result cross- - * comparisons. - */ - - vector /* Number of failed */ - initial_cross_comparison_mismatches; /* result cross- - * comparisons in the - * initial state of the - * state space. - */ - - vector /* Number of result */ - cross_comparisons_performed; /* cross-comparisons - * performed. - */ - - vector /* 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 /* 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::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::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::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 */ diff --git a/lbtt/src/TranslatorInterface.h b/lbtt/src/TranslatorInterface.h deleted file mode 100644 index eca8e172d..000000000 --- a/lbtt/src/TranslatorInterface.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 - * Heikki Tauriainen - * - * 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 -#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 */ diff --git a/lbtt/src/UserCommandReader.cc b/lbtt/src/UserCommandReader.cc deleted file mode 100644 index b6ee0ddf0..000000000 --- a/lbtt/src/UserCommandReader.cc +++ /dev/null @@ -1,940 +0,0 @@ -/* - * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 - * Heikki Tauriainen - * - * 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 -#include -#include -#include -#include -#ifdef HAVE_SSTREAM -#include -#else -#include -#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 -#include -#include -#include -#include -#endif /* HAVE_READLINE */ - -#ifdef HAVE_ISATTY -#ifdef HAVE_UNISTD_H -#include -#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 input_tokens; - TokenType token; - - bool formula_type = true; - - pair 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(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(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::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& command, vector::size_type min_arg_count, - vector::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 parseRedirection(vector& 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& 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) + ")."); -} - -} diff --git a/lbtt/src/UserCommandReader.h b/lbtt/src/UserCommandReader.h deleted file mode 100644 index b9a510519..000000000 --- a/lbtt/src/UserCommandReader.h +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 - * Heikki Tauriainen - * - * 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 -#include -#include -#include -#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& arguments, /* number of arguments */ - vector::size_type min_arg_count, /* for a command is */ - vector::size_type max_arg_count); /* within given limits. */ - -pair parseRedirection /* Checks whether an */ - (vector& input_tokens); /* user command given - * will require - * redirecting its - * output to a file. - */ - -bool parseFormulaType /* Checks whether an */ - (vector& 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 */ diff --git a/lbtt/src/UserCommands.cc b/lbtt/src/UserCommands.cc deleted file mode 100644 index 08980d028..000000000 --- a/lbtt/src/UserCommands.cc +++ /dev/null @@ -1,2019 +0,0 @@ -/* - * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 - * Heikki Tauriainen - * - * 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 -#include "BuchiProduct.h" -#include "DispUtil.h" -#include "Exception.h" -#include "PathEvaluator.h" -#include "Product.h" -#include "SharedTestData.h" -#include "StatDisplay.h" -#include "StateSpaceProduct.h" -#include "StringUtil.h" -#include "TestRoundInfo.h" -#include "TestStatistics.h" -#include "UserCommandReader.h" -#include "UserCommands.h" - -/****************************************************************************** - * - * Implementations for the user commands. - * - *****************************************************************************/ - -namespace UserCommands -{ - -using namespace ::DispUtil; -using namespace ::SharedTestData; -using namespace ::StatDisplay; -using namespace ::StringUtil; -using namespace ::UserCommandInterface; - -/* ========================================================================= */ -unsigned long int parseAlgorithmId(const string& id) -/* ---------------------------------------------------------------------------- - * - * Description: Parses an algorithm identifier (either a symbolic or a - * numeric one). - * - * Argument: id -- String containing the identifier. - * - * Returns: The numeric identifier of the algorithm. Throws a - * CommandErrorException if the identifier is not recognizable - * as a proper algorithm identifier. - * - * ------------------------------------------------------------------------- */ -{ - unsigned long int result; - string unquoted_id = unquoteString(id); - - try - { - result = parseNumber(unquoted_id); - verifyNumber(result, round_info.number_of_translators, - "Implementation identifier out of range"); - } - catch (const NotANumberException&) - { - map::const_iterator id_finder - = configuration.algorithm_names.find(unquoted_id); - if (id_finder == configuration.algorithm_names.end()) - throw CommandErrorException - ("Unknown implementation identifier (`" + unquoted_id + "')."); - result = id_finder->second; - } - - return result; -} - -/* ========================================================================= */ -void parseAlgorithmIdList(const string& ids, IntervalList& algorithms) -/* ---------------------------------------------------------------------------- - * - * Description: Parses a list of algorithm identifiers specified either as - * comma-separated intervals or algorithm identifiers. - * - * Arguments: ids -- A constant reference to a string containing - * the list of algorithm identifiers. - * algorithms -- A reference to an IntervalList for storing - * the numeric identifiers of the algorithms. - * - * Returns: Nothing. Throws a CommandErrorException if the identifier - * list includes a string not recognizable as an algorithm - * identifier. - * - * ------------------------------------------------------------------------- */ -{ - /* - * Make a copy of `ids' in which each comma (',') within double quotes is - * substituted with a newline. This is necessary to handle symbolic - * algorithm identifiers with commas correctly. - */ - - string id_string = substituteInQuotedString(ids, ",", "\n", INSIDE_QUOTES); - - try - { - vector nonnumeric_algorithm_ids; - - parseIntervalList(id_string, algorithms, 0, - round_info.number_of_translators - 1, - &nonnumeric_algorithm_ids); - - for (vector::iterator id = nonnumeric_algorithm_ids.begin(); - id != nonnumeric_algorithm_ids.end(); - ++id) - { - *id = unquoteString(substituteInQuotedString(*id, "\n", ",")); - map::const_iterator - id_finder = configuration.algorithm_names.find(*id); - if (id_finder == configuration.algorithm_names.end()) - throw CommandErrorException - ("Unknown implementation identifier (`" + *id + "')."); - algorithms.merge(id_finder->second); - } - } - catch (const IntervalRangeException& e) - { - throw CommandErrorException - (string("Implementation identifier out of range (") - + toString(e.getNumber()) - + ")."); - } -} - -/* ========================================================================= */ -void printAlgorithmList(ostream& stream, int indent) -/* ---------------------------------------------------------------------------- - * - * Description: Implements the user command `algorithms', i.e., writes a list - * of algorithms used in the tests to a stream. - * - * Arguments: stream -- A reference to an output stream. - * indent -- Number of spaces to leave on the left of the - * output. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - Exceptional_ostream estream(&stream, ios::badbit | ios::failbit); - - estream << string(indent, ' ') + "List of implementations:\n"; - - for (unsigned long int algorithm_id = 0; - algorithm_id < round_info.number_of_translators; - ++algorithm_id) - { - estream << string(indent + 2, ' ') - + configuration.algorithmString(algorithm_id) - + " (" - + (configuration.algorithms[algorithm_id].enabled - ? "en" - : "dis") - + "abled)\n"; - } - - estream.flush(); -} - -/* ========================================================================= */ -void printCrossComparisonAnalysisResults - (ostream& stream, int indent, bool formula_type, - const vector& input_tokens) -/* ---------------------------------------------------------------------------- - * - * Description: Implements the user command `resultanalysis', i.e., analyzes - * a discrepancy between the results of two algorithms (or one - * algorithm against the path algorithm) by searching for a - * system execution producting contradicting results and then - * displaying the execution. - * - * Arguments: stream -- A reference to an output stream. - * indent -- Number of spaces to leave on the - * left of the output. - * formula_type -- Tells the LTL formula for which - * the analysis is to be performed. - * input_tokens -- A reference to a vector - * containing the arguments of the - * command. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - Exceptional_ostream estream(&stream, ios::badbit | ios::failbit); - - unsigned long int algorithm1, algorithm2; - bool path_compare = false; - - if (!configuration.global_options.do_comp_test) - throw CommandErrorException("This command is available only when the " - "model checking result cross-comparison test " - "is enabled."); - - algorithm1 = parseAlgorithmId(input_tokens[1]); - algorithm2 = parseAlgorithmId(input_tokens[2]); - - if (algorithm1 == algorithm2) - throw CommandErrorException("Implementation identifiers must be " - "different."); - - /* - * Arrange the algorithm identifiers such that `algorithm1' never refers to - * the internal model checking algorithm (swap `algorithm1' and `algorithm2' - * if necessary). - */ - - if (configuration.isInternalAlgorithm(algorithm1)) - { - path_compare = true; - algorithm1 ^= algorithm2; - algorithm2 ^= algorithm1; - algorithm1 ^= algorithm2; - } - - if (configuration.isInternalAlgorithm(algorithm2)) - path_compare = true; - - if (path_compare - && !(configuration.global_options.statespace_generation_mode - & Configuration::PATH)) - throw CommandErrorException("This feature is available only when using " - "paths as state spaces."); - - int formula = (formula_type ? 0 : 1); - int generator_formula = formula; - - if (configuration.formula_options.output_mode != Configuration::NNF) - generator_formula += 2; - - const AutomatonStats* stats1; - const AutomatonStats* stats2; - - stats1 = &test_results[algorithm1].automaton_stats[formula]; - stats2 = &test_results[algorithm2].automaton_stats[formula]; - - if (!stats1->crossComparisonPerformed(algorithm2)) - { - printTextBlock(stream, indent, - "Model checking result cross-comparison was not " - "performed between " - + configuration.algorithmString(algorithm1) - + " and " + configuration.algorithmString(algorithm2) - + ".", - 78); - return; - } - - if (stats1->cross_comparison_stats[algorithm2].second == 0) - { - printTextBlock(stream, indent, - "No inconsistencies detected in the cross-comparison of " - "results given by " - + configuration.algorithmString(algorithm1) - + " and " - + configuration.algorithmString(algorithm2) + ".", - 78); - return; - } - - estream << string(indent, ' ') - + "Model checking result cross-comparison analysis:\n" - + string(indent + 2, ' ') + "Formula: " - << *round_info.formulae[generator_formula] - << "\n\n"; - - StateSpace::size_type state; - - if (input_tokens.size() == 3) - { - /* - * If no state identifier was given as a command argument, search for a - * system state in which the results of the two algorithms (or the result - * of an algorithm and the path checking algorithm) differ. - */ - - estream << string(indent + 2, ' ') + "The cross-comparison check failed " - "in " - + toString(stats1->cross_comparison_stats[algorithm2].second) - + " ("; - - changeStreamFormatting(stream, 0, 2, ios::fixed); - estream << static_cast - (stats1->cross_comparison_stats[algorithm2].second) - / round_info.real_emptiness_check_size - * 100.0; - restoreStreamFormatting(stream); - - estream << "%) of " + toString(round_info.real_emptiness_check_size) - + " test cases.\n\n"; - - for (state = 0; - stats1->emptiness_check_result[state] - == stats2->emptiness_check_result[state]; - ++state) - ; - } - else - { - /* - * Otherwise use the state given as the command argument. - */ - - state = parseNumber(input_tokens[3]); - - verifyNumber(state, round_info.statespace->size(), - "State identifier out of range"); - - if (state >= round_info.real_emptiness_check_size) - { - printTextBlock(stream, indent, - "Model checking result cross-comparison test was not " - "performed between " - + configuration.algorithmString(algorithm1) - + " and " - + configuration.algorithmString(algorithm2) - + " in state " - + toString(state) - + " of the state space.", - 78); - return; - } - - if (stats1->emptiness_check_result[state] - == stats2->emptiness_check_result[state]) - { - printTextBlock(stream, indent, - "No inconsistency detected between the results given by " - + configuration.algorithmString(algorithm1) - + " and " - + configuration.algorithmString(algorithm2) - + " in state " - + toString(state) - + " of the state space.", - 78); - return; - } - } - - /* - * Translate the formula to be analyzed into a Büchi automaton using the - * algorithm that claims the existence of an accepting cycle beginning in - * the state. - */ - - unsigned long int accepting_algorithm - = (stats1->emptiness_check_result[state] ? algorithm1 : algorithm2); - - unsigned long int rejecting_algorithm = (accepting_algorithm == algorithm1 - ? algorithm2 - : algorithm1); - - ::Graph::Product::Witness witness; - - if (!path_compare || accepting_algorithm == algorithm1) - { - /* - * Search the product automaton for an accepting cycle. - */ - - const BuchiAutomaton& automaton - = *test_results[accepting_algorithm].automaton_stats[formula] - .buchi_automaton; - - ::Graph::Product product - (automaton, *round_info.statespace); - - try - { - printText("", 0, 2); - - product.findWitness(automaton.initialState(), state, witness); - - if (witness.cycle.first.empty()) - throw Exception - ("UserCommands::printCrossComparisonAnalysisResults(...): internal " - "error [witness construction failed]"); - } - catch (const UserBreakException&) - { - printText(" user break\n", 0); - throw; - } - catch (...) - { - printText(" error\n", 0); - throw; - } - - printText(" ok\n\n", 0); - } - else - { - const StateSpace::size_type loop_state - = (*((*round_info.statespace)[round_info.statespace->size() - 1]. - edges().begin()))->targetNode(); - const StateSpace::size_type loop_length - = round_info.statespace->size() - loop_state; - - for ( ; state < loop_state; ++state) - witness.prefix.second.push_back(StateSpace::PathElement(state, 0)); - - state -= loop_state; - for (StateSpace::size_type s = 0; s < loop_length; ++s) - { - witness.cycle.second.push_back - (StateSpace::PathElement(state + loop_state, 0)); - state = (state + 1) % loop_length; - } - } - - /* - * Write information about the execution to the output stream. That is, - * display the states in the infinite execution (a prefix and a cycle) - * and tell which one of the algorithms would accept and which one - * would reject the execution (or show whether the algorithm compared - * against the path checking algorithm accepted or rejected the - * execution). - */ - - estream << string(indent + 2, ' ') + "Execution M:\n"; - - printPath(stream, indent + 4, witness.prefix.second, witness.cycle.second, - *(round_info.statespace)); - - estream << string(indent + 4, ' ') - + "accepted by: " - + configuration.algorithmString(accepting_algorithm) + '\n' - + string(indent + 4, ' ') + "rejected by: " - + configuration.algorithmString(rejecting_algorithm) - + "\n\n" - + string(indent + 2, ' ') - + "Analysis of the formula in the execution:\n"; - - /* - * Model check the formula separately in the obtained execution to find out - * which one of the algorithms was in error. - */ - - Ltl::PathEvaluator path_evaluator; - bool result = path_evaluator.evaluate - (*round_info.formulae[generator_formula], witness.prefix.second, - witness.cycle.second, *round_info.statespace); - - path_evaluator.print(stream, indent + 4); - - printTextBlock(stream, indent + 2, - string(" \n The formula is ") + (result ? "" : "not ") - + "satisfied in the execution, which should therefore be " - + (result ? "accep" : "rejec") - + "ted by all Büchi automata that represent the formula " - "correctly. This suggests an error in implementation " - + (path_compare - ? configuration.algorithmString(algorithm1) - : configuration.algorithmString(result - ? rejecting_algorithm - : accepting_algorithm)) - + ".", - 78); - - if (!result) - { - estream << '\n'; - printAcceptingCycle(stream, indent + 2, accepting_algorithm, - witness.prefix.first, witness.cycle.first, - *(test_results[accepting_algorithm]. - automaton_stats[formula].buchi_automaton), - witness.prefix.second, witness.cycle.second, - *round_info.statespace); - } -} - -/* ========================================================================= */ -void printConsistencyAnalysisResults - (ostream& stream, int indent, const vector& input_tokens) -/* ---------------------------------------------------------------------------- - * - * Description: Implements the user command `consistencyanalysis', i.e., - * analyzes a discrepancy detected in the model checking result - * consistency check for an implementation. - * - * Arguments: stream -- A reference to an output stream. - * indent -- Number of spaces to leave on the left of - * the output. - * input_tokens -- A reference to a vector containing the - * arguments of the command. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - Exceptional_ostream estream(&stream, ios::badbit | ios::failbit); - - if (!configuration.global_options.do_cons_test) - throw CommandErrorException("This command is available only when the " - "model checking result consistency check is " - "enabled."); - - unsigned long int algorithm_id = parseAlgorithmId(input_tokens[1]); - - if (test_results[algorithm_id].consistency_check_result == -1) - { - printTextBlock(stream, indent, - "Model checking result consistency check was not performed " - "on implementation " - + configuration.algorithmString(algorithm_id) - + ".", - 78); - return; - } - - if (test_results[algorithm_id].consistency_check_result == 1) - { - printTextBlock(stream, indent, - "Implementation " - + configuration.algorithmString(algorithm_id) - + " passed the model checking result consistency check.", - 78); - return; - } - - StateSpace::size_type state; - int formula = (configuration.formula_options.output_mode - == Configuration::NNF - ? 0 - : 2); - - estream << string(indent, ' ') + "Consistency check result analysis:\n" - + string(indent + 2, ' ') + "Implementation: " - + configuration.algorithmString(algorithm_id) + '\n' - + string(indent + 2, ' ') + "Positive formula: " - << *round_info.formulae[formula] - << "\n\n"; - - if (input_tokens.size() == 2) - { - /* - * If no state identifier was given as a parameter, search for a state in - * which the consistency check failed. - */ - - for (state = 0; - test_results[algorithm_id].automaton_stats[0]. - emptiness_check_result.test(state) - || test_results[algorithm_id].automaton_stats[1]. - emptiness_check_result.test(state); - ++state) - ; - } - else - { - /* - * Otherwise use the state given as a parameter for the command. - */ - - state = parseNumber(input_tokens[2]); - verifyNumber(state, round_info.statespace->size(), - "State identifier out of range"); - - if (state >= round_info.real_emptiness_check_size) - { - printTextBlock(stream, indent, - "Model checking result consistency check was not " - "performed on implementation " - + configuration.algorithmString(algorithm_id) - + " in state " + toString(state) + " of the state " - "space.", - 78); - return; - } - if (test_results[algorithm_id].automaton_stats[0]. - emptiness_check_result.test(state) - || test_results[algorithm_id].automaton_stats[1]. - emptiness_check_result.test(state)) - { - printTextBlock(stream, indent, - "No discrepancy detected in the model checking result " - "consistency check on implementation " - + configuration.algorithmString(algorithm_id) - + " in state " + toString(state) + " of the state " - "space.", - 78); - return; - } - } - - vector path; - StateSpace::Path prefix, cycle; - map ordering; - StateSpace::size_type state_count = 0; - StateSpace::size_type loop_state; - - /* - * Construct a vector of state identifiers representing a path by - * traversing the state space until some state is encountered twice. - */ - - while (1) - { - path.push_back(state); - ordering[state] = state_count; - state_count++; - - state = (*((*round_info.statespace)[state].edges().begin()))->targetNode(); - - if (ordering.find(state) != ordering.end()) - break; - } - - loop_state = ordering[state]; - - for (StateSpace::size_type s = 0; s < loop_state; s++) - prefix.push_back(StateSpace::PathElement(path[s], 0)); - - for (StateSpace::size_type s = loop_state; s < path.size(); s++) - cycle.push_back(StateSpace::PathElement(path[s], 0)); - - estream << string(indent + 2, ' ') + "Execution M:\n"; - printPath(stream, indent + 4, prefix, cycle, *(round_info.statespace)); - - estream << '\n' + string(indent + 2, ' ') - + "Analysis of the formula in the execution:\n"; - - Ltl::PathEvaluator path_evaluator; - bool result = path_evaluator.evaluate - (*round_info.formulae[formula], prefix, cycle, *round_info.statespace); - - path_evaluator.print(stream, indent + 4); - - printTextBlock(stream, indent + 2, - string(" \n The formula is ") + (result ? "" : "not ") - + "satisfied in the execution. It seems that the automaton " - "constructed for the " - + (result ? "posi" : "nega") - + "tive formula rejects the execution incorrectly.", - 78); -} - -/* ========================================================================= */ -void printAutomatonAnalysisResults - (ostream& stream, int indent, const vector& input_tokens) -/* ---------------------------------------------------------------------------- - * - * Description: Implements the user command `buchianalysis', i.e., analyzes - * an inconsistency detected in the intersection emptiness check - * for two Büchi automata constructed for the formula and its - * negation. - * - * Arguments: stream -- A reference to an output stream. - * indent -- Number of spaces to leave on the left of - * the output. - * input_tokens -- A reference to a vector containing the - * arguments of the command. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - Exceptional_ostream estream(&stream, ios::badbit | ios::failbit); - - if (!configuration.global_options.do_intr_test) - throw CommandErrorException("This command is available only when the " - "Büchi automata intersection emptiness check " - "is enabled."); - - unsigned long int algorithm1 = parseAlgorithmId(input_tokens[1]); - unsigned long int algorithm2 = parseAlgorithmId(input_tokens[2]); - - if (configuration.isInternalAlgorithm(algorithm1) - || configuration.isInternalAlgorithm(algorithm2)) - throw CommandErrorException - ("This feature is not available for lbtt's internal " - "model checking algorithm."); - - int test_result - = test_results[algorithm1].automaton_stats[0]. - buchi_intersection_check_stats[algorithm2]; - - if (test_result != 0) - { - printTextBlock(stream, indent, - string("The automata intersection check was ") - + (test_result == -1 ? "not performed" : "successful") + ' ' - + (algorithm1 == algorithm2 ? "o" : "betwee") - + "n implementation" - + (algorithm1 == algorithm2 ? "" : "s") + ' ' - + configuration.algorithmString(algorithm1) - + (algorithm1 == algorithm2 - ? "" - : " (positive formula) and " - + configuration.algorithmString(algorithm2) - + " (negative formula)") - + ".", - 78); - - return; - } - - int formula - = (configuration.formula_options.output_mode == Configuration::NNF - ? 0 - : 2); - - estream << string(indent, ' ') - + "Automata intersection emptiness check analysis:\n" - + string(indent + 2, ' ') + "Positive formula: "; - - round_info.formulae[formula]->print(estream); - - estream << '\n' + string(indent + 2, ' ') + "Negative formula: "; - round_info.formulae[formula + 1]->print(estream); - - estream << '\n' + string(indent + 2, ' ') + "Implementation" - + (algorithm1 != algorithm2 ? "s:" : ": ") + " " - + configuration.algorithmString(algorithm1); - - if (algorithm1 != algorithm2) - estream << " (positive formula)\n" + string(indent + 20, ' ') - + configuration.algorithmString(algorithm2) - + " (negative formula)"; - - estream << "\n\n"; - estream.flush(); - - ::Graph::Product::Witness witness; - - try - { - printText("", 0, 2); - - const BuchiAutomaton& automaton_1 - = *(test_results[algorithm1].automaton_stats[0].buchi_automaton); - const BuchiAutomaton& automaton_2 - = *(test_results[algorithm2].automaton_stats[1].buchi_automaton); - - ::Graph::Product product(automaton_1, automaton_2); - product.findWitness(automaton_1.initialState(), automaton_2.initialState(), - witness); - - if (witness.cycle.first.empty()) - throw Exception - ("UserCommands::printAutomatonAnalysisResults(...): internal error " - "[witness construction failed]"); - } - catch (const UserBreakException&) - { - printText(" user break\n", 0); - throw; - } - catch (...) - { - printText(" error\n", 0); - throw; - } - - printText(" ok\n", 0); - - const unsigned long int valuation_size - = configuration.formula_options.formula_generator - .number_of_available_variables; - const StateSpace::size_type path_length - = witness.prefix.first.size() + witness.cycle.first.size(); - StateSpace path(valuation_size, path_length); - - StateSpace::size_type state = 0; - StateSpace::Path::const_iterator p1, p2; - StateSpace::Path path_prefix, path_cycle; - - for (int i = 0; i < 2; ++i) - { - const pair* witness_segment; - StateSpace::Path* path_segment; - - if (i == 0) - { - witness_segment = &witness.prefix; - path_segment = &path_prefix; - } - else - { - witness_segment = &witness.cycle; - path_segment = &path_cycle; - } - - for (p1 = witness_segment->first.begin(), - p2 = witness_segment->second.begin(); - p1 != witness_segment->first.end(); - ++p1, ++p2, ++state) - { - ::Ltl::LtlFormula* f - = &::Ltl::And::construct - (static_cast(p1->edge()) - .guard(), - static_cast(p2->edge()) - .guard()); - - path[state].positiveAtoms().copy - (f->findPropositionalModel(valuation_size - 1), valuation_size); - - path_segment->push_back(StateSpace::PathElement(state, 0)); - - ::Ltl::LtlFormula::destruct(f); - } - } - - /* - * Display the input sequence accepted by both automata. - */ - - estream << string(indent + 2, ' ') - + "Execution M accepted by both automata:\n"; - - printPath(stream, indent + 4, path_prefix, path_cycle, path); - - estream << '\n'; - - /* - * For each of the original automata, display the accepting runs that - * these automata have on the input sequence. - */ - - for (int i = 0; i < 2; ++i) - { - const BuchiAutomaton::Path* prefix; - const BuchiAutomaton::Path* cycle; - - if (i == 0) - { - prefix = &witness.prefix.first; - cycle = &witness.cycle.first; - } - else - { - prefix = &witness.prefix.second; - cycle = &witness.cycle.second; - } - - printAcceptingCycle(stream, indent + 2, (i == 0 ? algorithm1 : algorithm2), - *prefix, *cycle, - *(test_results[i == 0 ? algorithm1 : algorithm2] - .automaton_stats[i].buchi_automaton), - path_prefix, path_cycle, path); - - estream << '\n'; - } - - /* - * Display a proof or a refutation for the formula in the execution. - */ - - estream << string(indent + 2, ' ') - + "Analysis of the positive formula in the execution M:\n"; - - Ltl::PathEvaluator path_evaluator; - bool result = path_evaluator.evaluate(*round_info.formulae[formula], - path_prefix, path_cycle, path); - - path_evaluator.print(stream, indent + 4); - - printTextBlock(stream, indent + 2, - " \n The positive formula is " + string(result ? "" : "not ") - + "satisfied in the execution. This suggests that the " - "Büchi automaton constructed for the " - + (result ? "nega" : "posi") + "tive formula " - + (algorithm1 == algorithm2 - ? "" - : "(the automaton constructed by implementation " - + configuration.algorithmString(result ? algorithm2 - : algorithm1) - + ") ") - + "is incorrect.", - 78); -} - -/* ========================================================================= */ -void printPath - (ostream& stream, int indent, const StateSpace::Path& prefix, - const StateSpace::Path& cycle, const StateSpace& path) -/* ---------------------------------------------------------------------------- - * - * Description: Writes information about a path in a state space to a stream. - * - * Arguments: stream -- A reference to an output stream. - * indent -- Number of spaces to leave to the left of output. - * prefix -- The prefix of the path. - * cycle -- The cycle of the path. - * path -- The state space to which the state identifiers in - * the prefix and the cycle refer. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - Exceptional_ostream estream(&stream, ios::badbit | ios::failbit); - - const StateSpace::Path* path_segment; - - for (int i = 0; i < 2; ++i) - { - if (i == 0 && prefix.empty()) - continue; - - estream << string(indent, ' '); - if (i == 0) - { - path_segment = &prefix; - estream << "prefix"; - } - else - { - path_segment = &cycle; - estream << "cycle"; - } - estream << ":\n"; - - bool first_printed; - - for (StateSpace::Path::const_iterator path_element = path_segment->begin(); - path_element != path_segment->end(); - ++path_element) - { - if (path_element != path_segment->begin()) - estream << toString(path_element->node()) + "\n"; - estream << string(indent + 2, ' ') + 's' + toString(path_element->node()) - + " {"; - - first_printed = false; - for (unsigned long int proposition = 0; - proposition < path.numberOfPropositions(); - ++proposition) - { - if (path[path_element->node()].positiveAtoms().test(proposition)) - { - if (first_printed) - estream << ','; - else - first_printed = true; - - estream << 'p' + toString(proposition); - } - } - - estream << "} --> s"; - } - estream << toString(cycle.begin()->node()) + "\n"; - } - - estream.flush(); -} - -/* ========================================================================= */ -void printAcceptingCycle - (ostream& stream, int indent, - vector::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& path) -/* ---------------------------------------------------------------------------- - * - * Description: Writes information about an execution of a Büchi automaton to - * a stream. - * - * Arguments: stream -- A reference to an output stream. - * indent -- Number of spaces to leave to the left of - * output. - * algorithm_id -- Identifier for an algorithm. - * aut_prefix -- The prefix of a path in a Büchi automaton. - * aut_cycle -- The cycle of a path in a Büchi automaton. - * automaton -- The Büchi automaton to which the state - * identifiers in `aut_prefix' and `aut_cycle' - * refer. - * path_prefix -- The prefix of a path in a state space. - * (This path is interpreted as the input for - * the Büchi automaton.) It is assumed that - * `path_prefix.size() == aut_prefix.size()'. - * path_cycle -- The cycle of a path in a state space. It - * is assumed that `path_cycle.size() == - * aut_cycle.size()'. - * path -- The state space to which the state - * identifiers in `path_prefix' and - * `path_cycle' refer. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - Exceptional_ostream estream(&stream, ios::badbit | ios::failbit); - - printTextBlock(stream, indent, - "On input M, the automaton constructed by implementation " - + configuration.algorithmString(algorithm_id) + " (with " - + toString(automaton.numberOfAcceptanceSets()) - + " acceptance set" - + (automaton.numberOfAcceptanceSets() == 1 ? "" : "s") - + ") has the following accepting execution:", - 78); - - const BuchiAutomaton::Path* aut_segment; - const StateSpace::Path* path_segment; - BuchiAutomaton::Path::const_iterator aut_state; - StateSpace::Path::const_iterator path_state; - - for (int i = 0; i < 2; ++i) - { - if (i == 0 && aut_prefix.empty()) - continue; - - estream << string(indent + 2, ' '); - if (i == 0) - { - estream << "prefix"; - aut_segment = &aut_prefix; - path_segment = &path_prefix; - } - else - { - estream << "cycle"; - aut_segment = &aut_cycle; - path_segment = &path_cycle; - } - estream << ":\n"; - - bool first_printed = false; - for (aut_state = aut_segment->begin(), path_state = path_segment->begin(); - aut_state != aut_segment->end(); - ++aut_state, ++path_state) - { - estream << string(indent + 4, ' ') + toString(aut_state->node()) + ' '; - - const BitArray* bits; - for (int j = 0; j < 2; ++j) - { - bits = (j == 0 - ? &automaton[aut_state->node()].acceptanceSets() - : &static_cast - (aut_state->edge()).acceptanceSets()); - first_printed = false; - - for (unsigned long int accept_set = 0; - accept_set < automaton.numberOfAcceptanceSets(); - ++accept_set) - { - if (bits->test(accept_set)) - { - if (first_printed) - estream << ','; - else - { - first_printed = true; - if (j == 1) - estream << "--"; - estream << '{'; - } - estream << accept_set; - } - } - - if (first_printed) - { - estream << "}"; - if (j == 0) - estream << ' '; - } - } - - estream << "--> " + toString(aut_state->edge().targetNode()) + " [ {"; - bits = &path[path_state->node()].positiveAtoms(); - first_printed = false; - for (unsigned long int proposition = 0; - proposition < path.numberOfPropositions(); - ++proposition) - { - if (bits->test(proposition)) - { - if (first_printed) - estream << ','; - else - first_printed = true; - estream << 'p' + toString(proposition); - } - } - estream << "} |== "; - static_cast(aut_state->edge()) - .guard().print(estream); - estream << " ]\n"; - } - } - - estream.flush(); -} - -/* ========================================================================= */ -void printBuchiAutomaton - (ostream& stream, int indent, bool formula_type, - vector& input_tokens, Graph::GraphOutputFormat fmt) -/* ---------------------------------------------------------------------------- - * - * Description: Implements the user command `buchi', i.e., writes information - * about a set of states of a Büchi automaton computed using a - * given algorithm to a stream. - * - * Arguments: stream -- A reference to an output stream. - * indent -- Number of spaces to leave on the left of - * the output. - * formula_type -- Determines the formula to be translated - * into a Büchi automaton. - * input_tokens -- A reference to a vector containing the - * arguments of the user command (the - * algorithm and automaton state numbers). - * fmt -- Determines the format of output. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - Exceptional_ostream estream(&stream, ios::badbit | ios::failbit); - - unsigned long int algorithm = parseAlgorithmId(input_tokens[1]); - int formula - = (configuration.formula_options.output_mode == Configuration::NNF - ? 0 : 2) - + (formula_type ? 0 : 1); - - if (configuration.isInternalAlgorithm(algorithm)) - throw CommandErrorException - ("This feature is not available for lbtt's internal " - "model checking algorithm."); - - if (!test_results[algorithm].automaton_stats[formula_type ? 0 : 1]. - buchiAutomatonComputed()) - { - printTextBlock(stream, indent, - "No automaton was generated using implementation " - + configuration.algorithmString(algorithm) - + " for the formula `" - + toString(*round_info.formulae[formula]) - + "'.", - 78); - return; - } - - const BuchiAutomaton* automaton - = test_results[algorithm].automaton_stats[formula_type ? 0 : 1]. - buchi_automaton; - - if (fmt == Graph::NORMAL) - { - /* - * Display information about the states of the automaton. If no state - * list was given, display the whole automaton. - */ - - estream << string(indent, ' ') + "Büchi automaton information:\n" - + string(indent + 2, ' ') + "Formula: "; - - round_info.formulae[formula]->print(estream); - - estream << '\n' + string(indent + 2, ' ') + "Implementation: " - + configuration.algorithmString(algorithm) + '\n' - + string(indent + 2, ' ') + "Number of acceptance sets: " - + toString(automaton->numberOfAcceptanceSets()) + '\n'; - - if (automaton->empty()) - estream << string(indent + 2, ' ') + "The automaton is empty.\n"; - else - { - IntervalList states; - - if (input_tokens.size() == 2) - input_tokens.push_back("*"); - - try - { - parseIntervalList(input_tokens[2], states, 0, automaton->size() - 1); - } - catch (const IntervalRangeException& e) - { - throw CommandErrorException - (string("State identifier out of range (") - + toString(e.getNumber()) - + ")."); - } - - for (IntervalList::const_iterator state = states.begin(); - state != states.end(); - ++state) - { - estream << string(indent + 2, ' ') + "State " + toString(*state) - + (*state == automaton->initialState() - ? " (initial state)" : "") + ":\n"; - automaton->node(*state).print(stream, indent + 4, Graph::NORMAL, - automaton->numberOfAcceptanceSets()); - } - } - } - else if (fmt == Graph::DOT) - automaton->print(stream, indent, Graph::DOT); - - estream.flush(); -} - -/* ========================================================================= */ -void evaluateFormula - (ostream& stream, int indent, bool formula_type, - vector& input_tokens) -/* ---------------------------------------------------------------------------- - * - * Description: Implements the user command `evaluate', i.e., tells whether - * there exists an accepting execution beginning at some system - * state according to the product automaton constructed from a - * Büchi automaton computed using a given algorithm (or - * algorithms). - * - * Arguments: stream -- A reference to an output stream. - * indent -- Number of spaces to leave on the left of - * the output. - * formula_type -- Determines the LTL formula to be evaluated. - * input_tokens -- A reference to a vector of strings - * containing the arguments of the user - * command. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - Exceptional_ostream estream(&stream, ios::failbit | ios::badbit); - - IntervalList algorithms; - IntervalList system_states; - string algorithm_name; - int formula = (formula_type ? 0 : 1); - - if (!configuration.global_options.do_comp_test - && !configuration.global_options.do_cons_test) - throw CommandErrorException("This command is available only when one of " - "the model checking tests is enabled."); - - if (round_info.statespace == 0) - throw CommandErrorException("No state space was generated in this test " - "round."); - - /* - * If no list of algorithms was given as an argument, show the results of - * all algorithms. - */ - - if (input_tokens.size() < 2) - input_tokens.push_back("*"); - - parseAlgorithmIdList(input_tokens[1], algorithms); - - /* - * If no list of states was given, show information about all states. - * (If only a local product was computed, show information only about the - * initial state.) - */ - - if (input_tokens.size() < 3) - input_tokens.push_back("*"); - - try - { - parseIntervalList(input_tokens[2], system_states, 0, - round_info.real_emptiness_check_size - 1); - } - catch (const IntervalRangeException& e) - { - throw CommandErrorException - (string("State identifier out of range (") - + toString(e.getNumber()) - + ")."); - } - - estream << string(indent, ' ') + "Acceptance information:\n" - + string(indent + 2, ' ') + "CTL* formula: E "; - - round_info.formulae[configuration.formula_options.output_mode - == Configuration::NNF - ? formula - : 2 + formula]->print(estream); - - estream << '\n'; - - for (IntervalList::const_iterator state = system_states.begin(); - state != system_states.end(); - ++state) - { - estream << string(indent + 2, ' ') + "State " + toString(*state) + ":\n"; - - for (IntervalList::const_iterator algorithm = algorithms.begin(); - algorithm != algorithms.end(); - ++algorithm) - { - algorithm_name = configuration.algorithms[*algorithm].name.substr(0, 20); - estream << string(indent + 4, ' ') + toString(*algorithm) + ": " - + algorithm_name + ':' - + string(21 - algorithm_name.length(), ' '); - - if (!test_results[*algorithm].automaton_stats[formula]. - emptiness_check_performed) - estream << (configuration.isInternalAlgorithm(*algorithm) - ? "model checking result not available\n" - : "emptiness check not performed\n"); - else - estream << (test_results[*algorithm].automaton_stats[formula]. - emptiness_check_result[*state] - ? "true" - : "false") - << '\n'; - } - } - - estream.flush(); -} - -/* ========================================================================= */ -void printFormula - (ostream& stream, int indent, bool formula_type, - const vector& input_tokens) -/* ---------------------------------------------------------------------------- - * - * Description: Implements the user command `formula', i.e., displays the - * random LTL formula (or its negation) used for generating the - * Büchi automata. The formula is shown in its original form and - * possibly also in negation normal form if the user has - * requested the conversion. - * - * Arguments: stream -- A reference to an output stream. - * indent -- Number of spaces to leave on the left of - * the output. - * formula_type -- Identifies the formula to be displayed. - * input_tokens -- A reference to a vector of strings - * containing the arguments of the user - * command. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - if (round_info.formulae[0] == 0) - throw CommandErrorException("No formulas were generated in this test " - "round."); - - Exceptional_ostream estream(&stream, ios::failbit | ios::badbit); - - if (input_tokens.size() <= 1 || input_tokens[1] == "normal") - { - estream << string(indent, ' '); - round_info.formulae[formula_type ? 2 : 3]->print(estream); - } - else if (input_tokens[1] == "nnf") - { - estream << string(indent, ' '); - if (configuration.formula_options.output_mode != Configuration::NNF) - { - ::Ltl::LtlFormula* f - = round_info.formulae[formula_type ? 2 : 3]->nnfClone(); - f->print(estream); - ::Ltl::LtlFormula::destruct(f); - } - else - round_info.formulae[formula_type ? 0 : 1]->print(estream); - } - else - throw CommandErrorException - ("`" + input_tokens[1] + "' is not a valid formula mode."); - - estream << '\n'; - estream.flush(); -} - -/* ========================================================================= */ -void printCommandHelp - (ostream& stream, int indent, const vector& input_tokens) -/* ---------------------------------------------------------------------------- - * - * Description: Implements the user command `help', i.e., gives instructions - * on the use of different commands. - * - * Arguments: stream -- A reference to an output stream. - * indent -- Number of spaces to leave on the left of - * the output. - * input_tokens -- A reference to a constant vector of strings - * containing the arguments of the user - * command. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - Exceptional_ostream estream(&stream, ios::failbit | ios::badbit); - - TokenType command = _NO_INPUT; - - if (input_tokens.size() > 1) - { - command = parseCommand(input_tokens[1]); - if (command == UNKNOWN) - estream << string(indent, ' ') + "Unknown command (`" + input_tokens[1] - + "').\n\n"; - } - - switch (command) - { - case ALGORITHMS : - estream << string(indent, ' ') + "algorithms\n" - + string(indent, ' ') + "implementations\n" - + string(indent, ' ') + "translators\n"; - - printTextBlock(stream, indent + 4, - "List all implementations currently available for " - "testing.", - 78); - break; - - case BUCHI : - estream << string(indent, ' ') + "buchi [\"+\"|\"-\"] " - "[states|\"dot\"]\n"; - - printTextBlock(stream, indent + 4, - "Display information about a (list of) state(s) of a " - "Büchi automaton constructed either from the positive or " - "the negated formula using a given implementation (\"+\" " - "denotes the positive formula, \"-\" the negated " - "formula). If no formula is specified, use the positive " - "formula. If no state list is given, display all the " - "states of the automaton. The description of the entire " - "automaton can be alternatively obtained in the input " - "format of the `dot' tool that can be used to produce a " - "graphical representation of the automaton. To do this, " - "replace the state list with the string \"dot\".", - 78); - break; - - case BUCHIANALYZE : - estream << string(indent, ' ') + "buchianalysis " - "\n"; - - printTextBlock(stream, indent + 4, - "Analyze a contradiction in the Büchi automata " - "intersection emptiness check between the automaton " - "constructed from the positive formula by " - "`implementation 1' " - "and the automaton constructed from the negated formula " - "by `implementation 2'.", - 78); - break; - - case CONSISTENCYANALYSIS : - estream << string(indent, ' ') - + "consistencyanalysis [state]\n"; - - printTextBlock(stream, indent + 4, - "Analyze a contradiction in the model checking result " - "consistency check for a given implementation. The " - "optional argument `state' can be used to specify a " - "state in which to do the analysis.", - 78); - break; - - case CONTINUE : - estream << string(indent, ' ') + "continue [number of rounds]\n"; - - printTextBlock(stream, indent + 4, - "Continue testing for a given number of rounds. If the " - "number of rounds is omitted, testing will continue " - "following the current interactivity mode (for example, " - "if the option `--pauseonerror' was given in the command " - "line when invoking `lbtt', testing will continue until " - "the next test failure or until all tests have " - "finished).\n\n" - "Note: The output of this command cannot be redirected " - "to a file.", - 78); - break; - - case DISABLE : - estream << string(indent, ' ') + "disable [implementations]\n"; - - printTextBlock(stream, indent + 4, - "Disable testing of a given set of implementations. " - "If no implementations are specified, disables all " - "implementations.\n\n" - "Note: The output of this command cannot be redirected " - "to a file.", - 78); - break; - - case ENABLE : - estream << string(indent, ' ') + "enable [implementations]\n"; - - printTextBlock(stream, indent + 4, - "Enable testing of a given set of implementations. " - "If no implementations are specified, enables all " - "implementations.\n\n" - "Note: The output of this command cannot be redirected " - "to a file.", - 78); - break; - - case EVALUATE : - estream << string(indent, ' ') + "evaluate [\"+\"|\"-\"] " - "[implementations] [states]\n"; - - printTextBlock(stream, indent + 4, - "Tell whether the Büchi automaton constructed from " - "a formula (\"+\" denotes the positive formula, \"-\" " - "the negated formula) using a given implementation " - "accepts some system execution starting from a given " - "system state. If no formula is specified, use the " - "positive formula. Leaving the list of implementations " - "or the list of states unspecified will display the " - "results for all implementations or all system states, " - "respectively.", - 78); - break; - - case FORMULA : - estream << string(indent, ' ') - + "formula [\"+\"|\"-\"] [\"normal\"|\"nnf\"]\n"; - - printTextBlock(stream, indent + 4, - "Display the LTL formula used in this test round for " - "generating Büchi automata (\"+\" denotes the positive " - "formula, \"-\" the negated formula; \"normal\" and " - "\"nnf\" select between the display mode). If no formula " - "(display mode) is specified, show the positive formula " - "(the formula as generated).", - 78); - break; - - case HELP : - estream << string(indent, ' ') + "help [command]\n"; - - printTextBlock(stream, indent + 4, - "Display help about a specific command. If no command " - "name is given, give a list of all available commands." - "\n\nIn command-specific help, arguments in angle " - "brackets < > are obligatory, while square bracketed [ ] " - "arguments are optional. A vertical bar | denotes " - "selection between alternatives. Arguments " - "in quotes must be entered literally (without the " - "quotes themselves).", - 78); - break; - - case INCONSISTENCIES : - estream << string(indent, ' ') + "inconsistencies [implementations]\n"; - - printTextBlock(stream, indent + 4, - "List the system states where the model checking result " - "consistency check failed for a given (set of) " - "implementation(s).", - 78); - break; - - case QUIT : - estream << string(indent, ' ') + "quit\n"; - - printTextBlock(stream, indent + 4, "Abort testing.", 78); - break; - - case RESULTANALYZE : - estream << string(indent, ' ') + "resultanalysis [\"+\"|\"-\"] " - " " - "[state]\n"; - - printTextBlock(stream, indent + 4, - "Analyze a contradiction in the model checking results " - "of two implementations on a formula (\"+\" denotes the " - "positive formula, \"-\" the negated formula). If no " - "formula is specified, use the positive formula. The " - "optional argument `state' can be used to specify the " - "state of the state space in which to do the analysis.", - 78); - break; - - case RESULTS : - estream << string(indent, ' ') + "results [implementations]\n"; - - printTextBlock(stream, indent + 4, - "Display this round's test results for a given (set of) " - "implementation(s). If no implementations are specified, " - "show the results for all implementations.", - 78); - break; - - case SKIP : - estream << string(indent, ' ') + "skip [number of rounds]\n"; - - printTextBlock(stream, indent + 4, - "Skip a given number of rounds (defaults to 1 if no " - "number is specified).\n\nNote: The output of this " - "command cannot be redirected to a file.", - 78); - break; - - case STATESPACE : - estream << string(indent, ' ') + "statespace [states|\"dot\"]\n"; - - printTextBlock(stream, indent + 4, - "Display information about a given (list of) system " - "state(s). Display the whole state space if no " - "states are specified. Alternatively, the state " - "space description can be obtained in the input format " - "of the `dot' tool that can be used to produce a " - "graphical representation of the state space. To do " - "this, replace the state list with the string \"dot\".", - 78); - break; - - case STATISTICS : - estream << string(indent, ' ') + "statistics\n"; - - printTextBlock(stream, indent + 4, - "Display test statistics over all tests performed.", - 78); - break; - - case VERBOSITY : - estream << string(indent, ' ') + "verbosity [0-5]\n"; - - printTextBlock(stream, indent + 4, - "Change the verbosity of the output produced by the " - "program. If no value is given, display the current " - "setting.\n\nNote: The output of this command cannot " - "be redirected to a file.", - 78); - break; - - default : - printTextBlock(stream, indent, - "List of available commands (use `help " - "[command]' for command specific help):\n", - 78); - - printTextBlock(stream, indent + 2, - "algorithms\n" - "buchi\n" - "buchianalysis\n" - "continue\n" - "consistencyanalysis\n" - "disable\n" - "enable\n" - "evaluate\n" - "formula\n" - "help\n" - "implementations\n" - "inconsistencies\n" - "quit\n" - "resultanalysis\n" - "results\n" - "skip\n" - "statespace\n" - "statistics\n" - "translators\n" - "verbosity\n", - 78); - - printTextBlock(stream, indent, - "Command names can be abbreviated to the shortest prefix " - "that identifies the command unambiguously. " - "For example, the prefix `h' can be used instead of the " - "`help' command.\n\n" - "Lists of implementation or state identifiers may be " - "specified as comma-separated intervals (with no spaces " - "in between), e.g., the command `statespace " - "-5,8,14-18,22-' would display the list of all states " - "with an identifier less than or equal to 5, state 8 and " - "states 14--18, together with the states whose " - "identifiers are greater than or equal to 22.\n\n" - "The output of most commands can be redirected or " - "appended to a file by ending the command line with " - "`>filename' or `>>filename', respectively. Optionally, " - "the output can be written to a pipe instead by ending " - "the command line with `| '.", - 78); - break; - } - - estream.flush(); -} - -/* ========================================================================= */ -void printInconsistencies - (ostream& stream, int indent, vector& input_tokens) -/* ---------------------------------------------------------------------------- - * - * Description: Implements the user command `inconsistencies', i.e., lists - * the states where the consistency check failed for a set of - * algorithms. - * - * Arguments: stream -- A reference to an output stream. - * indent -- Number of spaces to leave on the left of - * the output. - * input_tokens -- A reference to a vector of strings - * containing the parameters of the user - * command. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - Exceptional_ostream estream(&stream, ios::failbit | ios::badbit); - - IntervalList algorithms; - - if (!configuration.global_options.do_cons_test) - throw CommandErrorException("This command is available only when the " - "model checking result consistency check is " - "enabled."); - - if (input_tokens.size() == 1) - input_tokens.push_back("*"); - - parseAlgorithmIdList(input_tokens[1], algorithms); - - estream << string(indent, ' ') + "Model checking result consistency check " - "results for round " - + toString(round_info.current_round) + ":\n"; - - indent += 2; - - estream << string(indent, ' ') + "Positive formula: " - << *round_info.formulae[configuration.formula_options.output_mode - == Configuration::NNF - ? 0 - : 2] - << '\n'; - - for (IntervalList::const_iterator algorithm = algorithms.begin(); - algorithm != algorithms.end(); - ++algorithm) - { - estream << '\n' - + string(indent, ' ') - + configuration.algorithmString(*algorithm) - + '\n'; - - if (test_results[*algorithm].consistency_check_result == -1) - printTextBlock(stream, indent + 2, - "Model checking result consistency check was not " - "performed on this implementation.", - 78); - else - { - if (test_results[*algorithm].consistency_check_result > 0) - printTextBlock(stream, indent + 2, - "The implementation passed the model checking result " - "consistency check.", - 78); - else - { - bool first_printed = false; - - estream << string(indent + 2, ' ') + "Check failed in states\n"; - - string resultstring = "{"; - - for (unsigned long int state = 0; - state < round_info.real_emptiness_check_size; - state++) - { - if (!test_results[*algorithm].automaton_stats[0]. - emptiness_check_result[state] - && !test_results[*algorithm].automaton_stats[1]. - emptiness_check_result[state]) - { - if (first_printed) - resultstring += ", "; - else - first_printed = true; - - resultstring += toString(state); - } - } - - resultstring += "}"; - - printTextBlock(stream, indent + 4, resultstring, 78); - } - } - } - - estream.flush(); -} - -/* ========================================================================= */ -void printTestResults - (ostream& stream, int indent, vector& input_tokens) -/* ---------------------------------------------------------------------------- - * - * Description: Implements the user command `results', i.e., displays the - * current round's test results for a given (set of) - * algorithm(s). - * - * Arguments: stream -- A reference to an output stream. - * indent -- Number of spaces to leave on the left of - * the output. - * input_tokens -- A reference to a vector of strings - * containing the arguments of the user - * command. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - Exceptional_ostream estream(&stream, ios::failbit | ios::badbit); - IntervalList algorithms; - - if (input_tokens.size() == 1) - input_tokens.push_back("*"); - - parseAlgorithmIdList(input_tokens[1], algorithms); - - estream << string(indent, ' ') + "Test results for round " - + toString(round_info.current_round) << ":\n\n"; - - if (configuration.global_options.verbosity <= 2) - printStatTableHeader(stream, indent); - - for (IntervalList::const_iterator algorithm = algorithms.begin(); - algorithm != algorithms.end(); - ++algorithm) - printAllStats(stream, indent, *algorithm); - - if (configuration.global_options.verbosity <= 2) - estream << '\n'; - - if (configuration.global_options.do_comp_test) - { - estream << string(indent, ' ') - + "Model checking result cross-comparison:\n"; - printCrossComparisonStats(stream, indent + 2, algorithms); - } - - if (configuration.global_options.do_intr_test) - { - estream << string(indent, ' ') - + "Büchi automata intersection emptiness check:\n"; - printBuchiIntersectionCheckStats(stream, indent + 2, algorithms); - } - - estream.flush(); -} - -/* ========================================================================= */ -void printStateSpace - (ostream& stream, int indent, vector& input_tokens, - Graph::GraphOutputFormat fmt) -/* ---------------------------------------------------------------------------- - * - * Description: Implements the user command `statespace', i.e., displays - * information about a given set of states of the state space. - * - * Arguments: stream -- A reference to an output stream. - * indent -- Number of spaces to leave on the left of - * the output. - * input_tokens -- A reference to a vector of strings - * containing the arguments of the user - * command. - * fmt -- Determines the format of output. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - Exceptional_ostream estream(&stream, ios::failbit | ios::badbit); - IntervalList states; - - if (!configuration.global_options.do_comp_test - && !configuration.global_options.do_cons_test) - throw CommandErrorException("This command is available only when one of " - "the model checking tests is enabled."); - - if (round_info.statespace == 0) - throw CommandErrorException("No state space was generated in this test " - "round."); - - if (fmt == Graph::NORMAL) - { - if (input_tokens.size() == 1) - input_tokens.push_back("*"); - - try - { - parseIntervalList(input_tokens[1], states, 0, - round_info.statespace->size() - 1); - } - catch (const IntervalRangeException& e) - { - throw CommandErrorException - (string("State identifier out of range (") - + toString(e.getNumber()) - + ")."); - } - - estream << string(indent, ' ') + "State space information:\n"; - - for (IntervalList::const_iterator state = states.begin(); - state != states.end(); - ++state) - { - estream << string(indent, ' ') + "State " + toString(*state) - + (*state == round_info.statespace->initialState() - ? " (initial state)" - : "") - + ":\n"; - - (*(round_info.statespace))[*state].print - (stream, indent + 2, fmt, - round_info.statespace->numberOfPropositions()); - } - } - else if (fmt == Graph::DOT) - round_info.statespace->print(stream, indent, Graph::DOT); - - estream.flush(); -} - -/* ========================================================================= */ -void changeVerbosity(const vector& input_tokens) -/* ---------------------------------------------------------------------------- - * - * Description: Implements the user command `verbosity', i.e., displays or - * changes the output verbosity level. - * - * Argument: input_tokens -- A reference to a constant vector of strings - * containing the argument of the command. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - if (input_tokens.size() == 1) - printText("Output verbosity is currently set to " - + toString(configuration.global_options.verbosity) - + ".\n\n", - 0, - 2); - else - { - unsigned long int new_verbosity = parseNumber(input_tokens[1]); - if (new_verbosity > 5) - throw CommandErrorException("Verbosity level must be between 0 and 5 " - "inclusive."); - - configuration.global_options.verbosity = new_verbosity; - - printText("Output verbosity level set to " - + toString(new_verbosity) - + ".\n\n", - 0, - 2); - } -} - -/* ========================================================================= */ -void changeAlgorithmState(vector& input_tokens, bool enable) -/* ---------------------------------------------------------------------------- - * - * Description: Changes the enabledness of a set of algorithms used in the - * tests. - * - * Argument: input_tokens -- A reference to a constant vector of strings - * containing the argument of the command. - * enable -- Determines whether the algorithms are to be - * enabled or disabled. - * - * Returns: Nothing. - * - * ------------------------------------------------------------------------- */ -{ - IntervalList algorithms; - - if (input_tokens.size() < 2) - input_tokens.push_back("*"); - - parseAlgorithmIdList(input_tokens[1], algorithms); - - for (IntervalList::const_iterator algorithm = algorithms.begin(); - algorithm != algorithms.end(); - ++algorithm) - { - printText(string(enable ? "En" : "Dis") - + "abling implementation " - + configuration.algorithmString(*algorithm) - + ".\n", - 0, - 2); - - configuration.algorithms[*algorithm].enabled = enable; - } - - round_info.cout << '\n'; - round_info.cout.flush(); -} - -} diff --git a/lbtt/src/UserCommands.h b/lbtt/src/UserCommands.h deleted file mode 100644 index 51ed74ef5..000000000 --- a/lbtt/src/UserCommands.h +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 - * Heikki Tauriainen - * - * 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 -#include -#include -#include -#include -#include -#include -#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& input_tokens); /* implementations. */ - -void printConsistencyAnalysisResults /* Analyzes a */ - (ostream& stream, int indent, /* contradicition in the */ - const vector& input_tokens); /* model checking result - * consistency check for - * an implementation. - */ - -void printAutomatonAnalysisResults /* Analyzes a */ - (ostream& stream, int indent, /* contradiction in the */ - const vector& 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 /* 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& input_tokens, - Graph::GraphOutputFormat fmt); - -void evaluateFormula /* Displays information */ - (ostream& stream, int indent, /* about existence of */ - bool formula_type, /* accepting system */ - vector& input_tokens); /* executions. */ - -void printFormula /* Displays a formula */ - (ostream& stream, int indent, /* used for testing. */ - bool formula_type, - const vector& input_tokens); - -void printCommandHelp /* Displays help about */ - (ostream& stream, int indent, /* user commands. */ - const vector& input_tokens); - -void printInconsistencies /* Lists the system */ - (ostream& stream, int indent, /* states failing the */ - vector& input_tokens); /* consistency check - * for an algorihm. - */ - -void printTestResults /* Displays the test */ - (ostream& stream, int indent, /* results of the last */ - vector& input_tokens); /* round performed. */ - -void printStateSpace /* Displays information */ - (ostream& stream, int indent, /* about a state space. */ - vector& input_tokens, - Graph::GraphOutputFormat fmt); - -void changeVerbosity /* Displays or changes */ - (const vector& input_tokens); /* the verbosity of - * output. - */ - -void changeAlgorithmState /* Enables or disables a */ - (vector& input_tokens, bool enable); /* set of algorithms - * used in the tests. - */ - -} - -#endif /* !USERCOMMANDS_H */ diff --git a/lbtt/src/getopt.c b/lbtt/src/getopt.c deleted file mode 100644 index a950cb50e..000000000 --- a/lbtt/src/getopt.c +++ /dev/null @@ -1,1055 +0,0 @@ -/* Getopt for GNU. - NOTE: getopt is now part of the C library, so if you don't know what - "Keep this file name-space clean" means, talk to drepper@gnu.org - before changing it! - Copyright (C) 1987,88,89,90,91,92,93,94,95,96,98,99,2000,2001 - 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. */ - -/* This tells Alpha OSF/1 not to define a getopt prototype in . - Ditto for AIX 3.2 and . */ -#ifndef _NO_PROTO -# define _NO_PROTO -#endif - -#ifdef HAVE_CONFIG_H -# include -#endif - -#if !defined __STDC__ || !__STDC__ -/* This is a separate conditional since some stdc systems - reject `defined (const)'. */ -# ifndef const -# define const -# endif -#endif - -#include - -/* 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 -# 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__ -/* Don't include stdlib.h for non-GNU C libraries because some of them - contain conflicting prototypes for getopt. */ -# include -# include -#endif /* GNU C library. */ - -#ifdef VMS -# include -# if HAVE_STRING_H - 0 -# include -# endif -#endif - -#ifndef _ -/* This is for other GNU distributions with internationalized messages. */ -# if defined HAVE_LIBINTL_H || defined _LIBC -# include -# ifndef _ -# define _(msgid) gettext (msgid) -# endif -# else -# define _(msgid) (msgid) -# endif -#endif - -/* This version of `getopt' appears to the caller like standard Unix `getopt' - but it behaves differently for the user, since it allows the user - to intersperse the options with the other arguments. - - As `getopt' works, it permutes the elements of ARGV so that, - when it is done, all the options precede everything else. Thus - all application programs are extended to handle flexible argument order. - - Setting the environment variable POSIXLY_CORRECT disables permutation. - Then the behavior is completely standard. - - GNU application programs can use a third alternative mode in which - they can distinguish the relative order of options and other arguments. */ - -#include "gnu-getopt.h" - -/* For communication from `getopt' to the caller. - When `getopt' finds an option that takes an argument, - the argument value is returned here. - Also, when `ordering' is RETURN_IN_ORDER, - each non-option ARGV-element is returned here. */ - -char *gnu_optarg; - -/* Index in ARGV of the next element to be scanned. - This is used for communication to and from the caller - and for communication between successive calls to `getopt'. - - On entry to `getopt', zero means this is the first call; initialize. - - When `getopt' returns -1, this is the index of the first of the - non-option elements that the caller should itself scan. - - Otherwise, `optind' communicates from one call to the next - how much of ARGV has been scanned so far. */ - -/* 1003.2 says this must be 1 before any call. */ -int gnu_optind = 1; - -/* Formerly, initialization of getopt depended on optind==0, which - causes problems with re-calling getopt as programs generally don't - know that. */ - -int __gnu_getopt_initialized; - -/* The next char to be scanned in the option-element - in which the last option character we returned was found. - This allows us to pick up the scan where we left off. - - If this is zero, or a null string, it means resume the scan - by advancing to the next ARGV-element. */ - -static char *nextchar; - -/* Callers store zero here to inhibit the error message - for unrecognized options. */ - -int gnu_opterr = 1; - -/* Set to an option character which was unrecognized. - This must be initialized on some systems to avoid linking in the - system's own getopt implementation. */ - -int gnu_optopt = '?'; - -/* Describe how to deal with options that follow non-option ARGV-elements. - - If the caller did not specify anything, - the default is REQUIRE_ORDER if the environment variable - POSIXLY_CORRECT is defined, PERMUTE otherwise. - - REQUIRE_ORDER means don't recognize them as options; - stop option processing when the first non-option is seen. - This is what Unix does. - This mode of operation is selected by either setting the environment - variable POSIXLY_CORRECT, or using `+' as the first character - of the list of option characters. - - PERMUTE is the default. We permute the contents of ARGV as we scan, - so that eventually all the non-options are at the end. This allows options - to be given in any order, even with programs that were not written to - expect this. - - RETURN_IN_ORDER is an option available to programs that were written - to expect options and other ARGV-elements in any order and that care about - the ordering of the two. We describe each non-option ARGV-element - as if it were the argument of an option with character code 1. - Using `-' as the first character of the list of option characters - selects this mode of operation. - - The special argument `--' forces an end of option-scanning regardless - of the value of `ordering'. In the case of RETURN_IN_ORDER, only - `--' can cause `getopt' to return -1 with `optind' != ARGC. */ - -static enum -{ - REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER -} ordering; - -/* Value of POSIXLY_CORRECT environment variable. */ -static char *posixly_correct; - -#ifdef __GNU_LIBRARY__ -/* We want to avoid inclusion of string.h with non-GNU libraries - because there are many ways it can cause trouble. - On some systems, it contains special magic macros that don't work - in GCC. */ -# include -# define my_index strchr -#else - -# if HAVE_STRING_H -# include -# else -# include -# endif - -/* Avoid depending on library functions or files - whose names are inconsistent. */ - -#ifndef getenv -extern char *getenv (); -#endif - -static char * -my_index (str, chr) - const char *str; - int chr; -{ - while (*str) - { - if (*str == chr) - return (char *) str; - str++; - } - return 0; -} - -/* If using GCC, we can safely declare strlen this way. - If not using GCC, it is ok not to declare it. */ -#ifdef __GNUC__ -/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h. - That was relevant to code that was here before. */ -# if (!defined __STDC__ || !__STDC__) && !defined strlen -/* gcc with -traditional declares the built-in strlen to return int, - and has done so at least since version 2.4.5. -- rms. */ -extern int strlen (const char *); -# endif /* not __STDC__ */ -#endif /* __GNUC__ */ - -#endif /* not __GNU_LIBRARY__ */ - -/* Handle permutation of arguments. */ - -/* Describe the part of ARGV that contains non-options that have - been skipped. `first_nonopt' is the index in ARGV of the first of them; - `last_nonopt' is the index after the last of them. */ - -static int first_nonopt; -static int last_nonopt; - -#ifdef _LIBC -/* Stored original parameters. - XXX This is no good solution. We should rather copy the args so - that we can compare them later. But we must not use malloc(3). */ -extern int __libc_argc; -extern char **__libc_argv; - -/* Bash 2.0 gives us an environment variable containing flags - indicating ARGV elements that should not be considered arguments. */ - -# ifdef USE_NONOPTION_FLAGS -/* Defined in getopt_init.c */ -extern char *__getopt_nonoption_flags; - -static int nonoption_flags_max_len; -static int nonoption_flags_len; -# endif - -# ifdef USE_NONOPTION_FLAGS -# define SWAP_FLAGS(ch1, ch2) \ - if (nonoption_flags_len > 0) \ - { \ - char __tmp = __getopt_nonoption_flags[ch1]; \ - __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \ - __getopt_nonoption_flags[ch2] = __tmp; \ - } -# else -# define SWAP_FLAGS(ch1, ch2) -# endif -#else /* !_LIBC */ -# define SWAP_FLAGS(ch1, ch2) -#endif /* _LIBC */ - -/* Exchange two adjacent subsequences of ARGV. - One subsequence is elements [first_nonopt,last_nonopt) - which contains all the non-options that have been skipped so far. - The other is elements [last_nonopt,optind), which contains all - the options processed since those non-options were skipped. - - `first_nonopt' and `last_nonopt' are relocated so that they describe - the new indices of the non-options in ARGV after they are moved. */ - -#if defined __STDC__ && __STDC__ -static void exchange (char **); -#endif - -static void -exchange (argv) - char **argv; -{ - int bottom = first_nonopt; - int middle = last_nonopt; - int top = gnu_optind; - char *tem; - - /* Exchange the shorter segment with the far end of the longer segment. - That puts the shorter segment into the right place. - It leaves the longer segment in the right place overall, - but it consists of two parts that need to be swapped next. */ - -#if defined _LIBC && defined USE_NONOPTION_FLAGS - /* First make sure the handling of the `__getopt_nonoption_flags' - string can work normally. Our top argument must be in the range - of the string. */ - if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len) - { - /* We must extend the array. The user plays games with us and - presents new arguments. */ - char *new_str = malloc (top + 1); - if (new_str == NULL) - nonoption_flags_len = nonoption_flags_max_len = 0; - else - { - memset (__mempcpy (new_str, __getopt_nonoption_flags, - nonoption_flags_max_len), - '\0', top + 1 - nonoption_flags_max_len); - nonoption_flags_max_len = top + 1; - __getopt_nonoption_flags = new_str; - } - } -#endif - - while (top > middle && middle > bottom) - { - if (top - middle > middle - bottom) - { - /* Bottom segment is the short one. */ - int len = middle - bottom; - register int i; - - /* Swap it with the top part of the top segment. */ - for (i = 0; i < len; i++) - { - tem = argv[bottom + i]; - argv[bottom + i] = argv[top - (middle - bottom) + i]; - argv[top - (middle - bottom) + i] = tem; - SWAP_FLAGS (bottom + i, top - (middle - bottom) + i); - } - /* Exclude the moved bottom segment from further swapping. */ - top -= len; - } - else - { - /* Top segment is the short one. */ - int len = top - middle; - register int i; - - /* Swap it with the bottom part of the bottom segment. */ - for (i = 0; i < len; i++) - { - tem = argv[bottom + i]; - argv[bottom + i] = argv[middle + i]; - argv[middle + i] = tem; - SWAP_FLAGS (bottom + i, middle + i); - } - /* Exclude the moved top segment from further swapping. */ - bottom += len; - } - } - - /* Update records for the slots the non-options now occupy. */ - - first_nonopt += (gnu_optind - last_nonopt); - last_nonopt = gnu_optind; -} - -/* Initialize the internal data when the first call is made. */ - -#if defined __STDC__ && __STDC__ -static const char *_getopt_initialize (int, char *const *, const char *); -#endif -static const char * -_getopt_initialize (argc, argv, optstring) - int argc; - char *const *argv; - const char *optstring; -{ - /* Start processing options with ARGV-element 1 (since ARGV-element 0 - is the program name); the sequence of previously skipped - non-option ARGV-elements is empty. */ - - first_nonopt = last_nonopt = gnu_optind; - - nextchar = NULL; - - posixly_correct = getenv ("POSIXLY_CORRECT"); - - /* Determine how to handle the ordering of options and nonoptions. */ - - if (optstring[0] == '-') - { - ordering = RETURN_IN_ORDER; - ++optstring; - } - else if (optstring[0] == '+') - { - ordering = REQUIRE_ORDER; - ++optstring; - } - else if (posixly_correct != NULL) - ordering = REQUIRE_ORDER; - else - ordering = PERMUTE; - -#if defined _LIBC && defined USE_NONOPTION_FLAGS - if (posixly_correct == NULL - && argc == __libc_argc && argv == __libc_argv) - { - if (nonoption_flags_max_len == 0) - { - if (__getopt_nonoption_flags == NULL - || __getopt_nonoption_flags[0] == '\0') - nonoption_flags_max_len = -1; - else - { - const char *orig_str = __getopt_nonoption_flags; - int len = nonoption_flags_max_len = strlen (orig_str); - if (nonoption_flags_max_len < argc) - nonoption_flags_max_len = argc; - __getopt_nonoption_flags = - (char *) malloc (nonoption_flags_max_len); - if (__getopt_nonoption_flags == NULL) - nonoption_flags_max_len = -1; - else - memset (__mempcpy (__getopt_nonoption_flags, orig_str, len), - '\0', nonoption_flags_max_len - len); - } - } - nonoption_flags_len = nonoption_flags_max_len; - } - else - nonoption_flags_len = 0; -#endif - - return optstring; -} - -/* Scan elements of ARGV (whose length is ARGC) for option characters - given in OPTSTRING. - - If an element of ARGV starts with '-', and is not exactly "-" or "--", - then it is an option element. The characters of this element - (aside from the initial '-') are option characters. If `getopt' - is called repeatedly, it returns successively each of the option characters - from each of the option elements. - - If `getopt' finds another option character, it returns that character, - updating `optind' and `nextchar' so that the next call to `getopt' can - resume the scan with the following option character or ARGV-element. - - If there are no more option characters, `getopt' returns -1. - Then `optind' is the index in ARGV of the first ARGV-element - that is not an option. (The ARGV-elements have been permuted - so that those that are not options now come last.) - - OPTSTRING is a string containing the legitimate option characters. - If an option character is seen that is not listed in OPTSTRING, - return '?' after printing an error message. If you set `opterr' to - zero, the error message is suppressed but we still return '?'. - - If a char in OPTSTRING is followed by a colon, that means it wants an arg, - so the following text in the same ARGV-element, or the text of the following - ARGV-element, is returned in `optarg'. Two colons mean an option that - wants an optional arg; if there is text in the current ARGV-element, - it is returned in `optarg', otherwise `optarg' is set to zero. - - If OPTSTRING starts with `-' or `+', it requests different methods of - handling the non-option ARGV-elements. - See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. - - Long-named options begin with `--' instead of `-'. - Their names may be abbreviated as long as the abbreviation is unique - or is an exact match for some defined option. If they have an - argument, it follows the option name in the same ARGV-element, separated - from the option name by a `=', or else the in next ARGV-element. - When `getopt' finds a long-named option, it returns 0 if that option's - `flag' field is nonzero, the value of the option's `val' field - if the `flag' field is zero. - - The elements of ARGV aren't really const, because we permute them. - But we pretend they're const in the prototype to be compatible - with other systems. - - LONGOPTS is a vector of `struct option' terminated by an - element containing a name which is zero. - - LONGIND returns the index in LONGOPT of the long-named option found. - It is only valid when a long-named option has been found by the most - recent call. - - If LONG_ONLY is nonzero, '-' as well as '--' can introduce - long-named options. */ - -int -_gnu_getopt_internal (argc, argv, optstring, longopts, longind, long_only) - int argc; - char *const *argv; - const char *optstring; - const struct gnu_option *longopts; - int *longind; - int long_only; -{ - int print_errors = gnu_opterr; - if (optstring[0] == ':') - print_errors = 0; - - if (argc < 1) - return -1; - - gnu_optarg = NULL; - - if (gnu_optind == 0 || !__gnu_getopt_initialized) - { - if (gnu_optind == 0) - gnu_optind = 1; /* Don't scan ARGV[0], the program name. */ - optstring = _getopt_initialize (argc, argv, optstring); - __gnu_getopt_initialized = 1; - } - - /* Test whether ARGV[optind] points to a non-option argument. - Either it does not have option syntax, or there is an environment flag - from the shell indicating it is not an option. The later information - is only used when the used in the GNU libc. */ -#if defined _LIBC && defined USE_NONOPTION_FLAGS -# define NONOPTION_P (argv[gnu_optind][0] != '-' || argv[gnu_optind][1] == '\0' \ - || (gnu_optind < nonoption_flags_len \ - && __getopt_nonoption_flags[gnu_optind] == '1')) -#else -# define NONOPTION_P (argv[gnu_optind][0] != '-' || argv[gnu_optind][1] == '\0') -#endif - - if (nextchar == NULL || *nextchar == '\0') - { - /* Advance to the next ARGV-element. */ - - /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been - moved back by the user (who may also have changed the arguments). */ - if (last_nonopt > gnu_optind) - last_nonopt = gnu_optind; - if (first_nonopt > gnu_optind) - first_nonopt = gnu_optind; - - if (ordering == PERMUTE) - { - /* If we have just processed some options following some non-options, - exchange them so that the options come first. */ - - if (first_nonopt != last_nonopt && last_nonopt != gnu_optind) - exchange ((char **) argv); - else if (last_nonopt != gnu_optind) - first_nonopt = gnu_optind; - - /* Skip any additional non-options - and extend the range of non-options previously skipped. */ - - while (gnu_optind < argc && NONOPTION_P) - gnu_optind++; - last_nonopt = gnu_optind; - } - - /* The special ARGV-element `--' means premature end of options. - Skip it like a null option, - then exchange with previous non-options as if it were an option, - then skip everything else like a non-option. */ - - if (gnu_optind != argc && !strcmp (argv[gnu_optind], "--")) - { - gnu_optind++; - - if (first_nonopt != last_nonopt && last_nonopt != gnu_optind) - exchange ((char **) argv); - else if (first_nonopt == last_nonopt) - first_nonopt = gnu_optind; - last_nonopt = argc; - - gnu_optind = argc; - } - - /* If we have done all the ARGV-elements, stop the scan - and back over any non-options that we skipped and permuted. */ - - if (gnu_optind == argc) - { - /* Set the next-arg-index to point at the non-options - that we previously skipped, so the caller will digest them. */ - if (first_nonopt != last_nonopt) - gnu_optind = first_nonopt; - return -1; - } - - /* If we have come to a non-option and did not permute it, - either stop the scan or describe it to the caller and pass it by. */ - - if (NONOPTION_P) - { - if (ordering == REQUIRE_ORDER) - return -1; - gnu_optarg = argv[gnu_optind++]; - return 1; - } - - /* We have found another option-ARGV-element. - Skip the initial punctuation. */ - - nextchar = (argv[gnu_optind] + 1 - + (longopts != NULL && argv[gnu_optind][1] == '-')); - } - - /* Decode the current option-ARGV-element. */ - - /* Check whether the ARGV-element is a long option. - - If long_only and the ARGV-element has the form "-f", where f is - a valid short option, don't consider it an abbreviated form of - a long option that starts with f. Otherwise there would be no - way to give the -f short option. - - On the other hand, if there's a long option "fubar" and - the ARGV-element is "-fu", do consider that an abbreviation of - the long option, just like "--fu", and not "-f" with arg "u". - - This distinction seems to be the most useful approach. */ - - if (longopts != NULL - && (argv[gnu_optind][1] == '-' - || (long_only && (argv[gnu_optind][2] || !my_index (optstring, argv[gnu_optind][1]))))) - { - char *nameend; - const struct gnu_option *p; - const struct gnu_option *pfound = NULL; - int exact = 0; - int ambig = 0; - int indfound = -1; - int option_index; - - for (nameend = nextchar; *nameend && *nameend != '='; nameend++) - /* Do nothing. */ ; - - /* Test all long options for either exact match - or abbreviated matches. */ - for (p = longopts, option_index = 0; p->name; p++, option_index++) - if (!strncmp (p->name, nextchar, nameend - nextchar)) - { - if ((unsigned int) (nameend - nextchar) - == (unsigned int) strlen (p->name)) - { - /* Exact match found. */ - pfound = p; - indfound = option_index; - exact = 1; - break; - } - else if (pfound == NULL) - { - /* First nonexact match found. */ - pfound = p; - indfound = option_index; - } - else if (long_only - || pfound->has_arg != p->has_arg - || pfound->flag != p->flag - || pfound->val != p->val) - /* Second or later nonexact match found. */ - ambig = 1; - } - - if (ambig && !exact) - { - if (print_errors) - fprintf (stderr, _("%s: option `%s' is ambiguous\n"), - argv[0], argv[gnu_optind]); - nextchar += strlen (nextchar); - gnu_optind++; - gnu_optopt = 0; - return '?'; - } - - if (pfound != NULL) - { - option_index = indfound; - gnu_optind++; - if (*nameend) - { - /* Don't test has_arg with >, because some C compilers don't - allow it to be used on enums. */ - if (pfound->has_arg) - gnu_optarg = nameend + 1; - else - { - if (print_errors) - { - if (argv[gnu_optind - 1][1] == '-') - /* --option */ - fprintf (stderr, - _("%s: option `--%s' doesn't allow an argument\n"), - argv[0], pfound->name); - else - /* +option or -option */ - fprintf (stderr, - _("%s: option `%c%s' doesn't allow an argument\n"), - argv[0], argv[gnu_optind - 1][0], pfound->name); - } - - nextchar += strlen (nextchar); - - gnu_optopt = pfound->val; - return '?'; - } - } - else if (pfound->has_arg == 1) - { - if (gnu_optind < argc) - gnu_optarg = argv[gnu_optind++]; - else - { - if (print_errors) - fprintf (stderr, - _("%s: option `%s' requires an argument\n"), - argv[0], argv[gnu_optind - 1]); - nextchar += strlen (nextchar); - gnu_optopt = pfound->val; - return optstring[0] == ':' ? ':' : '?'; - } - } - nextchar += strlen (nextchar); - if (longind != NULL) - *longind = option_index; - if (pfound->flag) - { - *(pfound->flag) = pfound->val; - return 0; - } - return pfound->val; - } - - /* Can't find it as a long option. If this is not getopt_long_only, - or the option starts with '--' or is not a valid short - option, then it's an error. - Otherwise interpret it as a short option. */ - if (!long_only || argv[gnu_optind][1] == '-' - || my_index (optstring, *nextchar) == NULL) - { - if (print_errors) - { - if (argv[gnu_optind][1] == '-') - /* --option */ - fprintf (stderr, _("%s: unrecognized option `--%s'\n"), - argv[0], nextchar); - else - /* +option or -option */ - fprintf (stderr, _("%s: unrecognized option `%c%s'\n"), - argv[0], argv[gnu_optind][0], nextchar); - } - nextchar = (char *) ""; - gnu_optind++; - gnu_optopt = 0; - return '?'; - } - } - - /* Look at and handle the next short option-character. */ - - { - char c = *nextchar++; - char *temp = my_index (optstring, c); - - /* Increment `optind' when we start to process its last character. */ - if (*nextchar == '\0') - ++gnu_optind; - - if (temp == NULL || c == ':') - { - if (print_errors) - { - if (posixly_correct) - /* 1003.2 specifies the format of this message. */ - fprintf (stderr, _("%s: illegal option -- %c\n"), - argv[0], c); - else - fprintf (stderr, _("%s: invalid option -- %c\n"), - argv[0], c); - } - gnu_optopt = c; - return '?'; - } - /* Convenience. Treat POSIX -W foo same as long option --foo */ - if (temp[0] == 'W' && temp[1] == ';') - { - char *nameend; - const struct gnu_option *p; - const struct gnu_option *pfound = NULL; - int exact = 0; - int ambig = 0; - int indfound = 0; - int option_index; - - /* This is an option that requires an argument. */ - if (*nextchar != '\0') - { - gnu_optarg = nextchar; - /* If we end this ARGV-element by taking the rest as an arg, - we must advance to the next element now. */ - gnu_optind++; - } - else if (gnu_optind == argc) - { - if (print_errors) - { - /* 1003.2 specifies the format of this message. */ - fprintf (stderr, _("%s: option requires an argument -- %c\n"), - argv[0], c); - } - gnu_optopt = c; - if (optstring[0] == ':') - c = ':'; - else - c = '?'; - return c; - } - else - /* We already incremented `optind' once; - increment it again when taking next ARGV-elt as argument. */ - gnu_optarg = argv[gnu_optind++]; - - /* optarg is now the argument, see if it's in the - table of longopts. */ - - for (nextchar = nameend = gnu_optarg; *nameend && *nameend != '='; nameend++) - /* Do nothing. */ ; - - /* Test all long options for either exact match - or abbreviated matches. */ - for (p = longopts, option_index = 0; p->name; p++, option_index++) - if (!strncmp (p->name, nextchar, nameend - nextchar)) - { - if ((unsigned int) (nameend - nextchar) == strlen (p->name)) - { - /* Exact match found. */ - pfound = p; - indfound = option_index; - exact = 1; - break; - } - else if (pfound == NULL) - { - /* First nonexact match found. */ - pfound = p; - indfound = option_index; - } - else - /* Second or later nonexact match found. */ - ambig = 1; - } - if (ambig && !exact) - { - if (print_errors) - fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"), - argv[0], argv[gnu_optind]); - nextchar += strlen (nextchar); - gnu_optind++; - return '?'; - } - if (pfound != NULL) - { - option_index = indfound; - if (*nameend) - { - /* Don't test has_arg with >, because some C compilers don't - allow it to be used on enums. */ - if (pfound->has_arg) - gnu_optarg = nameend + 1; - else - { - if (print_errors) - fprintf (stderr, _("\ -%s: option `-W %s' doesn't allow an argument\n"), - argv[0], pfound->name); - - nextchar += strlen (nextchar); - return '?'; - } - } - else if (pfound->has_arg == 1) - { - if (gnu_optind < argc) - gnu_optarg = argv[gnu_optind++]; - else - { - if (print_errors) - fprintf (stderr, - _("%s: option `%s' requires an argument\n"), - argv[0], argv[gnu_optind - 1]); - nextchar += strlen (nextchar); - return optstring[0] == ':' ? ':' : '?'; - } - } - nextchar += strlen (nextchar); - if (longind != NULL) - *longind = option_index; - if (pfound->flag) - { - *(pfound->flag) = pfound->val; - return 0; - } - return pfound->val; - } - nextchar = NULL; - return 'W'; /* Let the application handle it. */ - } - if (temp[1] == ':') - { - if (temp[2] == ':') - { - /* This is an option that accepts an argument optionally. */ - if (*nextchar != '\0') - { - gnu_optarg = nextchar; - gnu_optind++; - } - else - gnu_optarg = NULL; - nextchar = NULL; - } - else - { - /* This is an option that requires an argument. */ - if (*nextchar != '\0') - { - gnu_optarg = nextchar; - /* If we end this ARGV-element by taking the rest as an arg, - we must advance to the next element now. */ - gnu_optind++; - } - else if (gnu_optind == argc) - { - if (print_errors) - { - /* 1003.2 specifies the format of this message. */ - fprintf (stderr, - _("%s: option requires an argument -- %c\n"), - argv[0], c); - } - gnu_optopt = c; - if (optstring[0] == ':') - c = ':'; - else - c = '?'; - } - else - /* We already incremented `optind' once; - increment it again when taking next ARGV-elt as argument. */ - gnu_optarg = argv[gnu_optind++]; - nextchar = NULL; - } - } - return c; - } -} - -int -gnu_getopt (argc, argv, optstring) - int argc; - char *const *argv; - const char *optstring; -{ - return _gnu_getopt_internal (argc, argv, optstring, - (const struct gnu_option *) 0, - (int *) 0, - 0); -} - -#endif /* Not ELIDE_CODE. */ - -#ifdef TEST - -/* Compile with -DTEST to make an executable for use in testing - the above definition of `getopt'. */ - -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; - - c = gnu_getopt (argc, argv, "abc:d:0123456789"); - if (c == -1) - break; - - switch (c) - { - 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 '?': - 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 */ diff --git a/lbtt/src/getopt1.c b/lbtt/src/getopt1.c deleted file mode 100644 index 23c4e508e..000000000 --- a/lbtt/src/getopt1.c +++ /dev/null @@ -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 -#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 - -/* 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 -#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 -#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 - -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 */ diff --git a/lbtt/src/gnu-getopt.h b/lbtt/src/gnu-getopt.h deleted file mode 100644 index 0ff0fb1ae..000000000 --- a/lbtt/src/gnu-getopt.h +++ /dev/null @@ -1,180 +0,0 @@ -/* Declarations for getopt. - Copyright (C) 1989-1994, 1996-1999, 2001 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. */ - -#ifndef _GETOPT_H - -#ifndef __need_getopt -# define _GETOPT_H 1 -#endif - -/* If __GNU_LIBRARY__ is not already defined, either we are being used - standalone, or this is the first header included in the source file. - If we are being used with glibc, we need to include , but - that does not exist if we are standalone. So: if __GNU_LIBRARY__ is - not defined, include , which will pull in for us - if it's from glibc. (Why ctype.h? It's guaranteed to exist and it - doesn't flood the namespace with stuff the way some other headers do.) */ -#if !defined __GNU_LIBRARY__ -# include -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* For communication from `getopt' to the caller. - When `getopt' finds an option that takes an argument, - the argument value is returned here. - Also, when `ordering' is RETURN_IN_ORDER, - each non-option ARGV-element is returned here. */ - -extern char *gnu_optarg; - -/* Index in ARGV of the next element to be scanned. - This is used for communication to and from the caller - and for communication between successive calls to `getopt'. - - On entry to `getopt', zero means this is the first call; initialize. - - When `getopt' returns -1, this is the index of the first of the - non-option elements that the caller should itself scan. - - Otherwise, `optind' communicates from one call to the next - how much of ARGV has been scanned so far. */ - -extern int gnu_optind; - -/* Callers store zero here to inhibit the error message `getopt' prints - for unrecognized options. */ - -extern int gnu_opterr; - -/* Set to an option character which was unrecognized. */ - -extern int gnu_optopt; - -#ifndef __need_getopt -/* Describe the long-named options requested by the application. - The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector - of `struct option' terminated by an element containing a name which is - zero. - - The field `has_arg' is: - no_argument (or 0) if the option does not take an argument, - required_argument (or 1) if the option requires an argument, - optional_argument (or 2) if the option takes an optional argument. - - If the field `flag' is not NULL, it points to a variable that is set - to the value given in the field `val' when the option is found, but - left unchanged if the option is not found. - - To have a long-named option do something other than set an `int' to - a compiled-in constant, such as set a value from `optarg', set the - option's `flag' field to zero and its `val' field to a nonzero - value (the equivalent single-letter option character, if there is - one). For long options that have a zero `flag' field, `getopt' - returns the contents of the `val' field. */ - -struct gnu_option -{ -# if (defined __STDC__ && __STDC__) || defined __cplusplus - const char *name; -# else - char *name; -# endif - /* has_arg can't be an enum because some compilers complain about - type mismatches in all the code that assumes it is an int. */ - int has_arg; - int *flag; - int val; -}; - -/* Names for the values of the `has_arg' field of `struct option'. */ - -# define no_argument 0 -# define required_argument 1 -# define optional_argument 2 -#endif /* need getopt */ - - -/* Get definitions and prototypes for functions to process the - arguments in ARGV (ARGC of them, minus the program name) for - options given in OPTS. - - Return the option character from OPTS just read. Return -1 when - there are no more options. For unrecognized options, or options - missing arguments, `optopt' is set to the option letter, and '?' is - returned. - - The OPTS string is a list of characters which are recognized option - letters, optionally followed by colons, specifying that that letter - takes an argument, to be placed in `optarg'. - - If a letter in OPTS is followed by two colons, its argument is - optional. This behavior is specific to the GNU `getopt'. - - The argument `--' causes premature termination of argument - scanning, explicitly telling `getopt' that there are no more - options. - - If OPTS begins with `--', then non-option arguments are treated as - arguments to the option '\0'. This behavior is specific to the GNU - `getopt'. */ - -#if (defined __STDC__ && __STDC__) || defined __cplusplus -# ifdef __GNU_LIBRARY__ -/* Many other libraries have conflicting prototypes for getopt, with - differences in the consts, in stdlib.h. To avoid compilation - errors, only prototype getopt for the GNU C library. */ -extern int gnu_getopt (int __argc, char *const *__argv, const char *__shortopts); -# else /* not __GNU_LIBRARY__ */ -extern int gnu_getopt (); -# endif /* __GNU_LIBRARY__ */ - -# ifndef __need_getopt -extern int gnu_getopt_long (int __argc, char *const *__argv, const char *__shortopts, - const struct gnu_option *__longopts, int *__longind); -extern int gnu_getopt_long_only (int __argc, char *const *__argv, - const char *__shortopts, - const struct gnu_option *__longopts, int *__longind); - -/* Internal only. Users should not call this directly. */ -extern int _gnu_getopt_internal (int __argc, char *const *__argv, - const char *__shortopts, - const struct gnu_option *__longopts, int *__longind, - int __long_only); -# endif -#else /* not __STDC__ */ -extern int gnu_getopt (); -# ifndef __need_getopt -extern int gnu_getopt_long (); -extern int gnu_getopt_long_only (); - -extern int _gnu_getopt_internal (); -# endif -#endif /* __STDC__ */ - -#ifdef __cplusplus -} -#endif - -/* Make sure we later can get all the definitions and declarations. */ -#undef __need_getopt - -#endif /* getopt.h */ diff --git a/lbtt/src/main.cc b/lbtt/src/main.cc deleted file mode 100644 index beb71052d..000000000 --- a/lbtt/src/main.cc +++ /dev/null @@ -1,819 +0,0 @@ -/* - * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008 - * Heikki Tauriainen - * - * 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 -#include -#include -#include -#include -#ifdef HAVE_SYS_TYPES_H -#include -#endif /* HAVE_SYS_TYPES_H */ -#include -#include -#ifdef HAVE_READLINE -#include -#include -#include -#endif /* HAVE_READLINE */ -#ifdef HAVE_ISATTY -#ifdef HAVE_UNISTD_H -#include -#endif /* HAVE_UNISTD_H */ -#endif /* HAVE_ISATTY */ -#include "LbttAlloc.h" -#include "Configuration.h" -#include "DispUtil.h" -#include "Exception.h" -#include "LtlFormula.h" -#include "Random.h" -#include "SharedTestData.h" -#include "StatDisplay.h" -#include "TempFsysName.h" -#include "TestOperations.h" -#include "TestRoundInfo.h" -#include "TestStatistics.h" -#include "UserCommandReader.h" - -using namespace std; - - - -/****************************************************************************** - * - * This variable will be used for testing whether the testing has been aborted - * with a SIGINT signal. - * - *****************************************************************************/ - -bool user_break; - - - -/****************************************************************************** - * - * Program configuration. - * - *****************************************************************************/ - -Configuration configuration; - - - -/****************************************************************************** - * - * Variables for storing test results and maintaining test state information. - * - *****************************************************************************/ - -namespace SharedTestData -{ - -TestRoundInfo round_info; /* Data structure for - * storing information - * about the current test - * round. - */ - -vector test_results; /* Test results for each - * individual algorithm. - */ - -vector final_statistics; /* Overall test - * statistics for each - * algorithm. - */ - -} - - - -/****************************************************************************** - * - * Functions for allocating and deallocating temporary file names. - * - *****************************************************************************/ - -static void allocateTempFilenames() -{ - using SharedTestData::round_info; - round_info.formula_file_name[0] = new TempFsysName; - round_info.formula_file_name[0]->allocate("lbtt"); - round_info.formula_file_name[1] = new TempFsysName; - round_info.formula_file_name[1]->allocate("lbtt"); - round_info.automaton_file_name = new TempFsysName; - round_info.automaton_file_name->allocate("lbtt"); - round_info.cout_capture_file = new TempFsysName; - round_info.cout_capture_file->allocate("lbtt"); - round_info.cerr_capture_file = new TempFsysName; - round_info.cerr_capture_file->allocate("lbtt"); -} - -static void deallocateTempFilenames() -{ - using SharedTestData::round_info; - if (round_info.formula_file_name[0] != 0) - { - delete round_info.formula_file_name[0]; - round_info.formula_file_name[0] = 0; - } - if (round_info.formula_file_name[1] != 0) - { - delete round_info.formula_file_name[1]; - round_info.formula_file_name[1] = 0; - } - if (round_info.automaton_file_name != 0) - { - delete round_info.automaton_file_name; - round_info.automaton_file_name = 0; - } - if (round_info.cout_capture_file != 0) - { - delete round_info.cout_capture_file; - round_info.cout_capture_file = 0; - } - if (round_info.cerr_capture_file != 0) - { - delete round_info.cerr_capture_file; - round_info.cerr_capture_file = 0; - } -} - - - -/****************************************************************************** - * - * Handler for the SIGINT signal. - * - *****************************************************************************/ - -static void breakHandler(int) -{ - user_break = true; -} - - - -/****************************************************************************** - * - * Default handler for signals that terminate the process. - * - *****************************************************************************/ - -pid_t translator_process = 0; /* Process group for translator process */ - -static void abortHandler(int signum) -{ - deallocateTempFilenames(); - if (translator_process != 0 && kill(translator_process, 0) == 0) - kill(-translator_process, SIGTERM); - struct sigaction s; - s.sa_handler = SIG_DFL; - sigemptyset(&s.sa_mask); - s.sa_flags = 0; - sigaction(signum, &s, static_cast(0)); - raise(signum); -} - - - -/****************************************************************************** - * - * Function for installing signal handlers. - * - *****************************************************************************/ - -static void installSignalHandler(int signum, void (*handler)(int)) -{ - struct sigaction s; - sigaction(signum, static_cast(0), &s); - - if (s.sa_handler != SIG_IGN) - { - s.sa_handler = handler; - sigemptyset(&s.sa_mask); - s.sa_flags = 0; - sigaction(signum, &s, static_cast(0)); - } -} - - - -/****************************************************************************** - * - * Test loop. - * - *****************************************************************************/ - -bool testLoop() -{ - using namespace DispUtil; - using namespace SharedTestData; - using namespace StatDisplay; - using namespace StringUtil; - using namespace TestOperations; - - const Configuration::GlobalConfiguration& global_options - = configuration.global_options; - - /* - * Initialize the test state information data structure with program - * configuration information. - */ - - round_info.number_of_translators = configuration.algorithms.size(); - - round_info.next_round_to_run += global_options.init_skip; - - round_info.next_round_to_stop - = (global_options.interactive == Configuration::ALWAYS - ? round_info.next_round_to_run - : global_options.number_of_rounds + 1); - - /* - * If a name for the error log file was given in the configuration, create - * the file. - */ - - if (!global_options.transcript_filename.empty()) - { - time_t current_time; - - time(¤t_time); - - try - { - openFile(global_options.transcript_filename.c_str(), - round_info.transcript_file, - ios::out | ios::trunc, - 0); - } - catch (const IOException&) - { - throw Exception("error creating log file `" - + global_options.transcript_filename + '\''); - } - - try - { - round_info.transcript_file << "lbtt " PACKAGE_VERSION - " error log file, created on " - + string(ctime(¤t_time)) - + '\n'; - - configuration.print(round_info.transcript_file); - } - catch (const IOException&) - { - round_info.transcript_file.close(); - } - } - - /* - * If a formula file name was given in the configuration, open the file for - * reading. The special filename "-" refers to the standard input. - */ - - try - { - if (!global_options.formula_input_filename.empty()) - { - if (global_options.formula_input_filename == "-") - round_info.formula_input_stream = &cin; - else - { - openFile(global_options.formula_input_filename.c_str(), - round_info.formula_input_file, - ios::in, - 0); - round_info.formula_input_stream = &round_info.formula_input_file; - } - } - } - catch (const FileOpenException& e) - { - if (round_info.transcript_file.is_open()) - writeToTranscript("Testing aborted: " + string(e.what()), false); - - throw; - } - - /* - * If using the rand48() function family for generating random numbers, - * initialize the random number generators. - */ - -#ifdef HAVE_RAND48 - unsigned short int statespace_random_state[3]; - unsigned short int formula_random_state[3]; - - SRAND(configuration.global_options.statespace_random_seed); - for (int i = 0; i < 3; i++) - statespace_random_state[i] = static_cast(LRAND(0, SHRT_MAX)); - - SRAND(configuration.global_options.formula_random_seed); - for (int i = 0; i < 3; i++) - formula_random_state[i] = static_cast(LRAND(0, SHRT_MAX)); -#endif /* HAVE_RAND48 */ - - /* - * Intialize the vector for storing the test results for each - * implementation and the vector for collecting overall test statistics for - * each implementation. - */ - - StateSpace::size_type max_emptiness_checking_size - = (global_options.product_mode == Configuration::GLOBAL - ? configuration.statespace_generator.max_size - : 1); - - test_results.clear(); - final_statistics.clear(); - for (unsigned long int i = 0; i < configuration.algorithms.size(); ++i) - { - test_results.push_back - (AlgorithmTestResults(configuration.algorithms.size(), - max_emptiness_checking_size)); - final_statistics.push_back - (TestStatistics(configuration.algorithms.size())); - } - - /* - * Test loop. - */ - - for (round_info.current_round = 1; - !round_info.abort - && round_info.current_round <= global_options.number_of_rounds; - ++round_info.current_round) - { - user_break = false; - round_info.error = false; - round_info.skip - = (round_info.current_round < round_info.next_round_to_run); - - if (!round_info.skip) - printText(string("Round ") + toString(round_info.current_round) - + " of " + toString(global_options.number_of_rounds) + "\n\n", - 2); - - try - { - /* - * Generate a new state space if necessary. - */ - - round_info.fresh_statespace - = ((global_options.do_comp_test || global_options.do_cons_test) - && round_info.next_round_to_change_statespace - == round_info.current_round); - - if (round_info.fresh_statespace) - { -#ifdef HAVE_RAND48 - seed48(statespace_random_state); - for (int i = 0; i < 3; i++) - statespace_random_state[i] = static_cast - (LRAND(0, SHRT_MAX)); -#else - SRAND(global_options.statespace_random_seed); - configuration.global_options.statespace_random_seed - = LRAND(0, RAND_MAX); -#endif /* HAVE_RAND48 */ - - if (global_options.statespace_change_interval == 0) - round_info.next_round_to_change_statespace - = global_options.number_of_rounds + 1; - else - round_info.next_round_to_change_statespace - += global_options.statespace_change_interval; - - for (vector::iterator it = test_results.begin(); - it != test_results.end(); - ++it) - it->emptinessReset(); - - if ((!user_break && !round_info.skip) - || (global_options.statespace_generation_mode - == Configuration::ENUMERATEDPATH) - || (round_info.next_round_to_run - < round_info.next_round_to_change_statespace)) - { - try - { - generateStateSpace(); - } - catch (const UserBreakException&) - { - } - catch (const StateSpaceGenerationException&) - { - round_info.error = true; - } - } - } - - /* - * Test whether it is necessary to generate (or read) a new LTL formula. - */ - - round_info.fresh_formula - = (round_info.next_round_to_change_formula - == round_info.current_round); - - if (round_info.fresh_formula) - { -#ifdef HAVE_RAND48 - seed48(formula_random_state); - for (int i = 0; i < 3; i++) - formula_random_state[i] = static_cast(LRAND(0, SHRT_MAX)); -#else - SRAND(global_options.formula_random_seed); - configuration.global_options.formula_random_seed = LRAND(0, RAND_MAX); -#endif /* HAVE_RAND48 */ - - if (global_options.formula_change_interval == 0) - round_info.next_round_to_change_formula - = global_options.number_of_rounds + 1; - else - round_info.next_round_to_change_formula - += global_options.formula_change_interval; - - round_info.formula_in_file[0] = round_info.formula_in_file[1] = false; - - for (vector::iterator it = test_results.begin(); - it != test_results.end(); - ++it) - it->fullReset(); - - if ((!round_info.error && !user_break && !round_info.skip) - || (round_info.next_round_to_run - < round_info.next_round_to_change_formula)) - { - try - { - generateFormulae(!global_options.formula_input_filename.empty() - ? round_info.formula_input_stream - : 0); - } - catch (const FormulaGenerationException&) - { - round_info.error = true; - round_info.abort = true; - continue; - } - } - } - - if (user_break) - { - printText("[User break]\n\n", 1, 4); - throw UserBreakException(); - } - - if (!round_info.error && !round_info.skip) - { - writeFormulaeToFiles(); - - /* - * If the generated state spaces paths, model check the formula - * separately in the path. - */ - - if (global_options.statespace_generation_mode & Configuration::PATH - && (global_options.do_cons_test || global_options.do_comp_test) - && (!test_results[round_info.number_of_translators - 1]. - automaton_stats[0].emptiness_check_performed) - && configuration.algorithms[round_info.number_of_translators - 1]. - enabled) - verifyFormulaOnPath(); - - if (!round_info.error) - { - if (global_options.verbosity == 2) - ::StatDisplay::printStatTableHeader(round_info.cout, 4); - - unsigned long int num_enabled_implementations = 0; - - for (unsigned long int algorithm_id = 0; - algorithm_id < round_info.number_of_translators; - ++algorithm_id) - { - if (!configuration.algorithms[algorithm_id].enabled) - continue; - - num_enabled_implementations++; - - if (configuration.isInternalAlgorithm(algorithm_id)) - continue; - - printText(configuration.algorithmString(algorithm_id) + '\n', - 3, 4); - - for (int counter = 0; counter < 2; counter++) - { - if (user_break) - { - printText("[User break]\n\n", 1, 4); - throw UserBreakException(); - } - - if (global_options.verbosity == 1 - || global_options.verbosity == 2) - { - if (counter == 1) - round_info.cout << '\n'; - if (global_options.verbosity == 1) - round_info.cout << round_info.current_round << ' '; - else - round_info.cout << string(4, ' '); - changeStreamFormatting(cout, 2, 0, ios::right); - round_info.cout << algorithm_id << ' '; - restoreStreamFormatting(cout); - round_info.cout << (counter == 0 ? '+' : '-') << ' '; - round_info.cout.flush(); - } - else - printText(string(counter == 1 ? "Negated" : "Positive") - + " formula:\n", - 3, - 6); - - try - { - /* - * Generate a Büchi automaton using the current algorithm. - * `counter' determines the formula which is to be - * translated into an automaton; 0 denotes the positive and - * 1 the negated formula. - */ - - generateBuchiAutomaton(counter, algorithm_id); - - if (global_options.do_cons_test || global_options.do_comp_test) - { - /* - * Find the system states from which an accepting - * execution cycle can be reached by checking the product - * automaton for emptiness. - */ - - performEmptinessCheck(counter, algorithm_id); - } - } - catch (const BuchiAutomatonGenerationException&) - { - round_info.error = true; - final_statistics[algorithm_id]. - failures_to_compute_buchi_automaton[counter]++; - } - catch (const ProductAutomatonGenerationException&) - { - round_info.error = true; - final_statistics[algorithm_id]. - failures_to_compute_product_automaton[counter]++; - } - catch (const EmptinessCheckFailedException&) - { - round_info.error = true; - } - } - - /* - * If the emptiness check was performed successfully for the - * product automata constructed from both the positive and - * negated formulae, test whether the emptiness check results - * are consistent with each other. (It should not be possible - * for both the formula and its negation to be true in any - * state.) - */ - if (global_options.do_cons_test - && test_results[algorithm_id].automaton_stats[0]. - emptiness_check_performed - && test_results[algorithm_id].automaton_stats[1]. - emptiness_check_performed) - performConsistencyCheck(algorithm_id); - - printText("\n", 1); - } - - if (global_options.verbosity == 2) - { - round_info.cout << '\n'; - round_info.cout.flush(); - } - - if (num_enabled_implementations > 0) - { - if (global_options.do_comp_test) - { - /* - * Perform the pairwise comparisons of the emptiness check - * results obtained using the different algorithms. - */ - - if (num_enabled_implementations >= 2) - compareResults(); - } - - if (global_options.do_intr_test) - { - /* - * Perform the pairwise intersection emptiness checks on the - * Büchi automata computed during this test round using the - * different algorithms. - */ - - performBuchiIntersectionCheck(); - } - - if ((global_options.do_comp_test || global_options.do_intr_test) - && global_options.verbosity == 2) - { - round_info.cout << '\n'; - round_info.cout.flush(); - } - } - } - } - } - catch (const UserBreakException&) - { - user_break = false; - round_info.next_round_to_stop = round_info.current_round; - } - - /* - * Determine from the program configuration and the error status whether - * the testing should be paused to wait for user commands. - */ - - if (round_info.error) - round_info.all_tests_successful = false; - - if (round_info.error - && global_options.interactive == Configuration::ONERROR) - round_info.next_round_to_stop = round_info.current_round; - - if (round_info.next_round_to_stop == round_info.current_round) - ::UserCommandInterface::executeUserCommands(); - } - - if (round_info.path_iterator != 0) - delete round_info.path_iterator; - else if (round_info.statespace != 0) - delete round_info.statespace; - - for (int f = 0; f < 4; f++) - { - if (round_info.formulae[f] != 0) - ::Ltl::LtlFormula::destruct(round_info.formulae[f]); - } - - for (vector::iterator it = test_results.begin(); - it != test_results.end(); - ++it) - it->fullReset(); - - round_info.current_round--; - - if (round_info.transcript_file.is_open()) - { - round_info.transcript_file << endl; - - if (round_info.abort) - round_info.transcript_file << "Testing aborted in round " - + toString(round_info.current_round) - + ".\n" - << endl; - - try - { - printCollectiveStats(round_info.transcript_file, 0); - } - catch (const IOException&) - { - } - - round_info.transcript_file << endl; - - time_t current_time; - - time(¤t_time); - - round_info.transcript_file << "lbtt error log closed on " - + string(ctime(¤t_time)) - << endl; - - round_info.transcript_file.close(); - } - - if (global_options.verbosity >= 2) - printCollectiveStats(cout, 0); - - if (round_info.formula_input_file.is_open()) - round_info.formula_input_file.close(); - - return round_info.all_tests_successful; -} - - - -/****************************************************************************** - * - * Main function. - * - *****************************************************************************/ - -int main(int argc, char* argv[]) -{ - try - { - configuration.read(argc, argv); - } - catch (const Configuration::ConfigurationException& e) - { - cerr << argv[0]; - if (!e.line_info.empty()) - cerr << ":" << configuration.global_options.cfg_filename << ":" - << e.line_info; - cerr << ": " << e.what() << endl; - exit(2); - } - -#ifdef HAVE_ISATTY - if (configuration.global_options.formula_input_filename == "-" - && !isatty(STDIN_FILENO)) - { - configuration.global_options.interactive = Configuration::NEVER; - configuration.global_options.handle_breaks = false; - } -#endif /* HAVE_ISATTY */ - - if (configuration.global_options.verbosity >= 3) - configuration.print(cout); - - user_break = false; - - installSignalHandler(SIGHUP, abortHandler); - installSignalHandler(SIGINT, - configuration.global_options.handle_breaks - ? breakHandler - : abortHandler); - installSignalHandler(SIGQUIT, abortHandler); - installSignalHandler(SIGABRT, abortHandler); - installSignalHandler(SIGPIPE, abortHandler); - installSignalHandler(SIGALRM, abortHandler); - installSignalHandler(SIGTERM, abortHandler); - installSignalHandler(SIGUSR1, abortHandler); - installSignalHandler(SIGUSR2, abortHandler); - -#ifdef HAVE_OBSTACK_H - obstack_alloc_failed_handler = &ObstackAllocator::failure; -#endif /* HAVE_OBSTACK_H */ - -#ifdef HAVE_READLINE - using_history(); -#endif /* HAVE_READLINE */ - - try - { - allocateTempFilenames(); - if (!testLoop()) - { - deallocateTempFilenames(); - return 1; - } - } - catch (const Exception& e) - { - deallocateTempFilenames(); - cerr << endl << argv[0] << ": " << e.what() << endl; - exit(3); - } - catch (const bad_alloc&) - { - deallocateTempFilenames(); - cerr << endl << argv[0] << ": out of memory" << endl; - exit(3); - } - - deallocateTempFilenames(); - return 0; -} diff --git a/lbtt/src/translate.cc b/lbtt/src/translate.cc deleted file mode 100644 index fdd2246f9..000000000 --- a/lbtt/src/translate.cc +++ /dev/null @@ -1,267 +0,0 @@ -/* - * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 - * Heikki Tauriainen - * - * 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 -#include -#include -#include -#include -#include "Exception.h" -#include "LbtWrapper.h" -#include "LtlFormula.h" -#include "SpinWrapper.h" -#include "SpotWrapper.h" -#ifdef HAVE_GETOPT_LONG -#include -#define OPTIONSTRUCT struct option -#else -#include "gnu-getopt.h" -#define opterr gnu_opterr -#define OPTIONSTRUCT struct gnu_option -#define getopt_long gnu_getopt_long -#endif /* HAVE_GETOPT_LONG */ - -/****************************************************************************** - * - * Pointer to the command line arguments of the program. - * - *****************************************************************************/ - -char** command_line_arguments; - - - -/****************************************************************************** - * - * Pointer to an object providing operations for translating a formula into an - * automaton. - * - *****************************************************************************/ - -static TranslatorInterface* translator = 0; - - - -/****************************************************************************** - * - * A function for showing warnings to the user. - * - *****************************************************************************/ - -void printWarning(const string& msg) -{ - cerr << string(command_line_arguments[0]) + ": warning: " + msg << endl; -} - - - -/****************************************************************************** - * - * Handler for SIGINT, SIGQUIT, SIGABRT and SIGTERM. - * - *****************************************************************************/ - -static void signalHandler(int signal_number) -{ - if (translator != 0) - delete translator; - struct sigaction s; - s.sa_handler = SIG_DFL; - sigemptyset(&s.sa_mask); - s.sa_flags = 0; - sigaction(signal_number, &s, static_cast(0)); - raise(signal_number); -} - - - -/****************************************************************************** - * - * Function for installing signal handlers. - * - *****************************************************************************/ - -static void installSignalHandler(int signum) -{ - struct sigaction s; - sigaction(signum, static_cast(0), &s); - - if (s.sa_handler != SIG_IGN) - { - s.sa_handler = signalHandler; - sigemptyset(&s.sa_mask); - s.sa_flags = 0; - sigaction(signum, &s, static_cast(0)); - } -} - - - -/****************************************************************************** - * - * Main function. - * - *****************************************************************************/ - -int main(int argc, char** argv) -{ - typedef enum {OPT_HELP = 'h', OPT_LBT, OPT_SPIN, OPT_SPOT, OPT_VERSION = 'V'} - OptionType; - - static OPTIONSTRUCT command_line_options[] = - { - {"help", no_argument, 0, OPT_HELP}, - {"lbt", no_argument, 0, OPT_LBT}, - {"spin", no_argument, 0, OPT_SPIN}, - {"spot", no_argument, 0, OPT_SPOT}, - {"version", no_argument, 0, OPT_VERSION}, - {0, 0, 0, 0} - }; - - command_line_arguments = argv; - - opterr = 1; - int opttype, option_index; - - do - { - option_index = 0; - opttype = getopt_long(argc, argv, "hV", command_line_options, - &option_index); - - switch (opttype) - { - case OPT_HELP : - cout << string("Usage: ") << command_line_arguments[0] - << " [translator] [command line for translator] [formula " - "file] [automaton file]\n" - "General options:\n" - " -h, --help Show this help\n" - " -V, --version Show version and exit\n\n" - "Translator options:\n" - " --lbt lbt\n" - " --spin Spin\n" - " --spot Spot\n" - "The command line for these translators must be given as a " - "single argument\n" - "including the name (and location) of an external program to " - "execute, together\n" - "with any optional parameters to be passed to the " - "program.\n\n"; - exit(0); - break; - - case OPT_LBT : - translator = new LbtWrapper(); - break; - - case OPT_SPIN : - translator = new SpinWrapper(); - break; - - case OPT_SPOT : - translator = new SpotWrapper(); - break; - - case OPT_VERSION : - cout << "lbtt-translate " PACKAGE_VERSION "\n" - "lbtt-translate is free software; you may change and " - "redistribute it under the\n" - "terms of the GNU General Public License. lbtt-translate " - "comes with NO WARRANTY.\n" - "See the file COPYING for details.\n"; - exit(0); - break; - - case '?' : - case ':' : - exit(-1); - } - } - while (opttype != -1); - - if (argc < 5) - { - cerr << argv[0] << ": too few command line arguments" << endl; - exit(-1); - } - - if (argc > 5) - { - cerr << argv[0] << ": too many command line arguments" << endl; - exit(-1); - } - - int exitstatus = 0; - - installSignalHandler(SIGHUP); - installSignalHandler(SIGINT); - installSignalHandler(SIGQUIT); - installSignalHandler(SIGABRT); - installSignalHandler(SIGPIPE); - installSignalHandler(SIGALRM); - installSignalHandler(SIGTERM); - installSignalHandler(SIGUSR1); - installSignalHandler(SIGUSR2); - - ::Ltl::LtlFormula* formula(0); - - try - { - ifstream input_file; - input_file.open(command_line_arguments[argc - 2], ios::in); - if (!input_file.good()) - throw FileOpenException(command_line_arguments[argc - 2]); - - formula = ::Ltl::LtlFormula::read(input_file); - - translator->translate(*formula, command_line_arguments[argc - 1]); - - ::Ltl::LtlFormula::destruct(formula); - delete translator; - } - catch (...) - { - if (formula != 0) - ::Ltl::LtlFormula::destruct(formula); - - cerr << string(command_line_arguments[0]) + ": "; - exitstatus = -1; - - if (translator != 0) - delete translator; - - try - { - throw; - } - catch (const Exception& e) - { - cerr << e.what(); - } - catch (...) - { - cerr << "fatal error, aborting"; - } - - cerr << endl; - } - - return exitstatus; -} diff --git a/lbtt/src/translate.h b/lbtt/src/translate.h deleted file mode 100644 index af028f4f4..000000000 --- a/lbtt/src/translate.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 - * Heikki Tauriainen - * - * 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 TRANSLATE_H -#define TRANSLATE_H - -#include -#include - -/****************************************************************************** - * - * Declarations of external variables and functions defined in translate.cc. - * - *****************************************************************************/ - -extern char** command_line_arguments; /* Command line arguments - * passed to the main - * translator program. - */ - -void printWarning(const string& msg); /* Displays a warning. */ - -#endif /* !TRANSLATE_H */ diff --git a/m4/lbtt.m4 b/m4/lbtt.m4 deleted file mode 100644 index f7c662271..000000000 --- a/m4/lbtt.m4 +++ /dev/null @@ -1,40 +0,0 @@ -AC_DEFUN([AX_CHECK_LBTT], [ - AC_ARG_WITH([included-lbtt], - [AC_HELP_STRING([--with-included-lbtt], - [use the LBTT program inclued here])]) - AS_IF([AM_RUN_LOG([lbtt-translate --version | grep 1.2.1a])], - [need_included_lbtt=no], - [need_included_lbtt=yes]) - - if test "$need_included_lbtt" = yes; then - if test "$with_included_lbtt" = no; then - AC_MSG_WARN([Cannot find lbtt, needed for test-suite and benchmarks. -Please install lbtt first, or configure with --with-included-lbtt.]) - else - with_included_lbtt=yes - fi - fi - - if test "$with_included_lbtt" = yes; then - LBTT='${top_builddir}/lbtt/src/lbtt' - LBTT_TRANSLATE='${top_builddir}/lbtt/src/lbtt-translate' - else - LBTT=lbtt - LBTT_TRANSLATE=lbtt-translate - fi - - # We always configure lbtt, even if it is not built to ensure it - # gets distributed properly. However, when someone uses - # --without-included-lbtt explicitely, we assume he might be trying - # to build Spot on a system where lbtt cannot build (e.g. MinGW) and - # where lbtt/configure will fail. So we don't run the sub-configure - # only in this case. On such a setup, "make distcheck" will break, - # but so probably isn't important. - if test "$with_included_lbtt" != no; then - AC_CONFIG_SUBDIRS([lbtt]) - fi - - AM_CONDITIONAL([WITH_INCLUDED_LBTT], [test "$with_included_lbtt" = yes]) - AC_SUBST([LBTT]) - AC_SUBST([LBTT_TRANSLATE]) -])