Initial revision
This commit is contained in:
commit
ababb9ff93
81 changed files with 49550 additions and 0 deletions
1
lbtt/AUTHORS
Normal file
1
lbtt/AUTHORS
Normal file
|
|
@ -0,0 +1 @@
|
|||
lbtt was written by Heikki Tauriainen <heikki.tauriainen@hut.fi>
|
||||
340
lbtt/COPYING
Normal file
340
lbtt/COPYING
Normal file
|
|
@ -0,0 +1,340 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
||||
201
lbtt/ChangeLog
Normal file
201
lbtt/ChangeLog
Normal file
|
|
@ -0,0 +1,201 @@
|
|||
2002-10-01 Heikki Tauriainen <heikki.tauriainen@hut.fi>
|
||||
|
||||
* Version 1.0.1 released.
|
||||
|
||||
2002-01 -- 2002-09-25 Heikki Tauriainen <heikki.tauriainen@hut.fi>
|
||||
|
||||
* 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<GraphEdgeContainer>::Edge&)
|
||||
(operator<<(ostream&, const Graph<GraphEdgeContainer>::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 <heikki.tauriainen@hut.fi>
|
||||
|
||||
* Version 1.0.0 released.
|
||||
229
lbtt/INSTALL
Normal file
229
lbtt/INSTALL
Normal file
|
|
@ -0,0 +1,229 @@
|
|||
Copyright 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software
|
||||
Foundation, Inc.
|
||||
|
||||
This file is free documentation; the Free Software Foundation gives
|
||||
unlimited permission to copy, distribute and modify it.
|
||||
|
||||
Basic Installation
|
||||
==================
|
||||
|
||||
These are generic installation instructions.
|
||||
|
||||
The `configure' shell script attempts to guess correct values for
|
||||
various system-dependent variables used during compilation. It uses
|
||||
those values to create a `Makefile' in each directory of the package.
|
||||
It may also create one or more `.h' files containing system-dependent
|
||||
definitions. Finally, it creates a shell script `config.status' that
|
||||
you can run in the future to recreate the current configuration, and a
|
||||
file `config.log' containing compiler output (useful mainly for
|
||||
debugging `configure').
|
||||
|
||||
It can also use an optional file (typically called `config.cache'
|
||||
and enabled with `--cache-file=config.cache' or simply `-C') that saves
|
||||
the results of its tests to speed up reconfiguring. (Caching is
|
||||
disabled by default to prevent problems with accidental use of stale
|
||||
cache files.)
|
||||
|
||||
If you need to do unusual things to compile the package, please try
|
||||
to figure out how `configure' could check whether to do them, and mail
|
||||
diffs or instructions to the address given in the `README' so they can
|
||||
be considered for the next release. If you are using the cache, and at
|
||||
some point `config.cache' contains results you don't want to keep, you
|
||||
may remove or edit it.
|
||||
|
||||
The file `configure.ac' (or `configure.in') is used to create
|
||||
`configure' by a program called `autoconf'. You only need
|
||||
`configure.ac' if you want to change it or regenerate `configure' using
|
||||
a newer version of `autoconf'.
|
||||
|
||||
The simplest way to compile this package is:
|
||||
|
||||
1. `cd' to the directory containing the package's source code and type
|
||||
`./configure' to configure the package for your system. If you're
|
||||
using `csh' on an old version of System V, you might need to type
|
||||
`sh ./configure' instead to prevent `csh' from trying to execute
|
||||
`configure' itself.
|
||||
|
||||
Running `configure' takes awhile. While running, it prints some
|
||||
messages telling which features it is checking for.
|
||||
|
||||
2. Type `make' to compile the package.
|
||||
|
||||
3. Optionally, type `make check' to run any self-tests that come with
|
||||
the package.
|
||||
|
||||
4. Type `make install' to install the programs and any data files and
|
||||
documentation.
|
||||
|
||||
5. You can remove the program binaries and object files from the
|
||||
source code directory by typing `make clean'. To also remove the
|
||||
files that `configure' created (so you can compile the package for
|
||||
a different kind of computer), type `make distclean'. There is
|
||||
also a `make maintainer-clean' target, but that is intended mainly
|
||||
for the package's developers. If you use it, you may have to get
|
||||
all sorts of other programs in order to regenerate files that came
|
||||
with the distribution.
|
||||
|
||||
Compilers and Options
|
||||
=====================
|
||||
|
||||
Some systems require unusual options for compilation or linking that
|
||||
the `configure' script does not know about. Run `./configure --help'
|
||||
for details on some of the pertinent environment variables.
|
||||
|
||||
You can give `configure' initial values for configuration parameters
|
||||
by setting variables in the command line or in the environment. Here
|
||||
is an example:
|
||||
|
||||
./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
|
||||
|
||||
*Note Defining Variables::, for more details.
|
||||
|
||||
Compiling For Multiple Architectures
|
||||
====================================
|
||||
|
||||
You can compile the package for more than one kind of computer at the
|
||||
same time, by placing the object files for each architecture in their
|
||||
own directory. To do this, you must use a version of `make' that
|
||||
supports the `VPATH' variable, such as GNU `make'. `cd' to the
|
||||
directory where you want the object files and executables to go and run
|
||||
the `configure' script. `configure' automatically checks for the
|
||||
source code in the directory that `configure' is in and in `..'.
|
||||
|
||||
If you have to use a `make' that does not support the `VPATH'
|
||||
variable, you have to compile the package for one architecture at a
|
||||
time in the source code directory. After you have installed the
|
||||
package for one architecture, use `make distclean' before reconfiguring
|
||||
for another architecture.
|
||||
|
||||
Installation Names
|
||||
==================
|
||||
|
||||
By default, `make install' will install the package's files in
|
||||
`/usr/local/bin', `/usr/local/man', etc. You can specify an
|
||||
installation prefix other than `/usr/local' by giving `configure' the
|
||||
option `--prefix=PATH'.
|
||||
|
||||
You can specify separate installation prefixes for
|
||||
architecture-specific files and architecture-independent files. If you
|
||||
give `configure' the option `--exec-prefix=PATH', the package will use
|
||||
PATH as the prefix for installing programs and libraries.
|
||||
Documentation and other data files will still use the regular prefix.
|
||||
|
||||
In addition, if you use an unusual directory layout you can give
|
||||
options like `--bindir=PATH' to specify different values for particular
|
||||
kinds of files. Run `configure --help' for a list of the directories
|
||||
you can set and what kinds of files go in them.
|
||||
|
||||
If the package supports it, you can cause programs to be installed
|
||||
with an extra prefix or suffix on their names by giving `configure' the
|
||||
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
|
||||
|
||||
Optional Features
|
||||
=================
|
||||
|
||||
Some packages pay attention to `--enable-FEATURE' options to
|
||||
`configure', where FEATURE indicates an optional part of the package.
|
||||
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
|
||||
is something like `gnu-as' or `x' (for the X Window System). The
|
||||
`README' should mention any `--enable-' and `--with-' options that the
|
||||
package recognizes.
|
||||
|
||||
For packages that use the X Window System, `configure' can usually
|
||||
find the X include and library files automatically, but if it doesn't,
|
||||
you can use the `configure' options `--x-includes=DIR' and
|
||||
`--x-libraries=DIR' to specify their locations.
|
||||
|
||||
Specifying the System Type
|
||||
==========================
|
||||
|
||||
There may be some features `configure' cannot figure out
|
||||
automatically, but needs to determine by the type of machine the package
|
||||
will run on. Usually, assuming the package is built to be run on the
|
||||
_same_ architectures, `configure' can figure that out, but if it prints
|
||||
a message saying it cannot guess the machine type, give it the
|
||||
`--build=TYPE' option. TYPE can either be a short name for the system
|
||||
type, such as `sun4', or a canonical name which has the form:
|
||||
|
||||
CPU-COMPANY-SYSTEM
|
||||
|
||||
where SYSTEM can have one of these forms:
|
||||
|
||||
OS KERNEL-OS
|
||||
|
||||
See the file `config.sub' for the possible values of each field. If
|
||||
`config.sub' isn't included in this package, then this package doesn't
|
||||
need to know the machine type.
|
||||
|
||||
If you are _building_ compiler tools for cross-compiling, you should
|
||||
use the `--target=TYPE' option to select the type of system they will
|
||||
produce code for.
|
||||
|
||||
If you want to _use_ a cross compiler, that generates code for a
|
||||
platform different from the build platform, you should specify the
|
||||
"host" platform (i.e., that on which the generated programs will
|
||||
eventually be run) with `--host=TYPE'.
|
||||
|
||||
Sharing Defaults
|
||||
================
|
||||
|
||||
If you want to set default values for `configure' scripts to share,
|
||||
you can create a site shell script called `config.site' that gives
|
||||
default values for variables like `CC', `cache_file', and `prefix'.
|
||||
`configure' looks for `PREFIX/share/config.site' if it exists, then
|
||||
`PREFIX/etc/config.site' if it exists. Or, you can set the
|
||||
`CONFIG_SITE' environment variable to the location of the site script.
|
||||
A warning: not all `configure' scripts look for a site script.
|
||||
|
||||
Defining Variables
|
||||
==================
|
||||
|
||||
Variables not defined in a site shell script can be set in the
|
||||
environment passed to `configure'. However, some packages may run
|
||||
configure again during the build, and the customized values of these
|
||||
variables may be lost. In order to avoid this problem, you should set
|
||||
them in the `configure' command line, using `VAR=value'. For example:
|
||||
|
||||
./configure CC=/usr/local2/bin/gcc
|
||||
|
||||
will cause the specified gcc to be used as the C compiler (unless it is
|
||||
overridden in the site shell script).
|
||||
|
||||
`configure' Invocation
|
||||
======================
|
||||
|
||||
`configure' recognizes the following options to control how it
|
||||
operates.
|
||||
|
||||
`--help'
|
||||
`-h'
|
||||
Print a summary of the options to `configure', and exit.
|
||||
|
||||
`--version'
|
||||
`-V'
|
||||
Print the version of Autoconf used to generate the `configure'
|
||||
script, and exit.
|
||||
|
||||
`--cache-file=FILE'
|
||||
Enable the cache: use and save the results of the tests in FILE,
|
||||
traditionally `config.cache'. FILE defaults to `/dev/null' to
|
||||
disable caching.
|
||||
|
||||
`--config-cache'
|
||||
`-C'
|
||||
Alias for `--cache-file=config.cache'.
|
||||
|
||||
`--quiet'
|
||||
`--silent'
|
||||
`-q'
|
||||
Do not print messages saying which checks are being made. To
|
||||
suppress all normal output, redirect it to `/dev/null' (any error
|
||||
messages will still be shown).
|
||||
|
||||
`--srcdir=DIR'
|
||||
Look for the package's source code in directory DIR. Usually
|
||||
`configure' can determine that directory automatically.
|
||||
|
||||
`configure' also accepts some other, not widely useful, options. Run
|
||||
`configure --help' for more details.
|
||||
|
||||
1
lbtt/Makefile.am
Normal file
1
lbtt/Makefile.am
Normal file
|
|
@ -0,0 +1 @@
|
|||
SUBDIRS = doc src
|
||||
191
lbtt/NEWS
Normal file
191
lbtt/NEWS
Normal file
|
|
@ -0,0 +1,191 @@
|
|||
lbtt NEWS -- history of user-visible changes. 01 Oct 2002
|
||||
Copyright (C) 2002 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.
|
||||
|
||||
Please send bug reports to <heikki.tauriainen@hut.fi>.
|
||||
|
||||
Version 1.0.1
|
||||
|
||||
* This release does not add new functionality to the program apart from
|
||||
some bug fixes and changes to sources to make them more compatible
|
||||
with versions 3.1.x and 3.2 of gcc.
|
||||
|
||||
Version 1.0.0
|
||||
|
||||
* lbtt is now packaged using GNU Autotools.
|
||||
|
||||
* The distribution includes sources for documentation that can be
|
||||
built in `info', `dvi' and `html' formats using GNU texinfo. The
|
||||
documentation is also available at the program's home page at
|
||||
<http://www.tcs.hut.fi/%7Ehtauriai/lbtt/>.
|
||||
|
||||
* lbtt now has direct support for the following binary LTL formula
|
||||
operators:
|
||||
---------------------------------------------------------------
|
||||
operator symbol used in input symbol used in
|
||||
files for LTL-to-Büchi messages
|
||||
translators
|
||||
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
logical "exclusive or"
|
||||
^ xor
|
||||
temporal "weak until"
|
||||
W W
|
||||
temporal "strong release" (dual of "weak until")
|
||||
M M
|
||||
temporal "before"
|
||||
B B
|
||||
|
||||
The ^ operator is also accepted in the transition guard formulas of the
|
||||
Büchi automata that are given to lbtt as input.
|
||||
|
||||
Please see the included documentation for a reference on the exact
|
||||
semantics of these operators.
|
||||
|
||||
* Changes in program behavior:
|
||||
|
||||
- The default priority for LTL formula operators is now 0 (instead of
|
||||
10 as in previous versions).
|
||||
|
||||
- The default interval for changing state spaces is now one test round
|
||||
(instead of 10 as in previous versions).
|
||||
|
||||
- The sequences of random formulas and state spaces generated by lbtt
|
||||
should now be independent of each other, i.e., changing the formula
|
||||
generation parameters does not affect the sequence of generated state
|
||||
spaces and vice versa. Unfortunately, the changes required to
|
||||
implement this functionality make the test sequences obtained using
|
||||
previous versions of the tool irreproducible with version 1.0.0. In
|
||||
addition, the random seed must now be set separately for the formula
|
||||
and state space generation algorithms.
|
||||
|
||||
* Changes in program configuration:
|
||||
|
||||
- lbtt supports the following new configuration file and command line
|
||||
options (`O' -- command line option, `C' -- equivalent configuration
|
||||
file option (SectionName.OptionName), `D' -- description):
|
||||
|
||||
O: --[no]comparisontest
|
||||
C: GlobalOptions.ComparisonTest = Yes | No
|
||||
D: Enable or disable the model checking result cross-comparison
|
||||
test
|
||||
|
||||
O: --[no]consistencytest
|
||||
C: GlobalOptions.ConsistencyTest = Yes | No
|
||||
D: Enable or disable the model checking result consistency test
|
||||
|
||||
O: --[no]intersectiontest
|
||||
C: GlobalOptions.IntersectionTest = Yes | No
|
||||
D: Enable or disable the Büchi automata intersection emptiness
|
||||
test
|
||||
|
||||
O: --profile
|
||||
D: Disable all of the above automata correctness tests
|
||||
|
||||
O: --skip=N
|
||||
D: Skip the first N test rounds
|
||||
|
||||
O: --nogeneratennf
|
||||
C: FormulaOptions.GenerateMode = Normal
|
||||
D: Do not force random formulas to be generated in negation
|
||||
normal form
|
||||
|
||||
O: --nooutputnnf
|
||||
C: FormulaOptions.OutputMode = Normal
|
||||
D: Do not rewrite LTL formulas into negation normal form before
|
||||
passing them to LTL-to Büchi translators
|
||||
|
||||
O: --quiet, --silent
|
||||
D: Run all tests silently without interruption
|
||||
|
||||
O: --showconfig
|
||||
D: Display program configuration and exit
|
||||
|
||||
O: --showoperatordistribution
|
||||
D: Compute the expected distribution of random formula operators
|
||||
and display the distribution with other configuration
|
||||
information
|
||||
|
||||
O: --xorpriority=PRIORITY
|
||||
C: FormulaOptions.XorPriority = PRIORITY
|
||||
D: Set priority for the logical "exclusive or" operator
|
||||
|
||||
O: --weakuntilpriority=PRIORITY
|
||||
C: FormulaOptions.WeakUntilPriority = PRIORITY
|
||||
D: Set priority for the temporal "weak until" operator
|
||||
|
||||
O: --strongreleasepriority=PRIORITY
|
||||
C: FormulaOptions.StrongReleasePriority = PRIORITY
|
||||
D: Set priority for the temporal "strong release" operator
|
||||
|
||||
O: --beforepriority=PRIORITY
|
||||
C: FormulaOptions.BeforePriority = PRIORITY
|
||||
D: Set priority for the temporal "before" operator
|
||||
|
||||
- The following configuration file and command line options have been
|
||||
renamed in lbtt version 1.0.0:
|
||||
|
||||
Command line options:
|
||||
--synchronousproduct => --modelcheck
|
||||
--localproduct => --localmodelcheck
|
||||
--globalproduct => --globalmodelcheck
|
||||
--randomseed => --formularandomseed,
|
||||
--statespacerandomseed
|
||||
--formulalength => --formulasize
|
||||
--vpriority => --releasepriority
|
||||
|
||||
Configuration file options:
|
||||
GlobalOptions.FormulaChangeInterval
|
||||
=> FormulaOptions.ChangeInterval
|
||||
GlobalOptions.StateSpaceChangeInterval
|
||||
=> StateSpaceOptions.ChangeInterval
|
||||
GlobalOptions.SynchronousProduct
|
||||
=> GlobalOptions.ModelCheck
|
||||
GlobalOptions.RandomSeed => FormulaOptions.RandomSeed
|
||||
StateSpaceOptions.RandomSeed
|
||||
FormulaOptions.Length => FormulaOptions.Size
|
||||
FormulaOptions.VPriority => FormulaOptions.ReleasePriority
|
||||
|
||||
Please see the included documentation for more information on these
|
||||
options.
|
||||
|
||||
* Changes in the user command interface:
|
||||
|
||||
- lbtt's internal command interface now supports redirecting the
|
||||
output of some internal commands to a pipe to be processed by an
|
||||
external program. This can be achieved by ending the command line
|
||||
with `| <command>'.
|
||||
|
||||
- If using random or enumerated paths as state spaces for the tests,
|
||||
the user commands `resultanalysis' and `eval' now support referring
|
||||
to results computed using lbtt's internal model checking algorithm.
|
||||
|
||||
- The tool includes a new user command `consistencyanalysis' that can
|
||||
be used for analyzing failures in the model checking result
|
||||
consistency check.
|
||||
|
||||
- The user command `resultanalysis' now accepts an optional state
|
||||
space identifier which can be used to force the analysis to be
|
||||
performed in a certain state of the state space.
|
||||
|
||||
- The user command `pathinconsistencies' has been removed. (The `eval'
|
||||
command provides equivalent functionality.)
|
||||
|
||||
- lbtt now supports the GNU readline library that provides command
|
||||
line editing enhancements when using the user commands. The support
|
||||
can be optionally disabled by running the `configure' script with
|
||||
the parameter `--without-readline'.
|
||||
|
||||
* The additional programs `aasa_lbt' and `spin_lbt' have been replaced with
|
||||
a common `lbtt-translate' utility. This program does not implement an
|
||||
LTL-to-Büchi translation algorithm, however; a free LTL-to-Büchi
|
||||
translator that provides similar functionality to the `aasa_lbt' tool
|
||||
included in previous lbtt releases can be obtained via
|
||||
<http://www.tcs.hut.fi/Software/maria/tools/lbt/>.
|
||||
85
lbtt/README
Normal file
85
lbtt/README
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
lbtt version 1.0.1
|
||||
------------------
|
||||
|
||||
lbtt is a tool for testing programs which translate formulas
|
||||
expressed in propositional linear temporal logic (LTL) into
|
||||
Büchi automata. The goal of the tool is to assist in the
|
||||
correct implementation of LTL-to-Büchi translation algorithms
|
||||
by providing an automated testing environment for LTL-to-Büchi
|
||||
translators. Additionally, the testing environment can be used
|
||||
for very basic profiling of different LTL-to-Büchi translators
|
||||
to evaluate their performance.
|
||||
|
||||
The latest version of the program is available at
|
||||
<http://www.tcs.hut.fi/%7Ehtauriai/lbtt/>.
|
||||
|
||||
lbtt is free software, you may change and redistribute it under
|
||||
the terms of the GNU General Public License. lbtt comes with
|
||||
NO WARRANTY. See the file COPYING for details.
|
||||
|
||||
|
||||
Quick installation instructions:
|
||||
--------------------------------
|
||||
|
||||
The basic procedure to build lbtt, the associated tools
|
||||
and GNU info documentation is to enter the following
|
||||
commands in the top-level package directory (the directory
|
||||
that contains this file):
|
||||
|
||||
./configure
|
||||
make
|
||||
|
||||
These commands should create two executable files
|
||||
(`lbtt' and `lbtt-translate') in the `src' subdirectory
|
||||
and GNU info documentation under the `doc' subdirectory.
|
||||
The program and documentation can be used directly in
|
||||
their build directories. Optionally, the program binaries
|
||||
and documentation can be installed in their default
|
||||
location (under `/usr/local/') by entering the command
|
||||
|
||||
make install
|
||||
|
||||
after the build process is complete. (To change the
|
||||
default installation directory, the `configure' script
|
||||
should be invoked with an appropriate `--prefix=PATH'
|
||||
option before running `make'. Please see the file INSTALL
|
||||
for generic information about running `configure'.)
|
||||
|
||||
|
||||
Documentation:
|
||||
--------------
|
||||
|
||||
The default build procedure builds the program documentation
|
||||
in the `doc' subdirectory only in `info' format. Assuming
|
||||
you have the GNU Info documentation browser installed, the
|
||||
documentation can be viewed by running the command
|
||||
`info -f doc/lbtt.info' after the program build is
|
||||
complete.
|
||||
|
||||
The documentation can be optionally generated in DVI
|
||||
or HTML formats using the TeX typesetting program and the
|
||||
GNU texinfo tools. To create DVI documentation, run the
|
||||
command
|
||||
|
||||
make dvi
|
||||
|
||||
in the top-level package directory. If you have TeX and
|
||||
the GNU texinfo tools properly installed, this command
|
||||
should generate a file `lbtt.dvi' in the `doc' subdirectory.
|
||||
|
||||
The documentation can be also generated in HTML format by
|
||||
running `makeinfo --html' on the file `lbtt.texi' in the
|
||||
`doc' subdirectory.
|
||||
|
||||
Note: The generated DVI or HTML files refer to two
|
||||
auxiliary picture files (`testprocedure.EXT' and
|
||||
`intersectioncheck.EXT', where EXT stands for `eps' for
|
||||
DVI documentation, `png' for HTML documentation)
|
||||
residing in the `doc' subdirectory. To see the figures
|
||||
included in the documentation correctly, make sure that
|
||||
the program used for viewing the documentation can find
|
||||
these files when needed.
|
||||
|
||||
The documentation is also available in various formats
|
||||
at the program's home page at
|
||||
<http://www.tcs.hut.fi/%7Ehtauriai/lbtt/>.
|
||||
190
lbtt/configure.ac
Normal file
190
lbtt/configure.ac
Normal file
|
|
@ -0,0 +1,190 @@
|
|||
# Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_PREREQ([2.53])
|
||||
AC_INIT([lbtt], [1.0.1], [heikki.tauriainen@hut.fi])
|
||||
AC_REVISION([Revision: 1.1])
|
||||
AC_CONFIG_SRCDIR([src/main.cc])
|
||||
AM_INIT_AUTOMAKE
|
||||
AM_CONFIG_HEADER([config.h])
|
||||
|
||||
|
||||
|
||||
# Checks for programs.
|
||||
|
||||
AC_PROG_CC
|
||||
AC_PROG_CPP
|
||||
AC_PROG_CXX
|
||||
AC_PROG_CXXCPP
|
||||
AM_PROG_LEX
|
||||
AC_PROG_YACC
|
||||
|
||||
YACC="${YACC} -d"
|
||||
|
||||
|
||||
|
||||
# Check whether the user has explicitly disabled the test for the availability
|
||||
# of the GNU readline library.
|
||||
|
||||
readline=yes
|
||||
|
||||
AC_ARG_WITH([readline],
|
||||
[AC_HELP_STRING([--without-readline],
|
||||
[disable check for the GNU readline library])],
|
||||
[if test x"${withval}" = xno; then readline=no; fi])
|
||||
|
||||
|
||||
|
||||
# Check for the availability of headers.
|
||||
|
||||
AC_HEADER_STDC
|
||||
AC_CHECK_HEADERS([fcntl.h obstack.h stdlib.h unistd.h])
|
||||
|
||||
# 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 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.
|
||||
|
||||
# Check for the availability of the slist header (an extension to the C++
|
||||
# Standard Template Library). (In GCC 3.x the header is in the ext/
|
||||
# subdirectory of the directory containing the standard C++ headers.)
|
||||
|
||||
AC_MSG_CHECKING([for slist])
|
||||
for slist_header in slist ext/slist no; do
|
||||
if test "${slist_header}" != no; then
|
||||
AC_TRY_CPP([#include <${slist_header}>], [break])
|
||||
fi
|
||||
done
|
||||
|
||||
# Try to determine the C++ namespace in which the class slist resides.
|
||||
# (For example, GCC versions 3.1, 3.1.1 and 3.2 put slist into the
|
||||
# __gnu_cxx namespace.)
|
||||
|
||||
if test "${slist_header}" != no; then
|
||||
for slist_namespace in std __gnu_cxx error; do
|
||||
if test "${slist_namespace}" != error; then
|
||||
AC_TRY_LINK([#include <${slist_header}>],
|
||||
[${slist_namespace}::slist<int> s;],
|
||||
[break])
|
||||
fi
|
||||
done
|
||||
if test "${slist_namespace}" != error; then
|
||||
AC_MSG_RESULT([header <${slist_header}>, typename ${slist_namespace}::slist])
|
||||
AC_DEFINE([HAVE_SLIST],
|
||||
[1],
|
||||
[Define to 1 if you have the <slist> or <ext/slist> header file.])
|
||||
AC_DEFINE_UNQUOTED([SLIST_NAMESPACE],
|
||||
[${slist_namespace}],
|
||||
[Define as the name of the C++ namespace containing slist.])
|
||||
AC_SUBST([INCLUDE_SLIST_HEADER], ["#include <${slist_header}>"])
|
||||
else
|
||||
slist_header=no
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "${slist_header}" = no; then
|
||||
AC_MSG_RESULT([no])
|
||||
|
||||
# Check for the availability of the single_client_alloc memory allocator
|
||||
# available in some compilers supporting the SGI extensions to the Standard
|
||||
# template library (for example, pre-3.0 versions of gcc). This check is not
|
||||
# needed if no suitable slist header was found above, since in that case the
|
||||
# compiler does not support the SGI extensions.
|
||||
|
||||
else
|
||||
AC_MSG_CHECKING([for single_client_alloc])
|
||||
AC_TRY_LINK([#include <${slist_header}>],
|
||||
[using namespace std;
|
||||
${slist_namespace}::slist<int, single_client_alloc> s;],
|
||||
[AC_MSG_RESULT([yes])
|
||||
AC_DEFINE([HAVE_SINGLE_CLIENT_ALLOC],
|
||||
[1],
|
||||
[Define if your C++ compiler supports the single_client_allocator memory allocator.])],
|
||||
[AC_MSG_RESULT([no])])
|
||||
fi
|
||||
|
||||
AC_LANG(C)
|
||||
|
||||
AC_C_CONST
|
||||
AC_C_INLINE
|
||||
|
||||
|
||||
|
||||
# Checks for library functions.
|
||||
|
||||
AC_TYPE_SIGNAL
|
||||
AC_CHECK_FUNCS([mkdir strchr strtod strtol strtoul getopt_long])
|
||||
if test x"${ac_cv_func_getopt_long}" = xno; then
|
||||
AC_LIBOBJ([getopt])
|
||||
AC_LIBOBJ([getopt1])
|
||||
AC_CHECK_HEADERS([libintl.h string.h strings.h])
|
||||
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_TRY_LINK([#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=""
|
||||
fi
|
||||
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
|
||||
3
lbtt/doc/Makefile.am
Normal file
3
lbtt/doc/Makefile.am
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
info_TEXINFOS = lbtt.texi
|
||||
lbtt_TEXINFOS = gpl.texi
|
||||
EXTRA_DIST = intersectioncheck.txt intersectioncheck.eps intersectioncheck.png testprocedure.txt testprocedure.eps testprocedure.png
|
||||
392
lbtt/doc/gpl.texi
Normal file
392
lbtt/doc/gpl.texi
Normal file
|
|
@ -0,0 +1,392 @@
|
|||
@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.
|
||||
|
||||
@iftex
|
||||
@heading NO WARRANTY
|
||||
@end iftex
|
||||
@ifinfo
|
||||
@center NO WARRANTY
|
||||
@end ifinfo
|
||||
|
||||
@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.
|
||||
747
lbtt/doc/intersectioncheck.eps
Normal file
747
lbtt/doc/intersectioncheck.eps
Normal file
|
|
@ -0,0 +1,747 @@
|
|||
%!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
|
||||
BIN
lbtt/doc/intersectioncheck.png
Normal file
BIN
lbtt/doc/intersectioncheck.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
55
lbtt/doc/intersectioncheck.txt
Normal file
55
lbtt/doc/intersectioncheck.txt
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
,,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
: 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 #
|
||||
#################
|
||||
4771
lbtt/doc/lbtt.texi
Normal file
4771
lbtt/doc/lbtt.texi
Normal file
File diff suppressed because it is too large
Load diff
769
lbtt/doc/testprocedure.eps
Normal file
769
lbtt/doc/testprocedure.eps
Normal file
|
|
@ -0,0 +1,769 @@
|
|||
%!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
|
||||
BIN
lbtt/doc/testprocedure.png
Normal file
BIN
lbtt/doc/testprocedure.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
54
lbtt/doc/testprocedure.txt
Normal file
54
lbtt/doc/testprocedure.txt
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
,,,,,,,,,,,,,,,
|
||||
: State space :
|
||||
'''''''''''''''
|
||||
|
|
||||
| ,,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,,,,,,,,,,,,
|
||||
| : LTL formula `f' :_____ : Negated LTL formula `!f' :
|
||||
| '''''''T''''''T'''' \ ___'''''''T'''''''''''T''''''''
|
||||
| | \ ___X / |
|
||||
| | \ ___/ \______ / |
|
||||
| | ___X X_______ |
|
||||
| | / \ / \ |
|
||||
| V V V V V V
|
||||
| :::::::::::::::: :::::::::::::::: ::::::::::::::::
|
||||
| : LTL-to-Buchi : : LTL-to-Buchi : . . . : LTL-to-Buchi :
|
||||
| : translator 1 : : translator 2 : : translator n :
|
||||
| :::::::::::::::: :::::::::::::::: ::::::::::::::::
|
||||
| | | | | / |
|
||||
| | | | | / |
|
||||
| V V | | V V
|
||||
| ,,,,,,,,,,,,, ,,,,,,,,,,,,,, | | ,,,,,,,,,,,,, ,,,,,,,,,,,,,,
|
||||
| : Automaton : : Automaton : | | : Automaton : : Automaton :
|
||||
| : 1 for `f' : : 1 for `!f' : | | : n for `f' : : n for `!f' :
|
||||
| ''T'''''''''' '''T'''''''''' | | ''''''''''T'' '''''''''''T''
|
||||
| | _/ V V \_____ \_
|
||||
| | / ,,,,,,,,,,,,, ,,,,,,,,,,,,,, \ \
|
||||
| | | : Automaton : : Automaton : | |
|
||||
| | | : 2 for `f' : : 2 for `!f' : | |
|
||||
| | | '''''''''T''' '''''''T'''''' | |
|
||||
| ! ! ! ! ! |
|
||||
|__________________________________________________________ |
|
||||
| . \ . \ . \ . \ . \ |
|
||||
| : \ : \ : \ : \ : \ |
|
||||
| | \ | \ | \ | \ | \ |
|
||||
V V V V V V V V V V V V
|
||||
::::::::: ::::::::: ::::::::: ::::::::: ::::::::: :::::::::
|
||||
: Model : : Model : : Model : : Model : : Model : : Model :
|
||||
: check : : check : : check : : check : : check : : check :
|
||||
::::::::: ::::::::: ::::::::: ::::::::: ::::::::: :::::::::
|
||||
| \ | \ / | | \ / | / |
|
||||
| \ | \ / | | \ / | / |
|
||||
| \ | \ / | | \ / | / |
|
||||
| V V X V V X V V |
|
||||
| ############### / \ ############### / \ ############### |
|
||||
| # Consistency # | | # Consistency # | | # Consistency # |
|
||||
| # check # | | # check # | | # check # |
|
||||
| ############### | | ############### | | ############### |
|
||||
\______ | \_______ _______/ | ______/
|
||||
\ | \ / | /
|
||||
| | X | |
|
||||
| | _/ \_ | |
|
||||
V V V V V V
|
||||
######################### #########################
|
||||
# Cross-comparison test # # Cross-comparison test #
|
||||
######################### #########################
|
||||
6257
lbtt/doc/texinfo.tex
Normal file
6257
lbtt/doc/texinfo.tex
Normal file
File diff suppressed because it is too large
Load diff
159
lbtt/src/Alloc.h
Normal file
159
lbtt/src/Alloc.h
Normal file
|
|
@ -0,0 +1,159 @@
|
|||
/*
|
||||
* Copyright (C) 1999, 2000, 2001, 2002
|
||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef ALLOC_H
|
||||
#define ALLOC_H
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#ifdef HAVE_SINGLE_CLIENT_ALLOC
|
||||
#define ALLOC(typename) single_client_alloc
|
||||
#else
|
||||
#define ALLOC(typename) allocator<typename>
|
||||
#endif /* HAVE_SINGLE_CLIENT_ALLOC */
|
||||
|
||||
#ifdef HAVE_OBSTACK_H
|
||||
|
||||
#include <obstack.h>
|
||||
#include <cstdlib>
|
||||
#include <new>
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* A wrapper class for allocating memory through an obstack.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
class ObstackAllocator
|
||||
{
|
||||
public:
|
||||
ObstackAllocator(); /* Constructor. */
|
||||
|
||||
~ObstackAllocator(); /* Destructor. */
|
||||
|
||||
void* alloc(int size); /* Allocates memory. */
|
||||
|
||||
void free(void* obj); /* Deallocates memory. */
|
||||
|
||||
static void failure(); /* Callback function for
|
||||
* reporting a memory
|
||||
* allocation failure.
|
||||
*/
|
||||
private:
|
||||
ObstackAllocator(const ObstackAllocator&); /* Prevent copying and */
|
||||
ObstackAllocator& operator= /* assignment of */
|
||||
(const ObstackAllocator&); /* ObstackAllocator
|
||||
* objects.
|
||||
*/
|
||||
|
||||
struct obstack store; /* The obstack. */
|
||||
};
|
||||
|
||||
#define obstack_chunk_alloc std::malloc
|
||||
#define obstack_chunk_free std::free
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Inline function definitions for class ObstackAllocator.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* ========================================================================= */
|
||||
inline ObstackAllocator::ObstackAllocator()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Constructor for class ObstackAllocator.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
obstack_init(&store);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline ObstackAllocator::~ObstackAllocator()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Destructor for class ObstackAllocator.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
obstack_free(&store, NULL);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline void* ObstackAllocator::alloc(int size)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Interface to the memory allocator.
|
||||
*
|
||||
* Argument: size -- Number of bytes to allocate.
|
||||
*
|
||||
* Returns: A pointer to the beginning of the newly allocated memory.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return obstack_alloc(&store, size);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline void ObstackAllocator::free(void* obj)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Interface to the memory deallocation function.
|
||||
*
|
||||
* Argument: obj -- A pointer to the object to deallocate. (Because the
|
||||
* underlying memory allocator is an obstack, freeing
|
||||
* an object also releases all objects allocated after
|
||||
* the given object.)
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
obstack_free(&store, obj);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline void ObstackAllocator::failure()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Callback function for reporting memory allocation failures.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
|
||||
#endif /* HAVE_OBSTACK_H */
|
||||
|
||||
#endif /* !ALLOC_H */
|
||||
457
lbtt/src/BitArray.cc
Normal file
457
lbtt/src/BitArray.cc
Normal file
|
|
@ -0,0 +1,457 @@
|
|||
/*
|
||||
* Copyright (C) 1999, 2000, 2001, 2002
|
||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma implementation
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#include <config.h>
|
||||
#ifdef HAVE_SSTREAM
|
||||
#include <sstream>
|
||||
#else
|
||||
#include <strstream>
|
||||
#endif /* HAVE_SSTREAM */
|
||||
#include "BitArray.h"
|
||||
#include "Exception.h"
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* `bit_counts[i]' tells the number of 1-bits in the 8-bit integer `i'.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
const unsigned char BitArray::bit_counts[] =
|
||||
{0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2,
|
||||
3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3,
|
||||
3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3,
|
||||
4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4,
|
||||
3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5,
|
||||
6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4,
|
||||
4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5,
|
||||
6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 2, 3, 3, 4, 3, 4, 4, 5,
|
||||
3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 3,
|
||||
4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6,
|
||||
6, 7, 6, 7, 7, 8};
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Function definitions for class BitArray.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* ========================================================================= */
|
||||
BitArray::BitArray(const unsigned long int size)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Constructor for class BitArray. Creates a bit array of a
|
||||
* given size.
|
||||
*
|
||||
* Argument: size -- Number of bits to allocate.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
unsigned long int bsize = (size + 7) >> 3;
|
||||
|
||||
bits = new unsigned char[bsize];
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
BitArray::~BitArray()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Destructor for class BitArray. Deallocates the memory used by
|
||||
* the bit array.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
delete[] bits;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
void BitArray::copy
|
||||
(const BitArray& bitarray, const unsigned long int bit_count)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Copy the first `bit_count' bits from `bitarray' to `this'
|
||||
* BitArray object. (As a side effect, the capacity of `this'
|
||||
* bit array is set to `bit_count'.)
|
||||
*
|
||||
* Argument: bitarray -- Reference to a constant bit array which should
|
||||
* be copied.
|
||||
* bit_count -- Number of bits to copy.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
if (this != &bitarray)
|
||||
{
|
||||
delete[] bits;
|
||||
|
||||
unsigned long int bsize = (bit_count + 7) >> 3;
|
||||
|
||||
bits = new unsigned char[bsize];
|
||||
memcpy(static_cast<void*>(bits), static_cast<const void*>(bitarray.bits),
|
||||
bsize);
|
||||
}
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
bool BitArray::equal
|
||||
(const BitArray& bitarray, const unsigned long int bit_count) const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Test whether the first `bit_count' bits of `this' BitArray
|
||||
* are equal to the correspoding bits of `bitarray'.
|
||||
*
|
||||
* Argument: bitarray -- Target of the comparison.
|
||||
* bit_count -- Number of bits to compare.
|
||||
*
|
||||
* Returns: `true' if the compared bits agree and `false' otherwise.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
if (bit_count > 0)
|
||||
{
|
||||
unsigned long int bsize = bit_count >> 3;
|
||||
|
||||
for (unsigned long int i = 0; i < bsize; ++i)
|
||||
{
|
||||
if (bits[i] != bitarray.bits[i])
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((bit_count & 0x07) == 0)
|
||||
return true;
|
||||
|
||||
unsigned char mask = (1 << (bit_count & 0x07)) - 1;
|
||||
|
||||
if (((bits[bsize] ^ bitarray.bits[bsize]) & mask) != 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
BitArray& BitArray::bitwiseOr
|
||||
(const BitArray& bitarray, const unsigned long int bit_count)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Compute the bitwise disjunction of the first `bit_count' bits
|
||||
* of two BitArrays (storing the result in `this' BitArray).
|
||||
*
|
||||
* Arguments: bitarray -- A reference to a constant BitArray.
|
||||
* bit_count -- Number of bits to include in the computation.
|
||||
*
|
||||
* Returns: A reference to `this' BitArray.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
unsigned long int bsize = bit_count >> 3;
|
||||
|
||||
for (unsigned long int i = 0; i < bsize; ++i)
|
||||
bits[i] |= bitarray.bits[i];
|
||||
|
||||
if ((bit_count & 0x07) != 0)
|
||||
bits[bsize] |= (bitarray.bits[bsize] & ((1 << (bit_count & 7)) - 1));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
BitArray& BitArray::bitwiseAnd
|
||||
(const BitArray& bitarray, const unsigned long int bit_count)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Compute the bitwise conjunction of the first `bit_count' bits
|
||||
* of two BitArrays (storing the result in `this' BitArray).
|
||||
*
|
||||
* Arguments: bitarray -- A reference to a constant BitArray.
|
||||
* bit_count -- Number of bits to include in the computation.
|
||||
*
|
||||
* Returns: A reference to `this' BitArray.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
unsigned long int bsize = bit_count >> 3;
|
||||
|
||||
for (unsigned long int i = 0; i < bsize; ++i)
|
||||
bits[i] &= bitarray.bits[i];
|
||||
|
||||
if ((bit_count & 0x07) != 0)
|
||||
bits[bsize] &= (bitarray.bits[bsize] | ~((1 << (bit_count & 7)) - 1));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
BitArray& BitArray::bitwiseXor
|
||||
(const BitArray& bitarray, const unsigned long int bit_count)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Compute the bitwise "exclusive or" of the first `bit_count'
|
||||
* bits of two BitArrays (storing the result in `this'
|
||||
* BitArray).
|
||||
*
|
||||
* Arguments: bitarray -- A reference to a constant BitArray.
|
||||
* bit_count -- Number of bits to include in the computation.
|
||||
*
|
||||
* Returns: A reference to `this' BitArray.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
unsigned long int bsize = bit_count >> 3;
|
||||
|
||||
for (unsigned long int i = 0; i < bsize; ++i)
|
||||
bits[i] ^= bitarray.bits[i];
|
||||
|
||||
if ((bit_count & 0x07) != 0)
|
||||
bits[bsize] ^= (bitarray.bits[bsize] & ((1 << (bit_count & 7)) - 1));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
bool BitArray::subset
|
||||
(const BitArray& bitarray, const unsigned long int bit_count) const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Tests whether the first `bit_count' bits of `this' BitArray
|
||||
* are set also in `bitarray'.
|
||||
*
|
||||
* Argument bitarray -- Target of the comparison.
|
||||
* bit_count -- Number of bits to test.
|
||||
*
|
||||
* Returns: Truth value depending on the result of the test.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
if (bit_count > 0)
|
||||
{
|
||||
unsigned long int bsize = bit_count >> 3;
|
||||
|
||||
for (unsigned long int i = 0; i < bsize; ++i)
|
||||
{
|
||||
if ((bits[i] & ~bitarray.bits[i]) != 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((bit_count & 0x07) == 0)
|
||||
return true;
|
||||
|
||||
unsigned char mask = (1 << (bit_count & 7)) - 1;
|
||||
|
||||
if (((bits[bsize] & ~bitarray.bits[bsize]) & mask) != 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
unsigned long int BitArray::count(const unsigned long int bit_count) const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Counts the number of 1-bits in the first `bit_count' bits of
|
||||
* the BitArray.
|
||||
*
|
||||
* Arguments: bit_count -- Number of bits to include in the computation.
|
||||
*
|
||||
* Returns: Number of 1-bits in the first `bit_count' bits of the
|
||||
* BitArray.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
if (bit_count == 0)
|
||||
return 0;
|
||||
|
||||
unsigned long int bsize = bit_count >> 3;
|
||||
unsigned long int result = 0;
|
||||
|
||||
for (unsigned long int i = 0; i < bsize; ++i)
|
||||
result += bit_counts[bits[i]];
|
||||
|
||||
if ((bit_count & 0x07) == 0)
|
||||
return result;
|
||||
|
||||
unsigned char mask = (1 << (bit_count & 7)) - 1;
|
||||
|
||||
result += bit_counts[bits[bsize] & mask];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
unsigned long int BitArray::hammingDistance
|
||||
(const BitArray& bitarray, const unsigned long int bit_count) const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Computes the Hamming distance (the number of bit positions in
|
||||
* which two bit vectors differ) between two bit vectors
|
||||
* comprising the first `bit_count' bits of two bit arrays.
|
||||
*
|
||||
* Argument: bitarray -- A reference to a constant BitArray.
|
||||
* bit_count -- Number of bits to include in the computation.
|
||||
*
|
||||
* Returns: The Hamming distance between the leftmost `bit_count' bits of
|
||||
* two BitArrays.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
unsigned long int result = 0;
|
||||
unsigned long int bsize = bit_count >> 3;
|
||||
|
||||
for (unsigned long int i = 0; i < bsize; ++i)
|
||||
result += bit_counts[bits[i] ^ bitarray.bits[i]];
|
||||
|
||||
if ((bit_count & 0x07) == 0)
|
||||
return result;
|
||||
|
||||
unsigned char mask = (1 << (bit_count & 7)) - 1;
|
||||
|
||||
result += bit_counts[(bits[bsize] ^ bitarray.bits[bsize]) & mask];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
void BitArray::flip(const unsigned long int bit_count)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Changes the state of the first `bit_count' bits in the
|
||||
* bit array.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
unsigned long bsize = (bit_count + 7) >> 3;
|
||||
|
||||
for (unsigned long int i = 0; i < bsize; ++i)
|
||||
bits[i] ^= 0xFF;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
unsigned long int BitArray::find(const unsigned long int max_count) const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Finds the first 1-bit in the bit array with an index less
|
||||
* than `max_count'.
|
||||
*
|
||||
* Arguments: max_count -- Upper bound for the bit index.
|
||||
*
|
||||
* Returns: Index of the first 1-bit with an index less than `max_count'
|
||||
* or `max_count' if there are no 1-bits with such an index in
|
||||
* the array.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
unsigned long int bsize = (max_count + 7) >> 3;
|
||||
unsigned long int i;
|
||||
for (i = 0; i < bsize && bits[i] == 0; ++i)
|
||||
;
|
||||
|
||||
if (i == max_count)
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
430
lbtt/src/BitArray.h
Normal file
430
lbtt/src/BitArray.h
Normal file
|
|
@ -0,0 +1,430 @@
|
|||
/*
|
||||
* Copyright (C) 1999, 2000, 2001, 2002
|
||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef BITARRAY_H
|
||||
#define BITARRAY_H
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma interface
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#include <config.h>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Bitset;
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* A class for arrays of bits.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
class BitArray
|
||||
{
|
||||
public:
|
||||
explicit BitArray /* Constructor. */
|
||||
(const unsigned long int size = 0);
|
||||
|
||||
~BitArray(); /* Destructor. */
|
||||
|
||||
private:
|
||||
BitArray(const BitArray& bitarray); /* Prevent copying and */
|
||||
BitArray& operator=(const BitArray& bitarray); /* assignment of
|
||||
* BitArray objects.
|
||||
* (Copying and
|
||||
* assignment requires
|
||||
* information about
|
||||
* the number of bits in
|
||||
* the bit array; this
|
||||
* information is not
|
||||
* included in the
|
||||
* object itself.)
|
||||
*/
|
||||
|
||||
public:
|
||||
bool operator[](const unsigned long int index) /* Tell the value of a */
|
||||
const; /* bit in a given array */
|
||||
bool test(const unsigned long int index) const; /* index.
|
||||
*/
|
||||
|
||||
|
||||
void copy /* Duplicate a bit */
|
||||
(const BitArray& bitarray, /* array. */
|
||||
const unsigned long int bit_count);
|
||||
|
||||
void copy(const Bitset& bitset); /* Copy bits from a */
|
||||
BitArray& operator=(const Bitset& bitset); /* Bitset. */
|
||||
|
||||
bool equal /* Test whether the */
|
||||
(const BitArray& bitarray, /* first `bit_count' */
|
||||
const unsigned long int bit_count) const; /* bits of two BitArrays
|
||||
* are equal.
|
||||
*/
|
||||
|
||||
bool equal(const Bitset& bitset) const; /* Compare a BitArray to */
|
||||
bool operator==(const Bitset& bitset) const; /* a Bitset. */
|
||||
|
||||
BitArray& bitwiseOr /* Compute the bitwise */
|
||||
(const BitArray& bitarray, /* disjunction of the */
|
||||
const unsigned long int bit_count); /* first `bit_count'
|
||||
* bits of two
|
||||
* BitArrays.
|
||||
*/
|
||||
|
||||
BitArray& bitwiseAnd /* Compute the bitwise */
|
||||
(const BitArray& bitarray, /* conjunction of the */
|
||||
const unsigned long int bit_count); /* first `bit_count'
|
||||
* bits of two
|
||||
* BitArrays.
|
||||
*/
|
||||
|
||||
BitArray& bitwiseXor /* Compute the bitwise */
|
||||
(const BitArray& bitarray, /* "exclusive or" of the */
|
||||
const unsigned long int bit_count); /* first `bit_count'
|
||||
* bits of two
|
||||
* BitArrays.
|
||||
*/
|
||||
|
||||
bool subset /* Test whether the */
|
||||
(const BitArray& bitarray, /* first `bit_count' */
|
||||
const unsigned long int bit_count) const; /* bits of `this'
|
||||
* BitArray are included
|
||||
* in another BitArray.
|
||||
*/
|
||||
|
||||
bool subset(const Bitset& bitset) const; /* Test for inclusion */
|
||||
bool operator<=(const Bitset& bitset) const; /* into a Bitset. */
|
||||
|
||||
unsigned long int count /* Compute the number of */
|
||||
(const unsigned long int bit_count) const; /* 1-bits in the first
|
||||
* `bit_count' bits of
|
||||
* the BitArray.
|
||||
*/
|
||||
|
||||
unsigned long int hammingDistance /* Compute the Hamming */
|
||||
(const BitArray& bitarray, /* distance between two */
|
||||
const unsigned long int bit_count) const; /* bit vectors
|
||||
* consisting of the
|
||||
* first `bit_count'
|
||||
* bits of two
|
||||
* BitArrays.
|
||||
*/
|
||||
|
||||
unsigned long int hammingDistance /* Compute the Hamming */
|
||||
(const Bitset& bitset) const; /* distance between a
|
||||
* BitArray and a
|
||||
* Bitset.
|
||||
*/
|
||||
|
||||
void set(const unsigned long int bit_count); /* Set a given number of
|
||||
* bits in the bit array.
|
||||
*/
|
||||
|
||||
void setBit(const unsigned long int index); /* Set a single bit in the
|
||||
* bit array.
|
||||
*/
|
||||
|
||||
void clear(const unsigned long int bit_count); /* Clear the first
|
||||
* `bit_count' bits in the
|
||||
* bit array.
|
||||
*/
|
||||
|
||||
void clearBit(const unsigned long int index); /* Clear a single bit in
|
||||
* the bit array.
|
||||
*/
|
||||
|
||||
void flip(const unsigned long int bit_count); /* Flip the first
|
||||
* `bit_count' bits in the
|
||||
* bit array.
|
||||
*/
|
||||
|
||||
void flipBit(const unsigned long int index); /* Flip a single bit in the
|
||||
* bit array.
|
||||
*/
|
||||
|
||||
unsigned long int find /* Return the index of */
|
||||
(const unsigned long int max_count) const; /* the first 1-bit in
|
||||
* the bit array with a
|
||||
* bit index less than
|
||||
* `max_count'.
|
||||
*/
|
||||
|
||||
void print /* Print the first */
|
||||
(const unsigned long int bit_count, /* `bit_count' bits of */
|
||||
ostream& stream = cout) const; /* the bit array. */
|
||||
|
||||
string toString /* Convert a prefix of */
|
||||
(const unsigned long int bit_count) const; /* a BitArray into a
|
||||
* string of 0's and
|
||||
* 1's.
|
||||
*/
|
||||
|
||||
private:
|
||||
unsigned char* bits; /* Storage for the bits. */
|
||||
|
||||
static const unsigned char bit_counts[]; /* `bit_counts[i]' gives
|
||||
* the number of bits in
|
||||
* the 8-bit integer `i'.
|
||||
* (Used by the member
|
||||
* function `count'.)
|
||||
*/
|
||||
|
||||
friend class Bitset;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#include "Bitset.h"
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Inline function definitions for class BitArray.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* ========================================================================= */
|
||||
inline bool BitArray::operator[](const unsigned long int index) const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Tells the state of a bit in a bit array.
|
||||
*
|
||||
* Argument: index -- Index of the bit to test.
|
||||
*
|
||||
* Returns: State of the bit in the bit array.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return ((bits[index >> 3] & (1 << (index & 7))) != 0);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline void BitArray::copy(const Bitset& bitset)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Initializes the BitArray with bits in a Bitset.
|
||||
*
|
||||
* Argument: bitset -- Bitset to copy.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return copy(bitset, bitset.capacity());
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline BitArray& BitArray::operator=(const Bitset& bitset)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Initializes the BitArray with bits in a Bitset.
|
||||
*
|
||||
* Argument: bitset -- Bitset to copy.
|
||||
*
|
||||
* Returns: A reference to `this' BitArray.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
copy(bitset, bitset.capacity());
|
||||
return *this;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline bool BitArray::equal(const Bitset& bitset) const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Compares the `bitset.capacity()' first bits of the BitArray
|
||||
* to `bitset'. The BitArray is assumed to be at least as large
|
||||
* as the Bitset.
|
||||
*
|
||||
* Argument: bitset -- Target of the comparison.
|
||||
*
|
||||
* Returns: Truth value based on the result of the test.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return equal(bitset, bitset.capacity());
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline bool BitArray::operator==(const Bitset& bitset) const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Compares the `bitset.capacity()' first bits of the BitArray
|
||||
* to `bitset'. The BitArray is assumed to be at least as large
|
||||
* as the Bitset.
|
||||
*
|
||||
* Argument: bitset -- Target of the comparison.
|
||||
*
|
||||
* Returns: Truth value according to the result of the test.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return equal(bitset, bitset.capacity());
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline bool BitArray::subset(const Bitset& bitset) const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Tests whether all of the first `bitset.capacity()' bits of
|
||||
* the BitArray are included in `bitset'. The BitArray should
|
||||
* be at least as large as the Bitset.
|
||||
*
|
||||
* Argument: bitset -- Target of the comparison.
|
||||
*
|
||||
* Returns: Truth value according to the result of the test.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return subset(bitset, bitset.capacity());
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline bool BitArray::operator<=(const Bitset& bitset) const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Tests whether all of the first `bitset.capacity()' bits of
|
||||
* the BitArray are included in `bitset'. The BitArray should be
|
||||
* at least as large as the Bitset.
|
||||
*
|
||||
* Argument: bitset -- Target of the comparison.
|
||||
*
|
||||
* Returns: Truth value according to the result of the test.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return subset(bitset, bitset.capacity());
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline unsigned long int BitArray::hammingDistance(const Bitset& bitset) const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Computer the Hamming distance (number of differing bits)
|
||||
* between the first `bitset.capacity()' bits of `bitset' and
|
||||
* the BitArray.
|
||||
*
|
||||
* Argument: bitset -- Target of the computation.
|
||||
*
|
||||
* Returns: The Hamming distance between `bitset' and the BitArray.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return hammingDistance(bitset, bitset.capacity());
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline bool BitArray::test(const unsigned long int index) const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Tells the state of a bit in a bit array.
|
||||
*
|
||||
* Argument: index -- Index of bit to test.
|
||||
*
|
||||
* Returns: Truth value according to the state of the bit.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return operator[](index);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline void BitArray::set(const unsigned long int bit_count)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Fills the first `bit_count' bits of the bit array with
|
||||
* 1-bits.
|
||||
*
|
||||
* Arguments: bit_count -- Number of bits to set to 1.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
memset(static_cast<void*>(bits), 0xFF, (bit_count + 7) >> 3);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
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.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
memset(static_cast<void*>(bits), 0, (bit_count + 7) >> 3);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
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 */
|
||||
626
lbtt/src/Bitset.h
Normal file
626
lbtt/src/Bitset.h
Normal file
|
|
@ -0,0 +1,626 @@
|
|||
/*
|
||||
* Copyright (C) 1999, 2000, 2001, 2002
|
||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef BITSET_H
|
||||
#define BITSET_H
|
||||
|
||||
#include <config.h>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include "Exception.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* A class for sets of bits.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
class Bitset
|
||||
{
|
||||
public:
|
||||
explicit Bitset /* Creates an empty bit */
|
||||
(const unsigned long int capacity = 0); /* set. */
|
||||
|
||||
explicit Bitset /* Creates a bit set */
|
||||
(const BitArray& bitarray, /* from a bit array. */
|
||||
const unsigned long int capacity);
|
||||
|
||||
Bitset(const Bitset& bitset); /* Copy constructor. */
|
||||
|
||||
~Bitset(); /* Destructor. */
|
||||
|
||||
operator const BitArray&() const; /* A Bitset can always be
|
||||
* cast into a constant
|
||||
* BitArray.
|
||||
*/
|
||||
|
||||
Bitset& operator=(const Bitset& bitset); /* Assignment operator. */
|
||||
|
||||
bool operator[](const unsigned long int index) /* Tell the value of a */
|
||||
const; /* bit in a given index. */
|
||||
bool test(const unsigned long int index) const;
|
||||
|
||||
bool operator==(const Bitset& bitset) const; /* Test whether two */
|
||||
bool equal(const Bitset& bitset) const; /* Bitsets are equal. */
|
||||
|
||||
bool operator<=(const Bitset& bitset) const; /* Test whether `this' */
|
||||
bool subset(const Bitset& bitset) const; /* Bitset is a subset
|
||||
* of another Bitset.
|
||||
*/
|
||||
|
||||
unsigned long int capacity() const; /* Tells the capacity of
|
||||
* the bit set.
|
||||
*/
|
||||
|
||||
unsigned long int count() const; /* Compute the number of
|
||||
* 1-bits in the Bitset.
|
||||
*/
|
||||
|
||||
unsigned long int hammingDistance /* Compute the Hamming */
|
||||
(const Bitset& bitset) const; /* distance between two
|
||||
* Bitsets.
|
||||
*/
|
||||
|
||||
void set(); /* Set all bits in the bit
|
||||
* set.
|
||||
*/
|
||||
|
||||
void setBit(const unsigned long int index); /* Set a single bit in the
|
||||
* bit set.
|
||||
*/
|
||||
|
||||
void clear(); /* Clear all bits in the
|
||||
* bit set.
|
||||
*/
|
||||
|
||||
void clearBit(const unsigned long int index); /* Clear a single bit in
|
||||
* the bit set.
|
||||
*/
|
||||
|
||||
void flip(); /* Flip all bits in the
|
||||
* bit set.
|
||||
*/
|
||||
|
||||
void flipBit(const unsigned long int index); /* Flip a single bit in the
|
||||
* bit set.
|
||||
*/
|
||||
|
||||
unsigned long int find() const; /* Return the index of the
|
||||
* first 1-bit in the bit
|
||||
* set.
|
||||
*/
|
||||
|
||||
void print(ostream& stream = cout) const; /* Print the bit set. */
|
||||
|
||||
string toString() const; /* Convert the Bitset into
|
||||
* a string if 0's and 1's.
|
||||
*/
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
class BitIndexException; /* An exception class for
|
||||
* reporting indexing
|
||||
* errors.
|
||||
*/
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
private:
|
||||
unsigned long int number_of_bits; /* Capacity of the bit
|
||||
* set.
|
||||
*/
|
||||
|
||||
BitArray bits; /* Storage for the bits. */
|
||||
};
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* An exception class for reporting bitset indexing errors.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
class Bitset::BitIndexException : public Exception
|
||||
{
|
||||
public:
|
||||
BitIndexException(); /* Constructor. */
|
||||
|
||||
/* default copy constructor */
|
||||
|
||||
~BitIndexException() throw(); /* Destructor. */
|
||||
|
||||
BitIndexException& /* Assignment operator. */
|
||||
operator=(const BitIndexException& e);
|
||||
|
||||
/* `what' inherited from class Exception */
|
||||
};
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Inline function definitions for class Bitset.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* ========================================================================= */
|
||||
inline Bitset::Bitset(const unsigned long int capacity) :
|
||||
number_of_bits(capacity), bits(capacity)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Constructor for class Bitset.
|
||||
*
|
||||
* Argument: capacity -- Number of bits to allocate.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline Bitset::Bitset
|
||||
(const BitArray& bitarray, const unsigned long int capacity) :
|
||||
number_of_bits(capacity), bits(capacity)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Constructor for class Bitset. Creates a Bitset from the
|
||||
* first `capacity' bits of a BitArray.
|
||||
*
|
||||
* Arguments: bitarray -- A reference to a constant BitArray.
|
||||
* capacity -- Capacity of the new bit set.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
memcpy(static_cast<void*>(bits.bits),
|
||||
static_cast<const void*>(bitarray.bits),
|
||||
(capacity + 7) >> 3);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline Bitset::Bitset(const Bitset& bitset) :
|
||||
number_of_bits(bitset.number_of_bits), bits(bitset.number_of_bits)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Copy constructor for class Bitset.
|
||||
*
|
||||
* Argument: bitset -- Bitset to be copied.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
memcpy(static_cast<void*>(bits.bits),
|
||||
static_cast<const void*>(bitset.bits.bits),
|
||||
(number_of_bits + 7) >> 3);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline Bitset::~Bitset()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Destructor for class Bitset.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline Bitset::operator const BitArray&() const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Converts a Bitset into a BitArray.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: The bits associated with the Bitset object as a reference to
|
||||
* a constant BitArray.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return bits;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline Bitset& Bitset::operator=(const Bitset& bitset)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Assignment operator for class Bitset.
|
||||
*
|
||||
* Arguments: bitset -- A reference to a Bitset to be assigned to `this'
|
||||
* Bitset.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
if (&bitset != this)
|
||||
{
|
||||
if ((number_of_bits >> 3) != (bitset.number_of_bits >> 3))
|
||||
bits.copy(bitset.bits, number_of_bits);
|
||||
else
|
||||
memcpy(static_cast<void*>(bits.bits),
|
||||
static_cast<const void*>(bitset.bits.bits),
|
||||
(bitset.number_of_bits + 7) >> 3);
|
||||
|
||||
number_of_bits = bitset.number_of_bits;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline bool Bitset::operator[](const unsigned long int index) const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Tells the state of a bit in a bit set.
|
||||
*
|
||||
* Argument: index -- Index of the bit to test.
|
||||
*
|
||||
* Returns: Truth value according to the state of the bit.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
if (index >= number_of_bits)
|
||||
throw BitIndexException();
|
||||
|
||||
return bits[index];
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline bool Bitset::test(const unsigned long int index) const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Tells the state of a bit in a bit set.
|
||||
*
|
||||
* Argument: index -- Index of bit to test.
|
||||
*
|
||||
* Returns: Truth value according to the state of the bit.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return operator[](index);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline bool Bitset::operator==(const Bitset& bitset) const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Compares two bitsets for equality.
|
||||
*
|
||||
* Argument: bitset -- Target of the comparison.
|
||||
*
|
||||
* Returns: `true' if the bit sets have the same capacity and contents.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return (number_of_bits == bitset.number_of_bits
|
||||
&& bits.equal(bitset.bits, number_of_bits));
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline bool Bitset::equal(const Bitset& bitset) const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Compares two bitsets for equality.
|
||||
*
|
||||
* Argument: bitset -- Target of the comparison.
|
||||
*
|
||||
* Returns: `true' if the bit sets have the same capacity and contents.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return operator==(bitset);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline bool Bitset::operator<=(const Bitset& bitset) const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Tests whether `this' bitset is a subset of another Bitset.
|
||||
*
|
||||
* Argument: bitset -- Target of the comparison.
|
||||
*
|
||||
* Returns: `true' if the capacity of `this' bitset is at most equal to
|
||||
* the capacity of the target bitset and all bits set in `this'
|
||||
* Bitset are also set in the other set.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return (number_of_bits <= bitset.number_of_bits
|
||||
&& bits.subset(bitset.bits, number_of_bits));
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline bool Bitset::subset(const Bitset& bitset) const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Tests whether `this' bitset is a subset of another Bitset.
|
||||
*
|
||||
* Argument: bitset -- Target of the comparison.
|
||||
*
|
||||
* Returns: `true' if the capacity of `this' bitset is at most equal to
|
||||
* the capacity of the target bitset and all bits set in `this'
|
||||
* Bitset are also set in the other set.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return operator<=(bitset);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline unsigned long int Bitset::capacity() const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Tells the capacity of the bit set.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Capacity of the bit set.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return number_of_bits;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline unsigned long int Bitset::count() const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Computes the number of 1-bits in the Bitset.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Number of 1-bits in the Bitset.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return bits.count(number_of_bits);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline unsigned long int Bitset::hammingDistance(const Bitset& bitset) const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Computes the Hamming distance between two Bitsets (or between
|
||||
* maximal prefixes of both Bitsets if the sets are of
|
||||
* different capacity).
|
||||
*
|
||||
* Argument: bitset -- A reference to a constant Bitset.
|
||||
*
|
||||
* Returns: The Hamming distance between the bitsets (or their maximal
|
||||
* prefixes of equal length).
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return bits.hammingDistance(bitset.bits,
|
||||
number_of_bits <= bitset.number_of_bits
|
||||
? number_of_bits
|
||||
: bitset.number_of_bits);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline void Bitset::set()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Fills the bit set with 1-bits.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
bits.set(number_of_bits);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline void Bitset::setBit(const unsigned long int index)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Sets a single bit in the bit set.
|
||||
*
|
||||
* Argument: index -- Index of the bit to be set.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
if (index >= number_of_bits)
|
||||
throw BitIndexException();
|
||||
|
||||
bits.setBit(index);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline void Bitset::clear()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Fills the bit set with 0-bits.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
bits.clear(number_of_bits);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline void Bitset::clearBit(const unsigned long int index)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Clears a single bit in the bit set.
|
||||
*
|
||||
* Argument: index -- Index of the bit to be cleared.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
if (index >= number_of_bits)
|
||||
throw BitIndexException();
|
||||
|
||||
bits.clearBit(index);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline void Bitset::flip()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Flips all bits in the bit set.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
bits.flip(number_of_bits);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline void Bitset::flipBit(const unsigned long int index)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Switches the state of a single bit in the bit set.
|
||||
*
|
||||
* Arguments: index -- Index of the bit.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
if (index >= number_of_bits)
|
||||
throw BitIndexException();
|
||||
|
||||
bits.flipBit(index);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline unsigned long int Bitset::find() const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Finds the index of the first 1-bit in the bit set.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Index of the first 1-bit in the bit set (or
|
||||
* `this->number_of_bits' if the bit set is empty).
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return bits.find(number_of_bits);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline void Bitset::print(ostream& stream) const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Writes the Bitset into a stream.
|
||||
*
|
||||
* Argument: stream -- A reference to an output stream.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
bits.print(number_of_bits, stream);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline string Bitset::toString() const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Converts the Bitset into a string.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: A string representation of the Bitset.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return bits.toString(number_of_bits);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Inline function definitions for class Bitset::BitIndexException.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* ========================================================================= */
|
||||
inline Bitset::BitIndexException::BitIndexException() :
|
||||
Exception("Index out of range.")
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Constructor for class Bitset::BitIndexException. Creates a
|
||||
* new exception object.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline Bitset::BitIndexException::~BitIndexException() throw()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Destructor for class Bitset::BitIndexException.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline Bitset::BitIndexException& Bitset::BitIndexException::operator=
|
||||
(const Bitset::BitIndexException& e)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Assignment operator for class Bitset::BitIndexException.
|
||||
*
|
||||
* Arguments: e -- A reference to another Bitset::BitIndexException.
|
||||
*
|
||||
* Returns: A reference to the assigned exception object.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
Exception::operator=(e);
|
||||
return *this;
|
||||
}
|
||||
|
||||
#endif /* !BITSET_H */
|
||||
1084
lbtt/src/BuchiAutomaton.cc
Normal file
1084
lbtt/src/BuchiAutomaton.cc
Normal file
File diff suppressed because it is too large
Load diff
861
lbtt/src/BuchiAutomaton.h
Normal file
861
lbtt/src/BuchiAutomaton.h
Normal file
|
|
@ -0,0 +1,861 @@
|
|||
/*
|
||||
* Copyright (C) 1999, 2000, 2001, 2002
|
||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef BUCHIAUTOMATON_H
|
||||
#define BUCHIAUTOMATON_H
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma interface
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#include <config.h>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include "Alloc.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 Büchi automata with a single set of accepting
|
||||
* states.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
class BuchiAutomaton : public Graph<GraphEdgeContainer>
|
||||
{
|
||||
public:
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
class BuchiTransition; /* A class for representing
|
||||
* the transitions between
|
||||
* the states of the
|
||||
* automaton.
|
||||
*/
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
class BuchiState : /* A class for */
|
||||
public Graph<GraphEdgeContainer>::Node /* representing the */
|
||||
{ /* states of the
|
||||
* automaton.
|
||||
*/
|
||||
public:
|
||||
explicit BuchiState /* Constructor. */
|
||||
(const unsigned long int
|
||||
num_of_acceptance_sets);
|
||||
|
||||
~BuchiState(); /* Destructor. */
|
||||
|
||||
/* `edges' inherited from Graph<GraphEdgeContainer>::Node */
|
||||
|
||||
BitArray& acceptanceSets(); /* Tell the acceptance */
|
||||
const BitArray& acceptanceSets() const; /* status of the state. */
|
||||
|
||||
void print /* Writes information */
|
||||
(ostream& stream, /* about the state to a */
|
||||
const int indent, /* stream. */
|
||||
const GraphOutputFormat fmt) const;
|
||||
|
||||
void print /* Writes information */
|
||||
(ostream& stream, /* about the state to a */
|
||||
const int indent, /* stream. */
|
||||
const GraphOutputFormat fmt,
|
||||
const unsigned long int
|
||||
number_of_acceptance_sets)
|
||||
const;
|
||||
|
||||
private:
|
||||
BuchiState(const BuchiState&); /* Prevent copying and */
|
||||
BuchiState& operator=(const BuchiState&); /* assignment of
|
||||
* BuchiState objects.
|
||||
*/
|
||||
|
||||
BitArray acceptance_sets; /* Acceptance status of the
|
||||
* state.
|
||||
*/
|
||||
};
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
explicit BuchiAutomaton /* Constructor. */
|
||||
(const size_type initial_number_of_states = 0,
|
||||
const size_type initstate = 0,
|
||||
const unsigned long int
|
||||
number_of_accept_sets = 0);
|
||||
|
||||
BuchiAutomaton(const BuchiAutomaton& automaton); /* Copy constructor. */
|
||||
|
||||
~BuchiAutomaton(); /* Destructor. */
|
||||
|
||||
BuchiAutomaton& /* Assignment operator. */
|
||||
operator=(const BuchiAutomaton& automaton);
|
||||
|
||||
BuchiState& operator[] /* Indexing operator. No */
|
||||
(const size_type index) const; /* range check is
|
||||
* performed on the
|
||||
* argument.
|
||||
*/
|
||||
|
||||
BuchiState& node(const size_type index) const; /* Synonym for the indexing
|
||||
* operator. This function
|
||||
* also checks the range of
|
||||
* the argument.
|
||||
*/
|
||||
|
||||
/* `size' inherited from Graph<GraphEdgeContainer> */
|
||||
|
||||
/* `empty' inherited from Graph<GraphEdgeContainer> */
|
||||
|
||||
void clear(); /* Makes the automaton
|
||||
* empty.
|
||||
*/
|
||||
|
||||
size_type expand(size_type node_count = 1); /* Inserts states to the
|
||||
* automaton.
|
||||
*/
|
||||
|
||||
void connect /* Connects two states */
|
||||
(const size_type father, /* of the automaton with */
|
||||
const size_type child); /* an unguarded
|
||||
* transition.
|
||||
*/
|
||||
|
||||
void connect /* Connects two states */
|
||||
(const size_type father, const size_type child, /* of the automaton with */
|
||||
::Ltl::LtlFormula& guard); /* a transition guarded */
|
||||
void connect /* by a propositional */
|
||||
(const size_type father, const size_type child, /* formula. */
|
||||
::Ltl::LtlFormula* guard);
|
||||
|
||||
/* `disconnect' inherited from Graph<GraphEdgeContainer> */
|
||||
|
||||
/* `connected' inherited from Graph<GraphEdgeContainer> */
|
||||
|
||||
/* `stats' inherited from Graph<GraphEdgeContainer> */
|
||||
|
||||
/* `subgraphStats' inherited from Graph<GraphEdgeContainer> */
|
||||
|
||||
size_type initialState() const; /* Get or set the */
|
||||
size_type& initialState(); /* initial state of the *
|
||||
* automaton.
|
||||
*/
|
||||
|
||||
unsigned long int numberOfAcceptanceSets() const; /* Returns the number of
|
||||
* acceptance sets in the
|
||||
* automaton.
|
||||
*/
|
||||
|
||||
BuchiAutomaton* regularize() const; /* Converts a generalized
|
||||
* automaton to an
|
||||
* automaton with one set
|
||||
* of accepting states.
|
||||
*/
|
||||
|
||||
void read(istream& input_stream); /* Reads the automaton
|
||||
* from a stream.
|
||||
*/
|
||||
|
||||
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).
|
||||
*/
|
||||
|
||||
static BuchiAutomaton* intersect /* Computes the */
|
||||
(const BuchiAutomaton& a1, /* intersection of two */
|
||||
const BuchiAutomaton& a2, /* Büchi automata. */
|
||||
map<size_type, StateIdPair,
|
||||
less<size_type>, ALLOC(StateIdPair) >*
|
||||
intersection_state_mapping = 0);
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
class AutomatonParseException; /* Class for reporting
|
||||
* parse errors when
|
||||
* reading an automaton
|
||||
* description from a
|
||||
* stream.
|
||||
*/
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
private:
|
||||
size_type initial_state; /* Identifier of the
|
||||
* initial state of the
|
||||
* automaton.
|
||||
*/
|
||||
|
||||
unsigned long int number_of_acceptance_sets; /* Number of acceptance
|
||||
* sets in the automaton.
|
||||
*/
|
||||
};
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* A class for representing the transitions of a Büchi automaton.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
class BuchiAutomaton::BuchiTransition : public Graph<GraphEdgeContainer>::Edge
|
||||
{
|
||||
public:
|
||||
BuchiTransition /* Constructor. */
|
||||
(const size_type target,
|
||||
::Ltl::LtlFormula* formula);
|
||||
|
||||
~BuchiTransition(); /* Destructor. */
|
||||
|
||||
private:
|
||||
|
||||
public:
|
||||
|
||||
/* `targetNode' inherited from Graph<GraphEdgeContainer>::Edge */
|
||||
|
||||
bool enabled /* These functions test */
|
||||
(const BitArray& truth_assignment, /* whether the */
|
||||
const unsigned long int assignment_size) /* transition is */
|
||||
const; /* enabled in a given */
|
||||
/* truth assignment for */
|
||||
bool enabled /* the atomic */
|
||||
(const Bitset& truth_assignment) const; /* propositions. */
|
||||
|
||||
::Ltl::LtlFormula& guard() const; /* Returns the
|
||||
* propositional formula
|
||||
* guarding the transition.
|
||||
*/
|
||||
|
||||
void print /* Writes information */
|
||||
(ostream& stream = cout, /* about the transition */
|
||||
const int indent = 0, /* to a stream in */
|
||||
const GraphOutputFormat fmt = NORMAL) const; /* various formats
|
||||
* (determined by the
|
||||
* `fmt' argument).
|
||||
*/
|
||||
|
||||
private:
|
||||
BuchiTransition(const BuchiTransition&); /* Prevent copying and */
|
||||
BuchiTransition& operator= /* assignment of */
|
||||
(const BuchiTransition&); /* BuchiTransition
|
||||
* objects.
|
||||
*/
|
||||
|
||||
bool operator== /* Equality test. Used */
|
||||
(const Graph<GraphEdgeContainer>::Edge& /* for sorting */
|
||||
transition) const; /* transitions in an STL
|
||||
* container.
|
||||
*/
|
||||
|
||||
bool operator< /* `Less than' relation. */
|
||||
(const Graph<GraphEdgeContainer>::Edge& /* Used for sorting */
|
||||
transition) const; /* transitions in an STL
|
||||
* container.
|
||||
*/
|
||||
|
||||
::Ltl::LtlFormula* guard_formula; /* The propositional
|
||||
* formula guarding the
|
||||
* transition.
|
||||
*/
|
||||
};
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* A class for reporting parse errors when reading an automaton description
|
||||
* from a stream.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
class BuchiAutomaton::AutomatonParseException : public Exception
|
||||
{
|
||||
public:
|
||||
AutomatonParseException /* Constructor. */
|
||||
(const string& msg = "parse error");
|
||||
|
||||
/* default copy constructor */
|
||||
|
||||
~AutomatonParseException() throw(); /* Destructor. */
|
||||
|
||||
AutomatonParseException& /* Assignment operator. */
|
||||
operator=(const AutomatonParseException& e);
|
||||
|
||||
/* `what' inherited from class Exception */
|
||||
};
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Inline function definitions for class BuchiAutomaton.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* ========================================================================= */
|
||||
inline BuchiAutomaton::~BuchiAutomaton()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Destructor for class BuchiAutomaton.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline BuchiAutomaton::BuchiState& BuchiAutomaton::operator[]
|
||||
(const size_type index) const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Indexing operator for class BuchiAutomaton. This function can
|
||||
* be used to refer to the individual states of the automaton.
|
||||
* No range check will be performed on the argument.
|
||||
*
|
||||
* Argument: index -- Index of a state.
|
||||
*
|
||||
* Returns: A reference to a state of the automaton.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return static_cast<BuchiState&>(*nodes[index]);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline BuchiAutomaton::BuchiState& BuchiAutomaton::node
|
||||
(const size_type index) const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Function for referring to a single state of a BuchiAutomaton.
|
||||
* This function will perform a range check on the argument.
|
||||
*
|
||||
* Argument: index -- Index of a state.
|
||||
*
|
||||
* Returns: A reference to a state of the automaton.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return static_cast<BuchiState&>(Graph<GraphEdgeContainer>::node(index));
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline void BuchiAutomaton::connect
|
||||
(const size_type father, const size_type child)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Connects two states of a BuchiAutomaton to each other with an
|
||||
* unguarded transition (actually, a transition with a guard
|
||||
* that is always true).
|
||||
*
|
||||
* Arguments: father -- Source state identifier.
|
||||
* child -- Target state identifier.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
connect(father, child, &(::Ltl::True::construct()));
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline void BuchiAutomaton::connect
|
||||
(const size_type father, const size_type child, ::Ltl::LtlFormula& guard)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
connect(father, child, guard.clone());
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline void BuchiAutomaton::connect
|
||||
(const size_type father, const size_type child, ::Ltl::LtlFormula* guard)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
BuchiTransition* new_buchi_transition = new BuchiTransition(child, guard);
|
||||
|
||||
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) :
|
||||
Edge(target), guard_formula(formula)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Constructor for class BuchiAutomaton::BuchiTransition.
|
||||
* Initializes a new transition to a BuchiState, guarded by an
|
||||
* LtlFormula (which is actually a propositional formula).
|
||||
*
|
||||
* Arguments: target -- Identifier of the target state of the automaton.
|
||||
* formula -- A pointer to a propositional formula guarding
|
||||
* the transition.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline BuchiAutomaton::BuchiTransition::BuchiTransition
|
||||
(const BuchiTransition& transition) :
|
||||
Edge(transition), guard_formula(transition.guard_formula->clone())
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Copy constructor for class BuchiAutomaton::BuchiTransition.
|
||||
* Creates a copy of a BuchiTransition object.
|
||||
*
|
||||
* Arguments: transition -- BuchiTransition to be copied.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline BuchiAutomaton::BuchiTransition::~BuchiTransition()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Destructor for class BuchiAutomaton::BuchiTransition.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
::Ltl::LtlFormula::destruct(guard_formula);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline bool BuchiAutomaton::BuchiTransition::operator==
|
||||
(const Graph<GraphEdgeContainer>::Edge& transition) const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Equality relation for comparing two BuchiTransitions. Two
|
||||
* transitions are `equal' if and only if their target nodes
|
||||
* have the same identifier and if their guard formulae are
|
||||
* identical according to the `less<class ::Ltl::LtlFormula>'
|
||||
* relation.
|
||||
*
|
||||
* Argument: transition -- A reference to a constant Edge.
|
||||
*
|
||||
* Returns: Truth value according to the relationship between the two
|
||||
* transitions.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
/*
|
||||
* This function is called only when comparing two edges stored in the
|
||||
* `outgoing_edges' GraphEdgeContainer of some state in a BuchiAutomaton.
|
||||
* Since (pointers to) BuchiTransitions are never mixed with other types in
|
||||
* that container, it is always safe to static_cast `transition' to a
|
||||
* reference to a BuchiTransition.
|
||||
*/
|
||||
|
||||
return (Edge::operator==(transition)
|
||||
&& !(guard_formula < static_cast<const BuchiTransition&>(transition)
|
||||
.guard_formula)
|
||||
&& !(static_cast<const BuchiTransition&>(transition).guard_formula
|
||||
< guard_formula));
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline bool BuchiAutomaton::BuchiTransition::operator<
|
||||
(const Graph<GraphEdgeContainer>::Edge& transition) const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: `Less than' relation for comparing two BuchiTransitions. A
|
||||
* BuchiTransition is `less than' another if and only if the
|
||||
* identifier of its target node is less than that of the other
|
||||
* or the target nodes agree but the guard formula of the
|
||||
* first transition is `less than' the other according to the
|
||||
* `less<class ::Ltl::LtlFormula>' relation.
|
||||
*
|
||||
* Argument: transition -- A reference to a constant Edge.
|
||||
*
|
||||
* Returns: Truth value according to the relationship between the two
|
||||
* transitions.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
/*
|
||||
* This function is called only when comparing two edges stored in the
|
||||
* `outgoing_edges' GraphEdgeContainer of some state in a BuchiAutomaton.
|
||||
* Since (pointers to) BuchiTransitions are never mixed with other types in
|
||||
* that container, it is always safe to static_cast `transition' to a
|
||||
* reference to a BuchiTransition.
|
||||
*/
|
||||
|
||||
return (Edge::operator<(transition)
|
||||
|| (Edge::operator==(transition)
|
||||
&& guard_formula
|
||||
< static_cast<const BuchiTransition&>(transition)
|
||||
.guard_formula));
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline bool BuchiAutomaton::BuchiTransition::enabled
|
||||
(const BitArray& truth_assignment, const unsigned long int assignment_size)
|
||||
const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Determines whether the transition is enabled in a given
|
||||
* truth assignment for propositional variables.
|
||||
*
|
||||
* Arguments: truth_assignment -- A reference to a constant BitArray
|
||||
* representing an assignment of truth
|
||||
* values to propositional variables.
|
||||
* assignment_size -- Number of propositions in the
|
||||
* truth assignment.
|
||||
*
|
||||
* Returns: A truth value telling whether the transition is enabled in
|
||||
* the truth assignment.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return guard_formula->evaluate(truth_assignment, assignment_size);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline bool BuchiAutomaton::BuchiTransition::enabled
|
||||
(const Bitset& truth_assignment) const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: See above.
|
||||
*
|
||||
* Arguments: truth_assignment -- A reference to a constant Bitset
|
||||
* representing an assignment of truth
|
||||
* values to propositional variables.
|
||||
*
|
||||
* Returns: A truth value telling whether the transition is enabled in
|
||||
* the truth assignment.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return enabled(truth_assignment, truth_assignment.capacity());
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline ::Ltl::LtlFormula& BuchiAutomaton::BuchiTransition::guard() const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Returns the propositional formula guarding the transition
|
||||
* (a LtlFormula object).
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: A reference to the constant propositional formula guarding
|
||||
* the transition.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return *guard_formula;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Inline 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 */
|
||||
258
lbtt/src/Config-lex.ll
Normal file
258
lbtt/src/Config-lex.ll
Normal file
|
|
@ -0,0 +1,258 @@
|
|||
/*
|
||||
* Copyright (C) 1999, 2000, 2001, 2002
|
||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
%{
|
||||
#include <config.h>
|
||||
#include <cmath>
|
||||
#include <climits>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include "Configuration.h"
|
||||
#include "Config-parse.h"
|
||||
|
||||
extern int config_file_line_number;
|
||||
|
||||
%}
|
||||
|
||||
%option case-insensitive
|
||||
%option never-interactive
|
||||
%option noyywrap
|
||||
|
||||
%%
|
||||
|
||||
[ \t]* { /* Skip whitespace. */ }
|
||||
"#"[^\n]* { /* Skip comments. */ }
|
||||
|
||||
"\n" { /* Skip newlines, but update the line number. */
|
||||
config_file_line_number++;
|
||||
}
|
||||
|
||||
"{" { return CFG_LBRACE; }
|
||||
"}" { return CFG_RBRACE; }
|
||||
"=" { return CFG_EQUALS; }
|
||||
|
||||
algorithm { return CFG_ALGORITHM; }
|
||||
enabled { return CFG_ENABLED; }
|
||||
name { return CFG_NAME; }
|
||||
parameters { return CFG_PARAMETERS; }
|
||||
path { return CFG_PROGRAMPATH; }
|
||||
|
||||
globaloptions { return CFG_GLOBALOPTIONS; }
|
||||
comparisoncheck { return CFG_COMPARISONTEST; }
|
||||
comparisontest { return CFG_COMPARISONTEST; }
|
||||
consistencycheck { return CFG_CONSISTENCYTEST; }
|
||||
consistencytest { return CFG_CONSISTENCYTEST; }
|
||||
interactive { return CFG_INTERACTIVE; }
|
||||
intersectioncheck { return CFG_INTERSECTIONTEST; }
|
||||
intersectiontest { return CFG_INTERSECTIONTEST; }
|
||||
modelcheck { return CFG_MODELCHECK; }
|
||||
rounds { return CFG_ROUNDS; }
|
||||
verbosity { return CFG_VERBOSITY; }
|
||||
|
||||
statespaceoptions { return CFG_STATESPACEOPTIONS; }
|
||||
edgeprobability { return CFG_EDGEPROBABILITY; }
|
||||
propositions { return CFG_PROPOSITIONS; }
|
||||
size { return CFG_SIZE; }
|
||||
truthprobability { return CFG_TRUTHPROBABILITY; }
|
||||
changeinterval { return CFG_CHANGEINTERVAL; }
|
||||
randomseed { return CFG_RANDOMSEED; }
|
||||
|
||||
formulaoptions { return CFG_FORMULAOPTIONS; }
|
||||
abbreviatedoperators { return CFG_ABBREVIATEDOPERATORS; }
|
||||
andpriority { return CFG_ANDPRIORITY; }
|
||||
beforepriority { return CFG_BEFOREPRIORITY; }
|
||||
defaultoperatorpriority { return CFG_DEFAULTOPERATORPRIORITY; }
|
||||
equivalencepriority { return CFG_EQUIVALENCEPRIORITY; }
|
||||
falsepriority { return CFG_FALSEPRIORITY; }
|
||||
finallypriority { return CFG_FINALLYPRIORITY; }
|
||||
generatemode { return CFG_GENERATEMODE; }
|
||||
globallypriority { return CFG_GLOBALLYPRIORITY; }
|
||||
implicationpriority { return CFG_IMPLICATIONPRIORITY; }
|
||||
nextpriority { return CFG_NEXTPRIORITY; }
|
||||
notpriority { return CFG_NOTPRIORITY; }
|
||||
orpriority { return CFG_ORPRIORITY; }
|
||||
outputmode { return CFG_OUTPUTMODE; }
|
||||
propositionpriority { return CFG_PROPOSITIONPRIORITY; }
|
||||
releasepriority { return CFG_RELEASEPRIORITY; }
|
||||
strongreleasepriority { return CFG_STRONGRELEASEPRIORITY; }
|
||||
truepriority { return CFG_TRUEPRIORITY; }
|
||||
untilpriority { return CFG_UNTILPRIORITY; }
|
||||
weakuntilpriority { return CFG_WEAKUNTILPRIORITY; }
|
||||
xorpriority { return CFG_XORPRIORITY; }
|
||||
|
||||
true|yes {
|
||||
yylval.truth_value = true;
|
||||
return CFG_TRUTH_VALUE;
|
||||
}
|
||||
|
||||
false|no {
|
||||
yylval.truth_value = false;
|
||||
return CFG_TRUTH_VALUE;
|
||||
}
|
||||
|
||||
always {
|
||||
yylval.interactivity_value =
|
||||
Configuration::ALWAYS;
|
||||
return CFG_INTERACTIVITY_VALUE;
|
||||
}
|
||||
|
||||
never {
|
||||
yylval.interactivity_value =
|
||||
Configuration::NEVER;
|
||||
return CFG_INTERACTIVITY_VALUE;
|
||||
}
|
||||
|
||||
onerror {
|
||||
yylval.interactivity_value =
|
||||
Configuration::ONERROR;
|
||||
return CFG_INTERACTIVITY_VALUE;
|
||||
}
|
||||
|
||||
normal {
|
||||
yylval.formula_mode_value =
|
||||
Configuration::NORMAL;
|
||||
return CFG_FORMULA_MODE_VALUE;
|
||||
}
|
||||
|
||||
nnf {
|
||||
yylval.formula_mode_value = Configuration::NNF;
|
||||
return CFG_FORMULA_MODE_VALUE;
|
||||
}
|
||||
|
||||
local {
|
||||
yylval.product_type_value = Configuration::LOCAL;
|
||||
return CFG_PRODUCT_TYPE_VALUE;
|
||||
}
|
||||
|
||||
global {
|
||||
yylval.product_type_value =
|
||||
Configuration::GLOBAL;
|
||||
return CFG_PRODUCT_TYPE_VALUE;
|
||||
}
|
||||
|
||||
randomgraph {
|
||||
yylval.statespace_mode_value
|
||||
= Configuration::RANDOMGRAPH;
|
||||
return CFG_STATESPACE_MODE_VALUE;
|
||||
}
|
||||
|
||||
randomconnectedgraph {
|
||||
yylval.statespace_mode_value
|
||||
= Configuration::RANDOMCONNECTEDGRAPH;
|
||||
return CFG_STATESPACE_MODE_VALUE;
|
||||
}
|
||||
|
||||
randompath {
|
||||
yylval.statespace_mode_value
|
||||
= Configuration::RANDOMPATH;
|
||||
return CFG_STATESPACE_MODE_VALUE;
|
||||
}
|
||||
|
||||
enumeratedpath {
|
||||
yylval.statespace_mode_value
|
||||
= Configuration::ENUMERATEDPATH;
|
||||
return CFG_STATESPACE_MODE_VALUE;
|
||||
}
|
||||
|
||||
|
||||
"-"?[0-9]+"...""-"?[0-9]+ {
|
||||
char* dot_ptr;
|
||||
yylval.integer_interval.min
|
||||
= strtol(yytext, &dot_ptr, 10);
|
||||
|
||||
if (yylval.integer_interval.min == LONG_MIN
|
||||
|| yylval.integer_interval.min == LONG_MAX)
|
||||
throw Configuration::ConfigurationException
|
||||
(config_file_line_number,
|
||||
"integer out of range");
|
||||
|
||||
dot_ptr += 3;
|
||||
yylval.integer_interval.max
|
||||
= strtol(dot_ptr, 0, 10);
|
||||
|
||||
if (yylval.integer_interval.max == LONG_MIN
|
||||
|| yylval.integer_interval.max == LONG_MAX)
|
||||
throw Configuration::ConfigurationException
|
||||
(config_file_line_number,
|
||||
"integer out of range");
|
||||
|
||||
return CFG_INTEGER_INTERVAL;
|
||||
}
|
||||
|
||||
"-"?[0-9]+ {
|
||||
yylval.integer = strtol(yytext, 0, 10);
|
||||
if (yylval.integer == LONG_MIN
|
||||
|| yylval.integer == LONG_MAX)
|
||||
throw Configuration::ConfigurationException
|
||||
(config_file_line_number,
|
||||
"integer out of range");
|
||||
return CFG_INTEGER;
|
||||
}
|
||||
|
||||
"-"?[0-9]*"."[0-9]+ {
|
||||
yylval.real = strtod(yytext, 0);
|
||||
|
||||
if (yylval.real == HUGE_VAL
|
||||
|| yylval.real == -HUGE_VAL)
|
||||
throw Configuration::ConfigurationException
|
||||
(config_file_line_number,
|
||||
"real number out of range");
|
||||
return CFG_REAL;
|
||||
}
|
||||
|
||||
\"([^\n\"\\]*(\\[^\n])?)*\" {
|
||||
unsigned long int len = strlen(yytext);
|
||||
bool escape = false;
|
||||
yylval.str = new string;
|
||||
for (unsigned long int i = 1; i < len - 1; i++)
|
||||
{
|
||||
if (!escape && yytext[i] == '\\')
|
||||
escape = true;
|
||||
else
|
||||
{
|
||||
escape = false;
|
||||
(*yylval.str) += yytext[i];
|
||||
}
|
||||
}
|
||||
return CFG_STRING_CONSTANT;
|
||||
}
|
||||
|
||||
. {
|
||||
return CFG_UNKNOWN;
|
||||
}
|
||||
|
||||
|
||||
%%
|
||||
|
||||
/* ========================================================================= */
|
||||
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();
|
||||
}
|
||||
1381
lbtt/src/Config-parse.yy
Normal file
1381
lbtt/src/Config-parse.yy
Normal file
File diff suppressed because it is too large
Load diff
1991
lbtt/src/Configuration.cc
Normal file
1991
lbtt/src/Configuration.cc
Normal file
File diff suppressed because it is too large
Load diff
627
lbtt/src/Configuration.h
Normal file
627
lbtt/src/Configuration.h
Normal file
|
|
@ -0,0 +1,627 @@
|
|||
/*
|
||||
* Copyright (C) 1999, 2000, 2001, 2002
|
||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef CONFIGURATION_H
|
||||
#define CONFIGURATION_H
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma interface
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#include <config.h>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include "Alloc.h"
|
||||
#include "Exception.h"
|
||||
#include "FormulaRandomizer.h"
|
||||
#include "StateSpaceRandomizer.h"
|
||||
#include "StringUtil.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* A class for storing program configuration information.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
class Configuration
|
||||
{
|
||||
public:
|
||||
Configuration(); /* Constructor. */
|
||||
|
||||
~Configuration(); /* Destructor. */
|
||||
|
||||
void read(int argc, char* argv[]); /* Reads the program
|
||||
* configuration.
|
||||
*/
|
||||
|
||||
void print /* Writes the current */
|
||||
(ostream& stream = cout, int indent = 0) const; /* configuration (in a
|
||||
* textual form) to a
|
||||
* stream.
|
||||
*/
|
||||
|
||||
struct AlgorithmInformation; /* See below. */
|
||||
|
||||
string algorithmString /* Formats the the id */
|
||||
(vector<AlgorithmInformation, /* of an algorithm and */
|
||||
ALLOC(AlgorithmInformation) >::size_type/* the name of the */
|
||||
algorithm_id) const; /* algorithm into a
|
||||
* string.
|
||||
*/
|
||||
|
||||
static void showCommandLineHelp /* Prints the list of */
|
||||
(const char* program_name); /* command line options. */
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
enum InteractionMode {NEVER, ALWAYS, ONERROR}; /* Enumeration constants
|
||||
* affecting the behaviour
|
||||
* of the program as
|
||||
* regards user control.
|
||||
*/
|
||||
|
||||
enum 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.
|
||||
*/
|
||||
|
||||
string* path_to_program; /* Path to the executable
|
||||
* required for running
|
||||
* the algorithm.
|
||||
*/
|
||||
|
||||
string* extra_parameters; /* Additional command-line
|
||||
* parameters required for
|
||||
* running the executable.
|
||||
*/
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
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.
|
||||
*/
|
||||
};
|
||||
|
||||
struct FormulaConfiguration /* A structure for storing
|
||||
* specific information
|
||||
* affecting the generation
|
||||
* of random formulae.
|
||||
*/
|
||||
{
|
||||
int default_operator_priority; /* Default priority for all
|
||||
* LTL formula symbols.
|
||||
*/
|
||||
|
||||
map<int, int, less<int>, ALLOC(int) > /* Priorities for LTL */
|
||||
symbol_priority; /* formula symbols. */
|
||||
|
||||
map<int, double, less<int>, ALLOC(double) > /* Expected numbers of */
|
||||
symbol_distribution; /* occurrence for the
|
||||
* different formula
|
||||
* operators.
|
||||
*/
|
||||
|
||||
bool allow_abbreviated_operators; /* Determines whether the
|
||||
* operators ->, <->, xor,
|
||||
* <>, [], W and M should
|
||||
* be allowed when
|
||||
* generating random
|
||||
* formulae (these are
|
||||
* `abbreviated' operators
|
||||
* since they could be
|
||||
* written in an equivalent
|
||||
* form by using another
|
||||
* operators).
|
||||
*/
|
||||
|
||||
Configuration::FormulaMode output_mode; /* Determines whether the
|
||||
* generated formulae are
|
||||
* to be converted to
|
||||
* negation normal form
|
||||
* before passing them to
|
||||
* the different
|
||||
* algorithms. Possible
|
||||
* values are:
|
||||
*
|
||||
* NORMAL:
|
||||
* No conversion.
|
||||
* NNF:
|
||||
* Do the conversion
|
||||
* (this may affect the
|
||||
* size of the formulae!)
|
||||
*/
|
||||
|
||||
Configuration::FormulaMode generate_mode; /* Determines whether the
|
||||
* formulae are to be
|
||||
* generated in negation
|
||||
* normal form (strict
|
||||
* size requirement for
|
||||
* formulae). Possible
|
||||
* values are:
|
||||
*
|
||||
* NORMAL:
|
||||
* Allow more flexibility
|
||||
* in the generation of
|
||||
* formulae.
|
||||
* NNF:
|
||||
* Force generation into
|
||||
* negation normal form.
|
||||
*/
|
||||
|
||||
::Ltl::FormulaRandomizer formula_generator; /* Interface to the random
|
||||
* LTL formula generation
|
||||
* algorithm.
|
||||
*/
|
||||
};
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
vector<AlgorithmInformation, /* A vector containing */
|
||||
ALLOC(AlgorithmInformation) > algorithms; /* information about the
|
||||
* algorithms used in
|
||||
* the tests.
|
||||
*/
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
typedef pair<int, int> IntPair;
|
||||
|
||||
set<IntPair, less<IntPair>, ALLOC(IntPair) > /* Configuration options */
|
||||
locked_options; /* the values of which
|
||||
* should not be
|
||||
* initialized from the
|
||||
* configuration file.
|
||||
*/
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
class ConfigurationException : public Exception /* A class for reporting
|
||||
* 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.
|
||||
*/
|
||||
};
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
struct IntegerRange /* Data structure for
|
||||
* representing integer-
|
||||
* valued ranges of certain
|
||||
* program configuration
|
||||
* options.
|
||||
*/
|
||||
{
|
||||
long int min; /* Lower bound. */
|
||||
|
||||
long int max; /* Upper bound. */
|
||||
|
||||
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
|
||||
VERBOSITY_RANGE, ROUND_COUNT_RANGE, GENERATION_RANGE, PRIORITY_RANGE,
|
||||
PROPOSITION_COUNT_RANGE, FORMULA_SIZE_RANGE, FORMULA_MAX_SIZE_RANGE,
|
||||
STATESPACE_SIZE_RANGE, STATESPACE_MAX_SIZE_RANGE;
|
||||
|
||||
private:
|
||||
enum CommandLineOptionType /* Command line options. */
|
||||
{OPT_COMPARISONTEST = 10000, OPT_CONFIGFILE,
|
||||
OPT_CONSISTENCYTEST, OPT_DISABLE, OPT_ENABLE,
|
||||
OPT_FORMULACHANGEINTERVAL, OPT_FORMULAFILE,
|
||||
OPT_FORMULARANDOMSEED, OPT_HELP = 'h',
|
||||
OPT_GLOBALPRODUCT = 20000, OPT_INTERACTIVE,
|
||||
OPT_INTERSECTIONTEST, OPT_LOGFILE,
|
||||
OPT_MODELCHECK, OPT_NOCOMPARISONTEST,
|
||||
OPT_NOCONSISTENCYTEST, OPT_NOINTERSECTIONTEST,
|
||||
OPT_NOPAUSE, OPT_PAUSE, OPT_PAUSEONERROR,
|
||||
OPT_PROFILE, OPT_QUIET, OPT_ROUNDS,
|
||||
OPT_SHOWCONFIG, OPT_SHOWOPERATORDISTRIBUTION,
|
||||
OPT_SKIP, OPT_STATESPACECHANGEINTERVAL,
|
||||
OPT_STATESPACERANDOMSEED, OPT_VERBOSITY,
|
||||
OPT_VERSION,
|
||||
|
||||
OPT_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_NOABBREVIATEDOPERATORS,
|
||||
OPT_NOGENERATENNF, OPT_NOOUTPUTNNF,
|
||||
OPT_NOTPRIORITY, OPT_ORPRIORITY,
|
||||
OPT_OUTPUTNNF, OPT_PROPOSITIONPRIORITY,
|
||||
OPT_RELEASEPRIORITY,
|
||||
OPT_STRONGRELEASEPRIORITY, OPT_TRUEPRIORITY,
|
||||
OPT_UNTILPRIORITY, OPT_WEAKUNTILPRIORITY,
|
||||
OPT_XORPRIORITY,
|
||||
|
||||
OPT_EDGEPROBABILITY,
|
||||
OPT_ENUMERATEDPATH, OPT_RANDOMCONNECTEDGRAPH,
|
||||
OPT_RANDOMGRAPH, OPT_RANDOMPATH,
|
||||
OPT_STATESPACEGENERATEMODE,
|
||||
OPT_STATESPACEPROPOSITIONS,
|
||||
OPT_STATESPACESIZE, OPT_TRUTHPROBABILITY};
|
||||
|
||||
typedef map<pair<int, int>, double, /* Type definitions for */
|
||||
less<pair<int, int> >, /* the result cache used */
|
||||
ALLOC(double) > /* for computing the */
|
||||
ProbabilityMapElement; /* probability */
|
||||
typedef map<int, ProbabilityMapElement, /* distribution of LTL */
|
||||
less<int>, /* formula operators. */
|
||||
ALLOC(ProbabilityMapElement) >
|
||||
ProbabilityMap;
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
long int parseCommandLineInteger /* Converts an integer */
|
||||
(const string& option, const string& value) /* to a string with */
|
||||
const; /* some additional
|
||||
* validity checks.
|
||||
*/
|
||||
|
||||
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'.
|
||||
*/
|
||||
};
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* 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 */
|
||||
183
lbtt/src/DispUtil.cc
Normal file
183
lbtt/src/DispUtil.cc
Normal file
|
|
@ -0,0 +1,183 @@
|
|||
/*
|
||||
* Copyright (C) 1999, 2000, 2001, 2002
|
||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma implementation
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#include <config.h>
|
||||
#include <deque>
|
||||
#include <stack>
|
||||
#include "Alloc.h"
|
||||
#include "DispUtil.h"
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Functions for displaying various statistics during testing.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
namespace DispUtil
|
||||
{
|
||||
|
||||
stack<StreamFormatting, /* Stack for storing the */
|
||||
deque<StreamFormatting, /* previous states of an */
|
||||
ALLOC(StreamFormatting) > > /* output stream. */
|
||||
stream_formatting_stack;
|
||||
|
||||
/* ========================================================================= */
|
||||
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();
|
||||
}
|
||||
|
||||
}
|
||||
163
lbtt/src/DispUtil.h
Normal file
163
lbtt/src/DispUtil.h
Normal file
|
|
@ -0,0 +1,163 @@
|
|||
/*
|
||||
* Copyright (C) 1999, 2000, 2001, 2002
|
||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef DISPUTIL_H
|
||||
#define DISPUTIL_H
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma interface
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#include <config.h>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include "Configuration.h"
|
||||
#include "SharedTestData.h"
|
||||
#include "TestRoundInfo.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
extern Configuration configuration;
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Prototypes for miscellaneous routines for controlling output stream
|
||||
* formatting and writing text into a stream.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
namespace DispUtil
|
||||
{
|
||||
|
||||
void changeStreamFormatting /* Changes the state of */
|
||||
(ostream& stream, int width, int precision, /* an output stream and */
|
||||
ios::fmtflags flags); /* saves its previous
|
||||
* state.
|
||||
*/
|
||||
|
||||
void restoreStreamFormatting(ostream& stream); /* Restores a previously
|
||||
* saved state of an
|
||||
* output stream.
|
||||
*/
|
||||
|
||||
void printTextBlock /* Writes an indented */
|
||||
(ostream& stream, int indent, const string& text, /* and word-wrapped */
|
||||
int max_line_len); /* block of text into
|
||||
* a stream.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
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);
|
||||
};
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* 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 */
|
||||
28
lbtt/src/EdgeContainer.h
Normal file
28
lbtt/src/EdgeContainer.h
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright (C) 1999, 2000, 2001, 2002
|
||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef EDGECONTAINER_H
|
||||
#define EDGECONTAINER_H
|
||||
|
||||
#include <config.h>
|
||||
#include "Graph.h"
|
||||
|
||||
typedef ::Graph::EdgeVector GraphEdgeContainer;
|
||||
|
||||
#endif /* !EDGECONTAINER_H */
|
||||
1170
lbtt/src/Exception.h
Normal file
1170
lbtt/src/Exception.h
Normal file
File diff suppressed because it is too large
Load diff
220
lbtt/src/ExternalTranslator.cc
Normal file
220
lbtt/src/ExternalTranslator.cc
Normal file
|
|
@ -0,0 +1,220 @@
|
|||
/*
|
||||
* Copyright (C) 1999, 2000, 2001, 2002
|
||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma implementation
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#include <config.h>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#ifdef HAVE_FCNTL_H
|
||||
#include <fcntl.h>
|
||||
#endif /* HAVE_FCNTL_H */
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif /* HAVE_UNISTD_H */
|
||||
#include <fstream>
|
||||
#include "ExternalTranslator.h"
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Function definitions for class ExternalTranslator.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* ========================================================================= */
|
||||
ExternalTranslator::~ExternalTranslator()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Destructor for class ExternalTranslator.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
/*
|
||||
* Delete all registered temporary files or directories in the reverse order
|
||||
* of registration.
|
||||
*/
|
||||
|
||||
while (!temporary_file_objects.empty())
|
||||
{
|
||||
delete temporary_file_objects.top();
|
||||
temporary_file_objects.pop();
|
||||
}
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
ExternalTranslator::TempFileObject&
|
||||
ExternalTranslator::registerTempFileObject
|
||||
(const string& filename, TempFileObject::Type type)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* 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.
|
||||
* type -- Type of the object (TempFileObject::FILE or
|
||||
* TempFileObject::DIRECTORY).
|
||||
*
|
||||
* Returns: A reference to the file object.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
temporary_file_objects.push(new TempFileObject(filename, type));
|
||||
return *temporary_file_objects.top();
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
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.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
TempFileObject& external_program_input_file = registerTempFileObject();
|
||||
|
||||
TempFileObject& external_program_output_file = registerTempFileObject();
|
||||
|
||||
string translated_formula;
|
||||
translateFormula(formula, translated_formula);
|
||||
|
||||
ofstream input_file;
|
||||
input_file.open(external_program_input_file.getName().c_str(),
|
||||
ios::out | ios::trunc);
|
||||
if (!input_file.good())
|
||||
throw FileCreationException(string("`")
|
||||
+ external_program_input_file.getName()
|
||||
+ "'");
|
||||
|
||||
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.getName(),
|
||||
external_program_output_file.getName());
|
||||
|
||||
if (!execSuccess(system(command_line.c_str())))
|
||||
throw ExecFailedException(command_line_arguments[2]);
|
||||
|
||||
parseAutomaton(external_program_output_file.getName(), filename);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Function definitions for class ExternalTranslator::TempFileObject.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* ========================================================================= */
|
||||
ExternalTranslator::TempFileObject::TempFileObject
|
||||
(const string& filename, Type t)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Constructor for class TempFileObject. Creates a temporary
|
||||
* file or a directory and tests whether it can really be
|
||||
* written to (if not, a FileCreationException is thrown).
|
||||
*
|
||||
* Arguments: filename -- Name of the temporary file or directory.
|
||||
* If the filename is an empty string, the
|
||||
* filename is obtained by a call to tmpnam(3).
|
||||
* t -- Type of the object (TempFileObject::FILE or
|
||||
* TempFileObject::DIRECTORY).
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
if (filename.empty())
|
||||
{
|
||||
char tempname[L_tmpnam + 1];
|
||||
|
||||
if (tmpnam(tempname) == 0)
|
||||
throw FileCreationException("a temporary file");
|
||||
|
||||
name = tempname;
|
||||
}
|
||||
else
|
||||
name = filename;
|
||||
|
||||
if (t == FILE)
|
||||
{
|
||||
ofstream tempfile;
|
||||
tempfile.open(name.c_str(), ios::out | ios::trunc);
|
||||
if (!tempfile.good())
|
||||
throw FileCreationException("a temporary file");
|
||||
tempfile.close();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mkdir(name.c_str(), 0700) != 0)
|
||||
throw FileCreationException("a temporary directory");
|
||||
}
|
||||
|
||||
type = t;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
ExternalTranslator::TempFileObject::~TempFileObject()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Destructor for class TempFileObject. Deletes the file or
|
||||
* the directory associated with the object (displays a warning
|
||||
* if this fails).
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
if (remove(name.c_str()) != 0)
|
||||
{
|
||||
string msg("error removing temporary ");
|
||||
|
||||
if (type == TempFileObject::FILE)
|
||||
msg += "file";
|
||||
else
|
||||
msg += "directory";
|
||||
|
||||
msg += " `" + name + "'";
|
||||
|
||||
printWarning(msg);
|
||||
}
|
||||
}
|
||||
388
lbtt/src/ExternalTranslator.h
Normal file
388
lbtt/src/ExternalTranslator.h
Normal file
|
|
@ -0,0 +1,388 @@
|
|||
/*
|
||||
* Copyright (C) 1999, 2000, 2001, 2002
|
||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef EXTERNALTRANSLATOR_H
|
||||
#define EXTERNALTRANSLATOR_H
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma interface
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#include <config.h>
|
||||
#include <deque>
|
||||
#include <stack>
|
||||
#include <string>
|
||||
#ifdef HAVE_SSTREAM
|
||||
#include <sstream>
|
||||
#else
|
||||
#include <strstream>
|
||||
#endif /* HAVE_SSTREAM */
|
||||
#include "Alloc.h"
|
||||
#include "Exception.h"
|
||||
#include "LtlFormula.h"
|
||||
#include "translate.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
|
||||
*
|
||||
* void registerTempFileObject
|
||||
* (const string& filename, TempFileObject::Type t)
|
||||
*
|
||||
* where `filename' is the full name of the temporary file and `t' is a type
|
||||
* of the object (TempFileObject::FILE or TempFileObject::DIRECTORY).
|
||||
*
|
||||
* All files or directories registered using this function will then 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:
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
class TempFileObject /* A class for storing */
|
||||
{ /* information about */
|
||||
public: /* temporary files and
|
||||
* directories.
|
||||
*/
|
||||
|
||||
enum Type {FILE, DIRECTORY}; /* Types for a temporary
|
||||
* file object.
|
||||
*/
|
||||
|
||||
TempFileObject /* Constructor. */
|
||||
(const string& filename = "", Type t = FILE);
|
||||
|
||||
~TempFileObject(); /* Destructor. */
|
||||
|
||||
const string& getName() const; /* Returns the filename
|
||||
* associated with the
|
||||
* object.
|
||||
*/
|
||||
|
||||
Type getType() const; /* Returns the type of
|
||||
* the object.
|
||||
*/
|
||||
|
||||
private:
|
||||
string name; /* Name of the file object.
|
||||
*/
|
||||
|
||||
Type type; /* Type of the file object.
|
||||
*/
|
||||
|
||||
TempFileObject(const TempFileObject&); /* Prevent copying and */
|
||||
TempFileObject& operator= /* assignment of */
|
||||
(const TempFileObject&); /* TempFileObjects. */
|
||||
};
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
ExternalTranslator(); /* Constructor. */
|
||||
|
||||
~ExternalTranslator(); /* Destructor. */
|
||||
|
||||
TempFileObject& registerTempFileObject /* Registers a temporary */
|
||||
(const string& filename = "", /* file or directory */
|
||||
TempFileObject::Type /* such that it will be */
|
||||
t = TempFileObject::FILE); /* automatically deleted
|
||||
* 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<TempFileObject*, /* Stack for storing */
|
||||
deque<TempFileObject*, /* temporary file */
|
||||
ALLOC(TempFileObject*) > > /* information. */
|
||||
temporary_file_objects;
|
||||
|
||||
friend class KecWrapper; /* Friend declarations. */
|
||||
friend class Ltl2AutWrapper;
|
||||
friend class Ltl2BaWrapper;
|
||||
friend class ProdWrapper;
|
||||
friend class SpinWrapper;
|
||||
friend class WringWrapper;
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
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::TempFileObject.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* ========================================================================= */
|
||||
inline const string& ExternalTranslator::TempFileObject::getName() const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Returns the name associated with the
|
||||
* ExternalTranslator::TempFileObject.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: The name associated with the object.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline ExternalTranslator::TempFileObject::Type
|
||||
ExternalTranslator::TempFileObject::getType() const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Returns the type of the ExternalTranslator::TempFileObject.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: The type associated with the object.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* 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 */
|
||||
233
lbtt/src/FormulaRandomizer.cc
Normal file
233
lbtt/src/FormulaRandomizer.cc
Normal file
|
|
@ -0,0 +1,233 @@
|
|||
/*
|
||||
* Copyright (C) 1999, 2000, 2001, 2002
|
||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma implementation
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#include <config.h>
|
||||
#include "FormulaRandomizer.h"
|
||||
#include "Random.h"
|
||||
|
||||
namespace Ltl
|
||||
{
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Function definitions for class FormulaRandomizer.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* ========================================================================= */
|
||||
void FormulaRandomizer::reset()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Sets the random formula generation parameters to their
|
||||
* default values.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
number_of_available_variables = 5;
|
||||
size = 5;
|
||||
max_size = 5;
|
||||
propositional_symbol_priorities.clear();
|
||||
short_formula_operators.clear();
|
||||
long_formula_operators.clear();
|
||||
propositional_symbol_priorities.push_back(make_pair(-1, 0));
|
||||
short_formula_operators.push_back(make_pair(-1, 0));
|
||||
long_formula_operators.push_back(make_pair(-1, 0));
|
||||
number_of_generated_formulas = 0;
|
||||
proposition_statistics.clear();
|
||||
symbol_statistics.clear();
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
LtlFormula* FormulaRandomizer::generate()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Generates a random (newly allocated) LtlFormula using the
|
||||
* parameters stored in `this' object.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: A pointer to the generated formula.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
unsigned long int target_size(size);
|
||||
|
||||
if (max_size > size)
|
||||
target_size += LRAND(0, max_size - size + 1);
|
||||
|
||||
number_of_generated_formulas++;
|
||||
return recGenerate(target_size);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
LtlFormula* FormulaRandomizer::recGenerate(unsigned long int target_size)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Implementation of the recursive random formula generation
|
||||
* algorithm.
|
||||
*
|
||||
* Arguments: target_size -- Size of the formula to be generated.
|
||||
*
|
||||
* Returns: A pointer to the generated formula.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
vector<IntegerPair, ALLOC(IntegerPair) >::const_iterator symbol_priority;
|
||||
LtlFormula* formula;
|
||||
long int x;
|
||||
|
||||
/*
|
||||
* Select a list of allowable symbols according to the target size. If the
|
||||
* size is 1, only atomic propositions and Boolean constants are allowed
|
||||
* If the size is 2, only unary operators are allowed. Otherwise select the
|
||||
* symbols from the set of unary and binary operators.
|
||||
*/
|
||||
|
||||
switch (target_size)
|
||||
{
|
||||
case 1 :
|
||||
x = LRAND(0, propositional_symbol_priorities[0].second);
|
||||
symbol_priority = propositional_symbol_priorities.begin();
|
||||
break;
|
||||
|
||||
case 2 :
|
||||
x = LRAND(0, short_formula_operators[0].second);
|
||||
symbol_priority = short_formula_operators.begin();
|
||||
break;
|
||||
|
||||
default :
|
||||
x = LRAND(0, long_formula_operators[0].second);
|
||||
symbol_priority = long_formula_operators.begin();
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Using the selected list, choose a random symbol in the list using the
|
||||
* priority distribution of the different symbols in the list. The list
|
||||
* consists of <symbol, priority> pairs. The first element of the list does
|
||||
* not correspond to any symbol, however; instead, it gives the sum of the
|
||||
* priorities of the symbols in the list.
|
||||
*/
|
||||
|
||||
++symbol_priority;
|
||||
while (x >= symbol_priority->second)
|
||||
{
|
||||
x -= symbol_priority->second;
|
||||
++symbol_priority;
|
||||
}
|
||||
|
||||
symbol_statistics[symbol_priority->first]++;
|
||||
|
||||
switch (symbol_priority->first)
|
||||
{
|
||||
case LTL_ATOM :
|
||||
{
|
||||
unsigned long int atom = LRAND(0, number_of_available_variables);
|
||||
proposition_statistics[atom]++;
|
||||
formula = &Atom::construct(atom);
|
||||
break;
|
||||
}
|
||||
|
||||
case LTL_TRUE :
|
||||
formula = &True::construct();
|
||||
break;
|
||||
|
||||
case LTL_FALSE :
|
||||
formula = &False::construct();
|
||||
break;
|
||||
|
||||
case LTL_NEGATION :
|
||||
formula = &Not::construct(recGenerate(target_size - 1));
|
||||
break;
|
||||
|
||||
case LTL_NEXT :
|
||||
formula = &Next::construct(recGenerate(target_size - 1));
|
||||
break;
|
||||
|
||||
case LTL_FINALLY :
|
||||
formula = &Finally::construct(recGenerate(target_size - 1));
|
||||
break;
|
||||
|
||||
case LTL_GLOBALLY :
|
||||
formula = &Globally::construct(recGenerate(target_size - 1));
|
||||
break;
|
||||
|
||||
default :
|
||||
{
|
||||
unsigned long int s = LRAND(1, target_size - 1);
|
||||
LtlFormula* g = recGenerate(s);
|
||||
LtlFormula* h = recGenerate(target_size - s - 1);
|
||||
|
||||
switch (symbol_priority->first)
|
||||
{
|
||||
case LTL_CONJUNCTION :
|
||||
formula = &And::construct(g, h);
|
||||
break;
|
||||
|
||||
case LTL_DISJUNCTION :
|
||||
formula = &Or::construct(g, h);
|
||||
break;
|
||||
|
||||
case LTL_IMPLICATION :
|
||||
formula = &Imply::construct(g, h);
|
||||
break;
|
||||
|
||||
case LTL_EQUIVALENCE :
|
||||
formula = &Equiv::construct(g, h);
|
||||
break;
|
||||
|
||||
case LTL_XOR :
|
||||
formula = &Xor::construct(g, h);
|
||||
break;
|
||||
|
||||
case LTL_UNTIL :
|
||||
formula = &Until::construct(g, h);
|
||||
break;
|
||||
|
||||
case LTL_V :
|
||||
formula = &V::construct(g, h);
|
||||
break;
|
||||
|
||||
case LTL_WEAK_UNTIL :
|
||||
formula = &WeakUntil::construct(g, h);
|
||||
break;
|
||||
|
||||
case LTL_STRONG_RELEASE :
|
||||
formula = &StrongRelease::construct(g, h);
|
||||
break;
|
||||
|
||||
default : /* LTL_BEFORE */
|
||||
formula = &Before::construct(g, h);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return formula;
|
||||
}
|
||||
|
||||
}
|
||||
333
lbtt/src/FormulaRandomizer.h
Normal file
333
lbtt/src/FormulaRandomizer.h
Normal file
|
|
@ -0,0 +1,333 @@
|
|||
/*
|
||||
* Copyright (C) 1999, 2000, 2001, 2002
|
||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef FORMULARANDOMIZER_H
|
||||
#define FORMULARANDOMIZER_H
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma interface
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#include <config.h>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include "Alloc.h"
|
||||
#include "LtlFormula.h"
|
||||
|
||||
namespace Ltl
|
||||
{
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Class for generating random LTL formulae.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
class FormulaRandomizer
|
||||
{
|
||||
public:
|
||||
FormulaRandomizer(); /* Constructor. */
|
||||
|
||||
/* default copy constructor */
|
||||
|
||||
~FormulaRandomizer(); /* Destructor. */
|
||||
|
||||
/* default assignment operator */
|
||||
|
||||
void reset(); /* Resets the formula
|
||||
* generation parameters.
|
||||
*/
|
||||
|
||||
void useSymbol /* Inserts an atomic */
|
||||
(const int symbol, const int priority); /* symbol (an atomic
|
||||
* proposition or a
|
||||
* Boolean constant)
|
||||
* into the set of
|
||||
* operands used for
|
||||
* generating random
|
||||
* formulae.
|
||||
*/
|
||||
|
||||
void useShortOperator /* Inserts an element */
|
||||
(const int symbol, const int priority); /* into the set of
|
||||
* operators used for
|
||||
* generating random
|
||||
* formulae of size
|
||||
* two.
|
||||
*/
|
||||
|
||||
void useLongOperator /* Inserts an element */
|
||||
(const int symbol, const int priority); /* into the set of
|
||||
* operators used for
|
||||
* generating random
|
||||
* formulae of size
|
||||
* greater than two.
|
||||
*/
|
||||
|
||||
LtlFormula* generate(); /* Generates a random LTL
|
||||
* formula.
|
||||
*/
|
||||
|
||||
unsigned long int numberOfFormulas() const; /* Get the number of
|
||||
* generated formulas since
|
||||
* the last call to
|
||||
* `reset'.
|
||||
*/
|
||||
|
||||
const map<unsigned long int, unsigned long int, /* Get the numbers of */
|
||||
less<unsigned long int>, /* different atomic */
|
||||
ALLOC(unsigned long int) >& /* propositions */
|
||||
propositionStatistics() const; /* generated since the
|
||||
* last call to `reset'.
|
||||
*/
|
||||
|
||||
const map<int, unsigned long int, less<int>, /* Get the numbers of */
|
||||
ALLOC(unsigned long int) >& /* different symbols */
|
||||
symbolStatistics() const; /* generated since the
|
||||
* last call to `reset'.
|
||||
*/
|
||||
|
||||
unsigned long int number_of_available_variables; /* Size of the set of
|
||||
* atomic propositions used
|
||||
* for generating random
|
||||
* LTL formulae.
|
||||
*/
|
||||
|
||||
unsigned long int size; /* Minimum size of the
|
||||
* generated formulae
|
||||
* (number of nodes in the
|
||||
* formula parse tree).
|
||||
*/
|
||||
|
||||
unsigned long int max_size; /* Maximum size of the
|
||||
* generated formulae.
|
||||
*/
|
||||
|
||||
private:
|
||||
LtlFormula* recGenerate /* Implementation of */
|
||||
(unsigned long int target_size); /* the random formula
|
||||
* generation algorithm.
|
||||
*/
|
||||
|
||||
typedef pair<int, int> IntegerPair;
|
||||
|
||||
vector<IntegerPair, ALLOC(IntegerPair) > /* Operand symbols and */
|
||||
propositional_symbol_priorities; /* their priorities in
|
||||
* random formulae.
|
||||
*/
|
||||
|
||||
vector<IntegerPair, ALLOC(IntegerPair) > /* Operators and their */
|
||||
short_formula_operators; /* priorities in random
|
||||
* formulae of size
|
||||
* two.
|
||||
*/
|
||||
|
||||
vector<IntegerPair, ALLOC(IntegerPair) > /* Operators and their */
|
||||
long_formula_operators; /* priorities in random
|
||||
* formulae of size
|
||||
* greater than two.
|
||||
*/
|
||||
|
||||
unsigned long int number_of_generated_formulas; /* Number of generated
|
||||
* formulas since the
|
||||
* last call to `reset'.
|
||||
*/
|
||||
|
||||
map<unsigned long int, unsigned long int, /* Number of different */
|
||||
less<unsigned long int>, /* atomic propositions */
|
||||
ALLOC(unsigned long int) > /* generated since the */
|
||||
proposition_statistics; /* last call to `reset' */
|
||||
|
||||
map<int, unsigned long int, less<int>, /* Number of different */
|
||||
ALLOC(unsigned long int) > /* formula symbols */
|
||||
symbol_statistics; /* generated since the
|
||||
* last call to `reset'.
|
||||
*/
|
||||
};
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Inline function definitions for class FormulaRandomizer.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* ========================================================================= */
|
||||
inline FormulaRandomizer::FormulaRandomizer()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Constructor for class FormulaRandomizer. Creates a new
|
||||
* formula parameter information object and initializes the
|
||||
* generation parameters with their default values.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline FormulaRandomizer::~FormulaRandomizer()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Destructor for class FormulaRandomizer.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline void FormulaRandomizer::useSymbol(const int symbol, const int priority)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Inserts an atomic symbol (an atomic proposition or a Boolean
|
||||
* constant) into the set of symbols used for generating random
|
||||
* LTL formulae. The symbol will then be chosen into a formula
|
||||
* by the random formula generation algorithm with a given
|
||||
* priority.
|
||||
*
|
||||
* Arguments: symbol -- A symbol type identifier (one of the LTL_
|
||||
* constants defined in LtlFormula.h).
|
||||
* priority -- Priority for the symbol.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
if (priority > 0)
|
||||
{
|
||||
propositional_symbol_priorities.push_back(make_pair(symbol, priority));
|
||||
propositional_symbol_priorities[0].second += priority;
|
||||
}
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline void FormulaRandomizer::useShortOperator
|
||||
(const int symbol, const int priority)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Inserts a symbol into the set of operators considered when
|
||||
* generating random LTL formulae with two nodes in their parse
|
||||
* tree. The symbol will then be chosen into a formula by the
|
||||
* random formula generation algorithm with a given priority.
|
||||
*
|
||||
* Arguments: symbol -- A symbol type identifier (one of the LTL_
|
||||
* constants defined in LtlFormula.h).
|
||||
* priority -- Priority for the symbol.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
if (priority > 0)
|
||||
{
|
||||
short_formula_operators.push_back(make_pair(symbol, priority));
|
||||
short_formula_operators[0].second += priority;
|
||||
}
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline void FormulaRandomizer::useLongOperator
|
||||
(const int symbol, const int priority)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Inserts a symbol into the set of operators considered when
|
||||
* generating random LTL formulae with two nodes in their parse
|
||||
* tree. The symbol will then be chosen into a formula by the
|
||||
* random formula generation algorithm with a given priority.
|
||||
*
|
||||
* Arguments: symbol -- A symbol type identifier (one of the LTL_
|
||||
* constants defined in LtlFormula.h).
|
||||
* priority -- Priority for the symbol.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
if (priority > 0)
|
||||
{
|
||||
long_formula_operators.push_back(make_pair(symbol, priority));
|
||||
long_formula_operators[0].second += priority;
|
||||
}
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline unsigned long int FormulaRandomizer::numberOfFormulas() const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Tells the number of formulae generated since the last call to
|
||||
* `reset'.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Number of formulae generated since the last call to `reset'.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return number_of_generated_formulas;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline const map<unsigned long int, unsigned long int, less<unsigned long int>,
|
||||
ALLOC(unsigned long int) >&
|
||||
FormulaRandomizer::propositionStatistics() const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Tells the number of different atomic propositions generated
|
||||
* since the last call to `reset'.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: A reference to a constant mapping between proposition
|
||||
* identifiers and their numbers.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return proposition_statistics;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline const map<int, unsigned long int, less<int>, ALLOC(unsigned long int) >&
|
||||
FormulaRandomizer::symbolStatistics() const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Tells the number of different formula symbols generated since
|
||||
* the last call to `reset'.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: A reference to a constant mapping between LTL formula symbols
|
||||
* and their numbers.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return symbol_statistics;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif /* !FORMULARANDOMIZER_H */
|
||||
452
lbtt/src/FormulaWriter.h
Normal file
452
lbtt/src/FormulaWriter.h
Normal file
|
|
@ -0,0 +1,452 @@
|
|||
/*
|
||||
* Copyright (C) 1999, 2000, 2001, 2002
|
||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef FORMULAWRITER_H
|
||||
#define FORMULAWRITER_H
|
||||
|
||||
#include "Exception.h"
|
||||
|
||||
namespace Ltl
|
||||
{
|
||||
|
||||
class LtlFormula;
|
||||
class Atom;
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* A function template class for writing the formula to a stream.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
template<class TrueWriter, class FalseWriter, class AtomWriter,
|
||||
class NotWriter, class NextWriter, class FinallyWriter,
|
||||
class GloballyWriter, class AndWriter, class OrWriter,
|
||||
class ImplyWriter, class EquivWriter, class XorWriter,
|
||||
class UntilWriter, class ReleaseWriter, class WeakUntilWriter,
|
||||
class StrongReleaseWriter, class BeforeWriter>
|
||||
class FormulaWriter
|
||||
{
|
||||
public:
|
||||
FormulaWriter(Exceptional_ostream& stream); /* Constructor. */
|
||||
|
||||
~FormulaWriter(); /* Destructor. */
|
||||
|
||||
void operator() /* Implements the write */
|
||||
(const LtlFormula* f, int operand); /* operation. */
|
||||
|
||||
private:
|
||||
Exceptional_ostream& estream; /* Output stream. */
|
||||
|
||||
FormulaWriter(const FormulaWriter&); /* Prevent copying and */
|
||||
FormulaWriter& operator=(const FormulaWriter&); /* assignment of
|
||||
* FormulaWriter
|
||||
* objects.
|
||||
*/
|
||||
};
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Class for printing atomic propositions.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
class AtomWriter
|
||||
{
|
||||
public:
|
||||
static void write /* Implements the write */
|
||||
(Exceptional_ostream& estream, /* operation. */
|
||||
long int atom_id);
|
||||
};
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Template class for printing Boolean constants.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
template<const char* symbol>
|
||||
class ConstantWriter
|
||||
{
|
||||
public:
|
||||
static void write(Exceptional_ostream& estream); /* Implements the write */
|
||||
}; /* operation. */
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Template class for printing unary operators.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
template<const char* symbol>
|
||||
class UnaryOperatorWriter
|
||||
{
|
||||
public:
|
||||
static void write /* Implements the write */
|
||||
(Exceptional_ostream& estream, int operand); /* operation. */
|
||||
};
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Template class for printing binary operators in prefix notation.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
template<const char* symbol>
|
||||
class BinaryOperatorPrefixWriter
|
||||
{
|
||||
public:
|
||||
static void write /* Implements the write */
|
||||
(Exceptional_ostream& estream, int operand); /* operation. */
|
||||
};
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Template class for printing binary operators in infix notation.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
template<const char* symbol>
|
||||
class BinaryOperatorInfixWriter
|
||||
{
|
||||
public:
|
||||
static void write /* Implements the write */
|
||||
(Exceptional_ostream& estream, int operand); /* operation. */
|
||||
};
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Inline function definitions for template class FormulaWriter.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* ========================================================================= */
|
||||
template<class TrueWriter, class FalseWriter, class AtomWriter,
|
||||
class NotWriter, class NextWriter, class FinallyWriter,
|
||||
class GloballyWriter, class AndWriter, class OrWriter,
|
||||
class ImplyWriter, class EquivWriter, class XorWriter,
|
||||
class UntilWriter, class ReleaseWriter, class WeakUntilWriter,
|
||||
class StrongReleaseWriter, class BeforeWriter>
|
||||
inline FormulaWriter<TrueWriter, FalseWriter, AtomWriter, NotWriter,
|
||||
NextWriter, FinallyWriter, GloballyWriter, AndWriter,
|
||||
OrWriter, ImplyWriter, EquivWriter, XorWriter,
|
||||
UntilWriter, ReleaseWriter, WeakUntilWriter,
|
||||
StrongReleaseWriter, BeforeWriter>::
|
||||
FormulaWriter(Exceptional_ostream& stream) :
|
||||
estream(stream)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Constructor for class FormulaWriter.
|
||||
*
|
||||
* Arguments: stream -- A reference to an exception-aware output
|
||||
* stream.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
template<class TrueWriter, class FalseWriter, class AtomWriter,
|
||||
class NotWriter, class NextWriter, class FinallyWriter,
|
||||
class GloballyWriter, class AndWriter, class OrWriter,
|
||||
class ImplyWriter, class EquivWriter, class XorWriter,
|
||||
class UntilWriter, class ReleaseWriter, class WeakUntilWriter,
|
||||
class StrongReleaseWriter, class BeforeWriter>
|
||||
inline FormulaWriter<TrueWriter, FalseWriter, AtomWriter, NotWriter,
|
||||
NextWriter, FinallyWriter, GloballyWriter, AndWriter,
|
||||
OrWriter, ImplyWriter, EquivWriter, XorWriter,
|
||||
UntilWriter, ReleaseWriter, WeakUntilWriter,
|
||||
StrongReleaseWriter, BeforeWriter>::
|
||||
~FormulaWriter()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Destructor for class FormulaWriter.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Inline function definitions for class AtomWriter.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* ========================================================================= */
|
||||
inline void AtomWriter::write
|
||||
(Exceptional_ostream& estream, long int atom_id)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Writes an atomic proposition into a stream.
|
||||
*
|
||||
* Arguments: estream -- A reference to an exception-aware output stream.
|
||||
* atom_id -- Numeric identifier of the proposition.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
estream << 'p' << atom_id;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Inline function definitions for template class ConstantWriter.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* ========================================================================= */
|
||||
template<const char* symbol>
|
||||
inline void ConstantWriter<symbol>::write(Exceptional_ostream& estream)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Writes a Boolean constant into a stream.
|
||||
*
|
||||
* Arguments: estream -- A reference to an exception-aware output stream.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
estream << symbol;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Inline function definitions for template class UnaryOperatorWriter.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* ========================================================================= */
|
||||
template<const char* symbol>
|
||||
inline void UnaryOperatorWriter<symbol>::write
|
||||
(Exceptional_ostream& estream, int operand)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Writes an unary operator symbol into a stream.
|
||||
*
|
||||
* Arguments: estream -- A reference to an exception-aware output stream.
|
||||
* operand -- Identifies the state of the depth-first search
|
||||
* that manages the writing. The operator will be
|
||||
* written to the stream if and only if `operand'
|
||||
* has the value 0.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
if (operand == 0)
|
||||
estream << symbol << ' ';
|
||||
}
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Inline function definitions for template class BinaryOperatorPrefixWriter.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* ========================================================================= */
|
||||
template<const char* symbol>
|
||||
inline void BinaryOperatorPrefixWriter<symbol>::write
|
||||
(Exceptional_ostream& estream, int operand)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Writes a binary operator symbol into a stream.
|
||||
*
|
||||
* Arguments: estream -- A reference to an exception-aware output stream.
|
||||
* operand -- Identifies the state of the depth-first search
|
||||
* that manages thel writing. This value is used to
|
||||
* decide what to write to the stream.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
if (operand == 0)
|
||||
estream << symbol << ' ';
|
||||
else if (operand == 1)
|
||||
estream << ' ';
|
||||
}
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Inline function definitions for template class BinaryOperatorInfixWriter.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* ========================================================================= */
|
||||
template<const char* symbol>
|
||||
inline void BinaryOperatorInfixWriter<symbol>::write
|
||||
(Exceptional_ostream& estream, int operand)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Writes a binary operator symbol into a stream.
|
||||
*
|
||||
* Arguments: estream -- A reference to an exception-aware output stream.
|
||||
* operand -- Identifies the state of the depth-first search
|
||||
* that manages the writing. This value is
|
||||
* used to decide what to write to the stream.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
if (operand == 0)
|
||||
estream << '(';
|
||||
else if (operand == 1)
|
||||
estream << ' ' << symbol << ' ';
|
||||
else
|
||||
estream << ')';
|
||||
}
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Function definitions for template class FormulaWriter.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* ========================================================================= */
|
||||
template<class TrueWriter, class FalseWriter, class AtomWriter,
|
||||
class NotWriter, class NextWriter, class FinallyWriter,
|
||||
class GloballyWriter, class AndWriter, class OrWriter,
|
||||
class ImplyWriter, class EquivWriter, class XorWriter,
|
||||
class UntilWriter, class ReleaseWriter, class WeakUntilWriter,
|
||||
class StrongReleaseWriter, class BeforeWriter>
|
||||
void FormulaWriter<TrueWriter, FalseWriter, AtomWriter, NotWriter, NextWriter,
|
||||
FinallyWriter, GloballyWriter, AndWriter, OrWriter,
|
||||
ImplyWriter, EquivWriter, XorWriter, UntilWriter,
|
||||
ReleaseWriter, WeakUntilWriter, StrongReleaseWriter,
|
||||
BeforeWriter>::
|
||||
operator()(const LtlFormula* f, int operand)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Implements the formula writing operation.
|
||||
*
|
||||
* Arguments: f -- A pointer to a constant LtlFormula.
|
||||
* operand -- Used for checking when to write certain `extra'
|
||||
* symbols (parentheses or spaces) to the stream.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
switch (f->what())
|
||||
{
|
||||
case LTL_ATOM :
|
||||
AtomWriter::write(estream, static_cast<const Atom*>(f)->getId());
|
||||
break;
|
||||
|
||||
case LTL_TRUE :
|
||||
TrueWriter::write(estream);
|
||||
break;
|
||||
|
||||
case LTL_FALSE :
|
||||
FalseWriter::write(estream);
|
||||
break;
|
||||
|
||||
case LTL_NEGATION :
|
||||
NotWriter::write(estream, operand);
|
||||
break;
|
||||
|
||||
case LTL_NEXT :
|
||||
NextWriter::write(estream, operand);
|
||||
break;
|
||||
|
||||
case LTL_FINALLY :
|
||||
FinallyWriter::write(estream, operand);
|
||||
break;
|
||||
|
||||
case LTL_GLOBALLY :
|
||||
GloballyWriter::write(estream, operand);
|
||||
break;
|
||||
|
||||
case LTL_CONJUNCTION :
|
||||
AndWriter::write(estream, operand);
|
||||
break;
|
||||
|
||||
case LTL_DISJUNCTION :
|
||||
OrWriter::write(estream, operand);
|
||||
break;
|
||||
|
||||
case LTL_IMPLICATION :
|
||||
ImplyWriter::write(estream, operand);
|
||||
break;
|
||||
|
||||
case LTL_EQUIVALENCE :
|
||||
EquivWriter::write(estream, operand);
|
||||
break;
|
||||
|
||||
case LTL_XOR :
|
||||
XorWriter::write(estream, operand);
|
||||
break;
|
||||
|
||||
case LTL_UNTIL :
|
||||
UntilWriter::write(estream, operand);
|
||||
break;
|
||||
|
||||
case LTL_V :
|
||||
ReleaseWriter::write(estream, operand);
|
||||
break;
|
||||
|
||||
case LTL_WEAK_UNTIL :
|
||||
WeakUntilWriter::write(estream, operand);
|
||||
break;
|
||||
|
||||
case LTL_STRONG_RELEASE :
|
||||
StrongReleaseWriter::write(estream, operand);
|
||||
break;
|
||||
|
||||
default : /* LTL_BEFORE */
|
||||
BeforeWriter::write(estream, operand);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif /* !FORMULAWRITER_H */
|
||||
1859
lbtt/src/Graph.h.in
Normal file
1859
lbtt/src/Graph.h.in
Normal file
File diff suppressed because it is too large
Load diff
135
lbtt/src/LbtWrapper.h
Normal file
135
lbtt/src/LbtWrapper.h
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
* Copyright (C) 1999, 2000, 2001, 2002
|
||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef LBTWRAPPER_H
|
||||
#define LBTWRAPPER_H
|
||||
|
||||
#include <config.h>
|
||||
#include <string>
|
||||
#include "ExternalTranslator.h"
|
||||
#include "translate.h"
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Interface class for lbt.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
class LbtWrapper : public ExternalTranslator
|
||||
{
|
||||
public:
|
||||
LbtWrapper(); /* Constructor. */
|
||||
|
||||
~LbtWrapper(); /* Destructor. */
|
||||
|
||||
/* `translateFormula' inherited from ExternalTranslator */
|
||||
|
||||
/* `formatInput' inherited from ExternalTranslator */
|
||||
|
||||
string commandLine /* Prepares the command */
|
||||
(const string& input_filename, /* line for executing */
|
||||
const string&); /* lbt. */
|
||||
|
||||
/* `execSuccess' inherited from ExternalTranslator */
|
||||
|
||||
void parseAutomaton /* Dummy function, */
|
||||
(const string&, const string&); /* needed to support the
|
||||
* ExternalTranslator
|
||||
* interface.
|
||||
*/
|
||||
|
||||
private:
|
||||
LbtWrapper(const LbtWrapper&); /* Prevent copying and */
|
||||
LbtWrapper& operator=(const LbtWrapper&); /* assignment of
|
||||
* LbtWrapper objects.
|
||||
*/
|
||||
};
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Inline function definitions for class LbtWrapper.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* ========================================================================= */
|
||||
inline LbtWrapper::LbtWrapper()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Constructor for class LbtWrapper.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline LbtWrapper::~LbtWrapper()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Destructor for class LbtWrapper.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline string LbtWrapper::commandLine
|
||||
(const string& input_filename, const string&)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Prepares the command line for lbt.
|
||||
*
|
||||
* Arguments: input_filename -- Name of the input file.
|
||||
* The other argument is only needed for supporting the
|
||||
* ExternalTranslator interface; the output will be written to
|
||||
* the filename stored in `command_line_arguments[4]'.
|
||||
*
|
||||
* Returns: The command line string.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return string(" <") + input_filename + " >"
|
||||
+ string(command_line_arguments[4]);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline void LbtWrapper::parseAutomaton(const string&, const string&)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Dummy function which is needed to support the
|
||||
* ExternalTranslator interface.
|
||||
*
|
||||
* Arguments: References to two constant strings.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
}
|
||||
|
||||
#endif /* !LBTWRAPPER_H */
|
||||
1329
lbtt/src/LtlFormula.cc
Normal file
1329
lbtt/src/LtlFormula.cc
Normal file
File diff suppressed because it is too large
Load diff
2659
lbtt/src/LtlFormula.h
Normal file
2659
lbtt/src/LtlFormula.h
Normal file
File diff suppressed because it is too large
Load diff
22
lbtt/src/Makefile.am
Normal file
22
lbtt/src/Makefile.am
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
bin_PROGRAMS = lbtt lbtt-translate
|
||||
lbtt_SOURCES = Alloc.h BitArray.h Bitset.h BitArray.cc BuchiAutomaton.h \
|
||||
BuchiAutomaton.cc Config-parse.yy Config-lex.ll Configuration.h \
|
||||
Configuration.cc DispUtil.h DispUtil.cc EdgeContainer.h Exception.h \
|
||||
FormulaRandomizer.h FormulaRandomizer.cc FormulaWriter.h LtlFormula.h \
|
||||
LtlFormula.cc main.cc PathEvaluator.h PathEvaluator.cc PathIterator.h \
|
||||
PathIterator.cc ProductAutomaton.h ProductAutomaton.cc Random.h SccIterator.h \
|
||||
SharedTestData.h StatDisplay.h StatDisplay.cc StateSpace.h StateSpace.cc \
|
||||
StateSpaceRandomizer.h StateSpaceRandomizer.cc StringUtil.h StringUtil.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.h
|
||||
lbtt_LDADD = @LIBOBJS@ @READLINELIBS@
|
||||
|
||||
lbtt_translate_SOURCES = Alloc.h BitArray.h BitArray.cc Exception.h \
|
||||
ExternalTranslator.h ExternalTranslator.cc FormulaWriter.h LbtWrapper.h \
|
||||
LtlFormula.h LtlFormula.cc NeverClaim-parse.yy NeverClaim-lex.ll \
|
||||
NeverClaimAutomaton.h NeverClaimAutomaton.cc SpinWrapper.h SpinWrapper.cc \
|
||||
StringUtil.h StringUtil.cc translate.h translate.cc TranslatorInterface.h
|
||||
EXTRA_lbtt_translate_SOURCES = gnu-getopt.h NeverClaim-parse.h
|
||||
lbtt_translate_LDADD = @LIBOBJS@
|
||||
187
lbtt/src/NeverClaim-lex.ll
Normal file
187
lbtt/src/NeverClaim-lex.ll
Normal file
|
|
@ -0,0 +1,187 @@
|
|||
/*
|
||||
* Copyright (C) 1999, 2000, 2001, 2002
|
||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
%{
|
||||
#include <config.h>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include "LtlFormula.h"
|
||||
#include "NeverClaim-parse.h"
|
||||
|
||||
extern string current_neverclaim_line;
|
||||
extern int current_neverclaim_line_number;
|
||||
%}
|
||||
|
||||
%option never-interactive
|
||||
%option noyywrap
|
||||
|
||||
%%
|
||||
|
||||
[ \t] {
|
||||
current_neverclaim_line += yytext;
|
||||
/* Skip whitespace. */
|
||||
}
|
||||
\n {
|
||||
current_neverclaim_line = "";
|
||||
current_neverclaim_line_number++;
|
||||
/* Skip newlines. */
|
||||
}
|
||||
"/*"([^\*]*(\*[^/])?)*"*/" {
|
||||
char* s = yytext, *t;
|
||||
|
||||
do
|
||||
{
|
||||
t = strchr(s, '\n');
|
||||
if (t != static_cast<char*>(0))
|
||||
{
|
||||
current_neverclaim_line = "";
|
||||
current_neverclaim_line_number++;
|
||||
s = t + 1;
|
||||
}
|
||||
}
|
||||
while (t != static_cast<char*>(0));
|
||||
|
||||
current_neverclaim_line += s;
|
||||
|
||||
/* Skip comments. */
|
||||
}
|
||||
|
||||
never {
|
||||
current_neverclaim_line += yytext;
|
||||
return NC_NEVER;
|
||||
}
|
||||
|
||||
if {
|
||||
current_neverclaim_line += yytext;
|
||||
return NC_IF;
|
||||
}
|
||||
|
||||
fi {
|
||||
current_neverclaim_line += yytext;
|
||||
return NC_FI;
|
||||
}
|
||||
|
||||
goto {
|
||||
current_neverclaim_line += yytext;
|
||||
return NC_GOTO;
|
||||
}
|
||||
|
||||
skip {
|
||||
current_neverclaim_line += yytext;
|
||||
return NC_SKIP;
|
||||
}
|
||||
|
||||
"::" {
|
||||
current_neverclaim_line += yytext;
|
||||
return NC_DOUBLE_COLON;
|
||||
}
|
||||
|
||||
":" {
|
||||
current_neverclaim_line += yytext;
|
||||
return NC_COLON;
|
||||
}
|
||||
|
||||
";" {
|
||||
current_neverclaim_line += yytext;
|
||||
return NC_SEMICOLON;
|
||||
}
|
||||
|
||||
"{" {
|
||||
current_neverclaim_line += yytext;
|
||||
return NC_LBRACE;
|
||||
}
|
||||
|
||||
"}" {
|
||||
current_neverclaim_line += yytext;
|
||||
return NC_RBRACE;
|
||||
}
|
||||
|
||||
"(" {
|
||||
current_neverclaim_line += yytext;
|
||||
return NC_LPAREN;
|
||||
}
|
||||
|
||||
")" {
|
||||
current_neverclaim_line += yytext;
|
||||
return NC_RPAREN;
|
||||
}
|
||||
|
||||
"->" {
|
||||
current_neverclaim_line += yytext;
|
||||
return NC_RIGHT_ARROW;
|
||||
}
|
||||
|
||||
"p"[0-9]+ {
|
||||
current_neverclaim_line += yytext;
|
||||
yylval.pf = new string(yytext);
|
||||
return NC_PROPOSITION;
|
||||
}
|
||||
|
||||
"1"|true {
|
||||
current_neverclaim_line += yytext;
|
||||
yylval.pf = new string;
|
||||
*yylval.pf += ::Ltl::LtlTrue::prefix_symbol;
|
||||
return NC_TRUE;
|
||||
}
|
||||
|
||||
"0"|false {
|
||||
current_neverclaim_line += yytext;
|
||||
yylval.pf = new string;
|
||||
*yylval.pf += ::Ltl::LtlFalse::prefix_symbol;
|
||||
return NC_FALSE;
|
||||
}
|
||||
|
||||
"||" {
|
||||
current_neverclaim_line += yytext;
|
||||
return NC_OR;
|
||||
}
|
||||
|
||||
"&&" {
|
||||
current_neverclaim_line += yytext;
|
||||
return NC_AND;
|
||||
}
|
||||
|
||||
"!" {
|
||||
current_neverclaim_line += yytext;
|
||||
return NC_NOT;
|
||||
}
|
||||
|
||||
[A-Za-z_][A-Za-z0-9_]* {
|
||||
current_neverclaim_line += yytext;
|
||||
yylval.str = new string(yytext);
|
||||
return NC_LABEL;
|
||||
}
|
||||
|
||||
%%
|
||||
|
||||
/* ========================================================================= */
|
||||
int getCharacter()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Reads the next character from the lexer input stream.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: The next character in the lexer input stream or EOF if there
|
||||
* are no more characters to read.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return yyinput();
|
||||
}
|
||||
301
lbtt/src/NeverClaim-parse.yy
Normal file
301
lbtt/src/NeverClaim-parse.yy
Normal file
|
|
@ -0,0 +1,301 @@
|
|||
/*
|
||||
* Copyright (C) 1999, 2000, 2001, 2002
|
||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
%{
|
||||
|
||||
#include <config.h>
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
#include "LtlFormula.h"
|
||||
#include "NeverClaimAutomaton.h"
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Variables used when parsing a never claim.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
static NeverClaimAutomaton* automaton; /* Automaton in which the
|
||||
* results are stored.
|
||||
*/
|
||||
|
||||
string current_neverclaim_line; /* Current input line. */
|
||||
|
||||
int current_neverclaim_line_number; /* Number of the current
|
||||
* line in the never claim
|
||||
* file.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Declarations for external functions and variables (provided by the lexer)
|
||||
* used when parsing a never claim.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
extern void yyrestart(FILE*); /* Changes the input stream
|
||||
* for the lexer (provided
|
||||
* by the lexer).
|
||||
*/
|
||||
|
||||
extern int yylex(); /* Reads the next token
|
||||
* from the input (this
|
||||
* function is provided by
|
||||
* the lexer).
|
||||
*/
|
||||
|
||||
extern int getCharacter(); /* Returns the next
|
||||
* character in the lexer
|
||||
* input stream (defined
|
||||
* in NeverClaim-lex.ll).
|
||||
*/
|
||||
|
||||
extern int yyleng; /* Length of the last
|
||||
* token parsed from the
|
||||
* input (provided by the
|
||||
* lexer).
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Function to be called in case of a parse error.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* ========================================================================= */
|
||||
void yyerror(char*)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Function for reporting never claim parse errors.
|
||||
*
|
||||
* Arguments: A pointer to a char (required to satisfy the function
|
||||
* interface).
|
||||
*
|
||||
* Returns: Nothing. Instead, throws an exception with information about
|
||||
* the location of the error.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
int c;
|
||||
|
||||
string::size_type error_pos = current_neverclaim_line.length();
|
||||
if (error_pos > static_cast<unsigned long int>(yyleng))
|
||||
error_pos -= yyleng;
|
||||
|
||||
do
|
||||
{
|
||||
c = getCharacter();
|
||||
if (c != EOF && c != '\n')
|
||||
current_neverclaim_line += static_cast<char>(c);
|
||||
}
|
||||
while (c != EOF && c != '\n');
|
||||
|
||||
throw ParseErrorException
|
||||
(current_neverclaim_line, current_neverclaim_line_number, error_pos);
|
||||
}
|
||||
|
||||
|
||||
|
||||
%}
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Declarations for terminal and nonterminal symbols used in the grammar rules
|
||||
* below.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* Data types. */
|
||||
|
||||
%union {
|
||||
string* pf;
|
||||
string* str;
|
||||
}
|
||||
|
||||
/* Keywords. */
|
||||
|
||||
%token NC_NEVER NC_IF NC_FI NC_GOTO NC_SKIP
|
||||
|
||||
/* State labels. */
|
||||
|
||||
%token <str> NC_LABEL
|
||||
|
||||
/* Punctuation symbols. */
|
||||
|
||||
%token NC_COLON NC_SEMICOLON NC_DOUBLE_COLON NC_LBRACE NC_RBRACE NC_LPAREN
|
||||
NC_RPAREN NC_RIGHT_ARROW
|
||||
|
||||
/* Propositional formulae. */
|
||||
|
||||
%token <pf> NC_PROPOSITION NC_TRUE NC_FALSE
|
||||
%right NC_OR
|
||||
%right NC_AND
|
||||
%nonassoc NC_NOT
|
||||
|
||||
%type <pf> formula
|
||||
|
||||
%%
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Grammar rule definitions.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
never_claim: NC_NEVER NC_LBRACE states optional_semicolon NC_RBRACE
|
||||
;
|
||||
|
||||
optional_semicolon: NC_SEMICOLON
|
||||
| /* empty */
|
||||
;
|
||||
|
||||
states: state
|
||||
| states NC_SEMICOLON state
|
||||
;
|
||||
|
||||
state: {
|
||||
automaton->addNewState();
|
||||
}
|
||||
state_labels state_body
|
||||
;
|
||||
|
||||
state_labels: NC_LABEL NC_COLON
|
||||
{
|
||||
automaton->addNewLabel(*$1);
|
||||
delete $1;
|
||||
}
|
||||
| state_labels NC_LABEL NC_COLON
|
||||
{
|
||||
automaton->addNewLabel(*$2);
|
||||
delete $2;
|
||||
}
|
||||
;
|
||||
|
||||
state_body: NC_IF transitions NC_FI
|
||||
| NC_SKIP
|
||||
| NC_FALSE
|
||||
{
|
||||
automaton->currentState()->accepting() = false;
|
||||
}
|
||||
| NC_IF NC_DOUBLE_COLON NC_FALSE NC_FI
|
||||
{
|
||||
automaton->currentState()->accepting() = false;
|
||||
}
|
||||
;
|
||||
|
||||
transitions: transition
|
||||
| transitions transition
|
||||
;
|
||||
|
||||
transition: NC_DOUBLE_COLON formula NC_RIGHT_ARROW NC_GOTO NC_LABEL
|
||||
{
|
||||
automaton->currentState()->addTransition(*$5, $2);
|
||||
delete $5;
|
||||
}
|
||||
;
|
||||
|
||||
formula: NC_PROPOSITION
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
| NC_TRUE
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
| NC_FALSE
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
| NC_NOT formula
|
||||
{
|
||||
$$ = new string;
|
||||
*$$ += ::Ltl::LtlNegation::prefix_symbol;
|
||||
*$$ += ' ';
|
||||
*$$ += *$2;
|
||||
delete $2;
|
||||
}
|
||||
| formula NC_AND formula
|
||||
{
|
||||
$$ = new string;
|
||||
*$$ += ::Ltl::LtlConjunction::prefix_symbol;
|
||||
*$$ += ' ';
|
||||
*$$ += *$1;
|
||||
*$$ += ' ';
|
||||
*$$ += *$3;
|
||||
delete $1;
|
||||
delete $3;
|
||||
}
|
||||
| formula NC_OR formula
|
||||
{
|
||||
$$ = new string;
|
||||
*$$ += ::Ltl::LtlDisjunction::prefix_symbol;
|
||||
*$$ += ' ';
|
||||
*$$ += *$1;
|
||||
*$$ += ' ';
|
||||
*$$ += *$3;
|
||||
delete $1;
|
||||
delete $3;
|
||||
}
|
||||
| NC_LPAREN formula NC_RPAREN
|
||||
{
|
||||
$$ = $2;
|
||||
}
|
||||
;
|
||||
|
||||
%%
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Main interface to the parser.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* ========================================================================= */
|
||||
int parseNeverClaim(FILE* stream, NeverClaimAutomaton& a)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Main interface to the never claim file parser. Parses a
|
||||
* never claim and stores the results into the given
|
||||
* NeverClaimAutomaton object.
|
||||
*
|
||||
* Arguments: stream -- A pointer to a file from which the never claim
|
||||
* should be read. The file is assumed to be open
|
||||
* for reading.
|
||||
* a -- A reference to a NeverClaimAutomaton object in
|
||||
* which the results should be stored.
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
yyrestart(stream);
|
||||
automaton = &a;
|
||||
current_neverclaim_line_number = 1;
|
||||
return yyparse();
|
||||
}
|
||||
323
lbtt/src/NeverClaimAutomaton.cc
Normal file
323
lbtt/src/NeverClaimAutomaton.cc
Normal file
|
|
@ -0,0 +1,323 @@
|
|||
/*
|
||||
* Copyright (C) 1999, 2000, 2001, 2002
|
||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma implementation
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#include <config.h>
|
||||
#include <cstdio>
|
||||
#include <fstream>
|
||||
#include "LtlFormula.h"
|
||||
#include "NeverClaimAutomaton.h"
|
||||
#include "StringUtil.h"
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Declarations for functions and variables provided by the parser.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include "NeverClaim-parse.h" /* Include declarations for
|
||||
* the tokens that may be
|
||||
* present in a never claim
|
||||
* file.
|
||||
*/
|
||||
|
||||
extern int parseNeverClaim /* Parser interface. */
|
||||
(FILE*, NeverClaimAutomaton&);
|
||||
|
||||
extern int current_neverclaim_line_number; /* Number of the current
|
||||
* line in the never claim
|
||||
* file.
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Function definitions for class NeverClaimAutomaton.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* ========================================================================= */
|
||||
void NeverClaimAutomaton::clear()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Makes a NeverClaimAutomaton empty.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
for (vector<StateInfo*, ALLOC(StateInfo*) >::iterator
|
||||
state = state_list.begin();
|
||||
state != state_list.end();
|
||||
++state)
|
||||
delete (*state);
|
||||
|
||||
state_list.clear();
|
||||
label_mapping.clear();
|
||||
current_state = 0;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
void NeverClaimAutomaton::read(const char* input_filename)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Initializes a NeverClaimAutomaton by parsing a "never claim"
|
||||
* stored in a file.
|
||||
*
|
||||
* Arguments: input_filename -- A C-style string containing the name of
|
||||
* the input file.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
clear();
|
||||
|
||||
/*
|
||||
* Parse the never claim in the given input file.
|
||||
*/
|
||||
|
||||
FILE* input_file = fopen(input_filename, "r");
|
||||
if (input_file == 0)
|
||||
throw FileOpenException(string("`") + input_filename + "'");
|
||||
|
||||
try
|
||||
{
|
||||
parseNeverClaim(input_file, *this);
|
||||
fclose(input_file);
|
||||
}
|
||||
catch (const ParseErrorException&)
|
||||
{
|
||||
fclose(input_file);
|
||||
clear();
|
||||
throw;
|
||||
}
|
||||
|
||||
if (state_list.size() == 1)
|
||||
state_list[0]->initial() = true;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
void NeverClaimAutomaton::write(const char* output_filename)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Writes a NeverClaimAutomaton to a file in `lbtt' format.
|
||||
*
|
||||
* Arguments: output_filename -- A C-style string containing the name of
|
||||
* the output file.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
ofstream automaton_file;
|
||||
automaton_file.open(output_filename, ios::out | ios::trunc);
|
||||
if (!automaton_file.good())
|
||||
throw FileCreationException(string("`") + output_filename + "'");
|
||||
|
||||
try
|
||||
{
|
||||
Exceptional_ostream eautomaton_file(&automaton_file,
|
||||
ios::failbit | ios::badbit);
|
||||
|
||||
eautomaton_file << ::StringUtil::toString(state_list.size()) + " 1\n";
|
||||
|
||||
/*
|
||||
* Go through the vector of states. For each state, write the following
|
||||
* information to the output file:
|
||||
*
|
||||
* - The number of the state.
|
||||
*
|
||||
* - Information about whether the state is the initial state of
|
||||
* the automaton.
|
||||
*
|
||||
* - Information about whether the state is an accepting state.
|
||||
*
|
||||
* - Transitions from the state to other states (in the form
|
||||
* [state number] [guard formula]; end the transition list with
|
||||
* `-1'.
|
||||
*/
|
||||
|
||||
for (vector<StateInfo*, ALLOC(StateInfo*) >::const_iterator
|
||||
state = state_list.begin();
|
||||
state != state_list.end();
|
||||
++state)
|
||||
{
|
||||
eautomaton_file << ::StringUtil::toString((*state)->number()) + ' '
|
||||
+ ((*state)->initial() ? "1" : "0") + ' '
|
||||
+ ((*state)->accepting() ? "0 " : "") + "-1\n";
|
||||
|
||||
for (multimap<Cstr, Cstr*, less<Cstr>, ALLOC(Cstr*) >::const_iterator
|
||||
transition = (*state)->transitions().begin();
|
||||
transition != (*state)->transitions().end(); ++transition)
|
||||
{
|
||||
if (label_mapping.find(transition->first) == label_mapping.end())
|
||||
{
|
||||
remove(output_filename);
|
||||
automaton_file.close();
|
||||
throw Exception("error in never claim: jump to undefined label `"
|
||||
+ transition->first + "'");
|
||||
}
|
||||
|
||||
eautomaton_file << ::StringUtil::toString
|
||||
((*(label_mapping.find(transition->first))).
|
||||
second->number())
|
||||
+ ' '
|
||||
+ ::StringUtil::toString(*(transition->second))
|
||||
+ '\n';
|
||||
}
|
||||
|
||||
eautomaton_file << "-1\n";
|
||||
}
|
||||
|
||||
automaton_file.close();
|
||||
}
|
||||
catch (const IOException&)
|
||||
{
|
||||
remove(output_filename);
|
||||
automaton_file.close();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
void NeverClaimAutomaton::addNewState()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Adds a state to a NeverClaimAutomaton and makes it the
|
||||
* `current' state of the automaton.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
current_state = new StateInfo(state_list.size());
|
||||
state_list.push_back(current_state);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
void NeverClaimAutomaton::addNewLabel(Cstr& label)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Gives a new label for the `current' state of the automaton.
|
||||
* The following substrings, if present in the label, have the
|
||||
* following side effects (the side effects are cumulative):
|
||||
* - If the label contains the substring "init", the current
|
||||
* state is made an initial state.
|
||||
* - If the label contains the substring "accept", the
|
||||
* current state is made an accepting state.
|
||||
* - If the state is labeled "accept_all", a transition is
|
||||
* added from the state to itself.
|
||||
*
|
||||
* Argument: label -- A string giving the label for the state.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
label_mapping[label] = current_state;
|
||||
|
||||
if (label.find("init") != string::npos)
|
||||
current_state->initial() = true;
|
||||
if (label.find("accept") != string::npos)
|
||||
current_state->accepting() = true;
|
||||
if (label == "accept_all")
|
||||
{
|
||||
string* true_str = new string;
|
||||
*true_str += ::Ltl::LtlTrue::prefix_symbol;
|
||||
current_state->addTransition(label, true_str);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Function definitions for class NeverClaimAutomaton::StateInfo.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* ========================================================================= */
|
||||
NeverClaimAutomaton::StateInfo::~StateInfo()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Destructor for class NeverClaimAutomaton::StateInfo.
|
||||
* Releases the memory allocated by the state object.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
for (multimap<Cstr, Cstr*, less<Cstr>, ALLOC(Cstr*) >::const_iterator
|
||||
transition = state_transitions.begin();
|
||||
transition != state_transitions.end();
|
||||
++transition)
|
||||
delete transition->second;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Function definitions for class ParseErrorException.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* ========================================================================= */
|
||||
ParseErrorException::ParseErrorException
|
||||
(const string& msg, int line_number, string::size_type error_pos) :
|
||||
Exception()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Constructor for class ParseErrorException. Initializes an
|
||||
* exception object with an error message.
|
||||
*
|
||||
* Arguments: msg -- A string containing the error message.
|
||||
* line_number -- If nonzero, `msg' is interpreted as the line
|
||||
* containing the parse error. In this case, the
|
||||
* error message indicates the position of the
|
||||
* error on the line.
|
||||
* error_pos -- Position of the error on the line.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
if (line_number == 0)
|
||||
changeMessage(msg);
|
||||
else
|
||||
{
|
||||
string space_string(msg.substr(0, error_pos));
|
||||
for (string::size_type c = 0; c < msg.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");
|
||||
}
|
||||
}
|
||||
460
lbtt/src/NeverClaimAutomaton.h
Normal file
460
lbtt/src/NeverClaimAutomaton.h
Normal file
|
|
@ -0,0 +1,460 @@
|
|||
/*
|
||||
* Copyright (C) 1999, 2000, 2001, 2002
|
||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef NEVERCLAIMAUTOMATON_H
|
||||
#define NEVERCLAIMAUTOMATON_H
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma interface
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#include <config.h>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include "Alloc.h"
|
||||
#include "Exception.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* A class for representing the Büchi automaton obtained by parsing a "never
|
||||
* claim" (model checker Spin's representation for Büchi automata). This class
|
||||
* provides only a very limited set of operations that suffice for parsing a
|
||||
* never claim and outputting the parsed automaton in the format used by
|
||||
* `lbtt'.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
class NeverClaimAutomaton
|
||||
{
|
||||
private:
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
class StateInfo; /* A class for storing the
|
||||
* states of the automaton.
|
||||
*/
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
typedef const string Cstr;
|
||||
|
||||
public:
|
||||
NeverClaimAutomaton(); /* Constructor. */
|
||||
|
||||
~NeverClaimAutomaton(); /* Destructor. */
|
||||
|
||||
void clear(); /* Makes the automaton
|
||||
* empty.
|
||||
*/
|
||||
|
||||
void read(const char* input_filename); /* Initializes the
|
||||
* automaton by parsing a
|
||||
* never claim stored in a
|
||||
* file.
|
||||
*/
|
||||
|
||||
void write(const char* output_filename); /* Outputs the automaton in
|
||||
* `lbtt' format.
|
||||
*/
|
||||
|
||||
StateInfo* currentState(); /* Returns a pointer to the
|
||||
* `current' state of the
|
||||
* automaton (corresponding
|
||||
* to the most recently
|
||||
* introduced state in the
|
||||
* never claim that is
|
||||
* currently being parsed).
|
||||
*/
|
||||
|
||||
void addNewState(); /* Adds a new state to the
|
||||
* automaton.
|
||||
*/
|
||||
|
||||
void addNewLabel(Cstr& label); /* Adds a new label for the
|
||||
* `current' state of the
|
||||
* automaton (a single
|
||||
* state can have several
|
||||
* different labels).
|
||||
*/
|
||||
|
||||
private:
|
||||
vector<StateInfo*, ALLOC(StateInfo*) > /* States of the */
|
||||
state_list; /* automaton. */
|
||||
|
||||
map<string, StateInfo*, less<string>, /* Mapping from state */
|
||||
ALLOC(StateInfo*) > /* labels to the states */
|
||||
label_mapping; /* itself. */
|
||||
|
||||
StateInfo* current_state; /* Pointer to the state
|
||||
* introduced most recently
|
||||
* in the input file.
|
||||
*/
|
||||
|
||||
NeverClaimAutomaton /* Prevent copying and */
|
||||
(const NeverClaimAutomaton& automaton); /* assignment of */
|
||||
NeverClaimAutomaton& operator= /* NeverClaimAutomaton */
|
||||
(const NeverClaimAutomaton& automaton); /* objects. */
|
||||
};
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* A class for storing the states of a Büchi automaton that is being generated
|
||||
* by parsing a never claim.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
class NeverClaimAutomaton::StateInfo
|
||||
{
|
||||
public:
|
||||
explicit StateInfo(unsigned long int num); /* Constructor. */
|
||||
|
||||
~StateInfo(); /* Destructor. */
|
||||
|
||||
unsigned long int number() const; /* Returns the unique
|
||||
* identifier of the
|
||||
* state.
|
||||
*/
|
||||
|
||||
bool initial() const; /* Returns or changes */
|
||||
bool& initial(); /* the `initialness' */
|
||||
/* of the state.
|
||||
*/
|
||||
|
||||
bool accepting() const; /* Returns or changes */
|
||||
bool& accepting(); /* the acceptance status */
|
||||
/* of the state.
|
||||
*/
|
||||
|
||||
const multimap<Cstr, Cstr*, less<Cstr>, /* Returns the labels of */
|
||||
ALLOC(Cstr*) >& /* the state's successor */
|
||||
transitions() const; /* states, including the
|
||||
* conditions controlling
|
||||
* the enabledness of the
|
||||
* transition.
|
||||
*/
|
||||
|
||||
void addTransition /* Connects the state to */
|
||||
(Cstr& target_label, Cstr* guard); /* another state, given
|
||||
* a state label and a
|
||||
* propositional formula
|
||||
* guarding the transition.
|
||||
*/
|
||||
|
||||
private:
|
||||
StateInfo(const StateInfo&); /* Prevent copying and */
|
||||
StateInfo& operator=(const StateInfo&); /* assignment of
|
||||
* StateInfo objects.
|
||||
*/
|
||||
|
||||
unsigned long int state_number; /* Unique state identifier.
|
||||
*/
|
||||
|
||||
bool is_initial; /* Is the state an initial
|
||||
* state?
|
||||
*/
|
||||
|
||||
bool accept; /* Is the state an
|
||||
* accepting state?
|
||||
*/
|
||||
|
||||
multimap<Cstr, Cstr*, less<Cstr>, ALLOC(Cstr*) > /* Labels of the state's */
|
||||
state_transitions; /* successors, including
|
||||
* the guard formulae
|
||||
* controlling the
|
||||
* enabledness of the
|
||||
* transitions between
|
||||
* states.
|
||||
*/
|
||||
};
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* A class for reporting errors when parsing a never claim.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
class ParseErrorException : public Exception
|
||||
{
|
||||
public:
|
||||
ParseErrorException /* Constructor. */
|
||||
(const string& msg
|
||||
= "error parsing never claim",
|
||||
int line_number = 0,
|
||||
string::size_type error_pos = 0);
|
||||
|
||||
/* default copy constructor */
|
||||
|
||||
~ParseErrorException() throw(); /* Destructor. */
|
||||
|
||||
ParseErrorException& operator= /* Assignment operator. */
|
||||
(const ParseErrorException& e);
|
||||
};
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Inline function definitions for class NeverClaimAutomaton.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* ========================================================================= */
|
||||
inline NeverClaimAutomaton::NeverClaimAutomaton() :
|
||||
current_state(static_cast<StateInfo*>(0))
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Constructor for class NeverClaimAutomaton. Creates an empty
|
||||
* automaton.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline NeverClaimAutomaton::~NeverClaimAutomaton()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Destructor for class NeverClaimAutomaton.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline NeverClaimAutomaton::StateInfo* NeverClaimAutomaton::currentState()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Returns a pointer to the "current" state of the automaton,
|
||||
* i.e., the state corresponding to the most recently introduced
|
||||
* state parsed from the never claim.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: A pointer to the state.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return current_state;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Inline function definitions for class NeverClaimAutomaton::StateInfo.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* ========================================================================= */
|
||||
inline NeverClaimAutomaton::StateInfo::StateInfo(unsigned long int num) :
|
||||
state_number(num), is_initial(false), accept(false)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Constructor for class NeverClaimAutomaton::StateInfo.
|
||||
* Creates a new state with a given identifier. By default, the
|
||||
* created state will be noninitial and nonaccepting.
|
||||
*
|
||||
* Arguments: num -- Numeric identifier for the state.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline unsigned long int NeverClaimAutomaton::StateInfo::number() const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Tells the identifier of a state.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: The identifier of the state.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return state_number;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline bool NeverClaimAutomaton::StateInfo::initial() const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Tells whether the state is an initial state. This function
|
||||
* can be used only for querying the value.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Truth value telling whether the state is an initial state.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return is_initial;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline bool& NeverClaimAutomaton::StateInfo::initial()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Tells whether the state is an initial state. This function
|
||||
* can be also used to change the `initialness' of the state.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: A reference to a truth value telling whether the state is an
|
||||
* initial state.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return is_initial;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline bool NeverClaimAutomaton::StateInfo::accepting() const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Tells whether the state is an accepting state. This function
|
||||
* can be used only for querying the acceptance status.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: A truth value telling whether the state is an accepting
|
||||
* state.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return accept;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline bool& NeverClaimAutomaton::StateInfo::accepting()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Tells whether the state is an accepting state. This function
|
||||
* can also be used to change the acceptance status.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: A reference to a truth value telling whether the state is an
|
||||
* accepting state.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return accept;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline const multimap<NeverClaimAutomaton::Cstr, NeverClaimAutomaton::Cstr*,
|
||||
less<NeverClaimAutomaton::Cstr>,
|
||||
ALLOC(NeverClaimAutomaton::Cstr*) >&
|
||||
NeverClaimAutomaton::StateInfo::transitions() const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Returns the set of labels of the state's successor states,
|
||||
* including the propositional formulae containing the
|
||||
* conditions (propositional formulae) controlling the
|
||||
* enabledness of the transitions the state and its successors.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: A constant reference to a constant multimap object containing
|
||||
* the successor information.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return state_transitions;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline void NeverClaimAutomaton::StateInfo::addTransition
|
||||
(Cstr& target_label, Cstr* guard)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Connects the state to another state.
|
||||
*
|
||||
* Arguments: target_label -- Label of the target state.
|
||||
* guard -- A pointer to a constant string containing
|
||||
* the guard (a propositional formula) for
|
||||
* the transition.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
state_transitions.insert(make_pair(target_label, guard));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Inline function definitions for class ParseErrorException.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* ========================================================================= */
|
||||
inline ParseErrorException::~ParseErrorException() throw()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Destructor for class ParseErrorException.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline ParseErrorException&
|
||||
ParseErrorException::operator=(const ParseErrorException& e)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Assignment operator for class ParseErrorException.
|
||||
*
|
||||
* Argument: e -- A reference to a constant exception object of the
|
||||
* same type.
|
||||
*
|
||||
* Returns: A reference to the exception object assigned to.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
Exception::operator=(e);
|
||||
return *this;
|
||||
}
|
||||
|
||||
#endif /* !NEVERCLAIMAUTOMATON_H */
|
||||
987
lbtt/src/PathEvaluator.cc
Normal file
987
lbtt/src/PathEvaluator.cc
Normal file
|
|
@ -0,0 +1,987 @@
|
|||
/*
|
||||
* Copyright (C) 1999, 2000, 2001, 2002
|
||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma implementation
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#include <config.h>
|
||||
#include <deque>
|
||||
#include <stack>
|
||||
#include <string>
|
||||
#include "PathEvaluator.h"
|
||||
|
||||
namespace Ltl
|
||||
{
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Function definitions for class PathEvaluator.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* ========================================================================= */
|
||||
void PathEvaluator::reset()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Prepares the formula evaluator for a new computation.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
current_formula = static_cast<const LtlFormula*>(0);
|
||||
current_path = static_cast<const StateSpace*>(0);
|
||||
current_loop_state = 0;
|
||||
path_states.clear();
|
||||
|
||||
for (map<const LtlFormula*, BitArray*, LtlFormula::ptr_less,
|
||||
ALLOC(BitArray*) >::iterator it
|
||||
= eval_info.begin();
|
||||
it != eval_info.end();
|
||||
++it)
|
||||
delete it->second;
|
||||
|
||||
eval_info.clear();
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
bool PathEvaluator::evaluate
|
||||
(const LtlFormula& formula, const StateSpace& statespace,
|
||||
const vector<StateSpace::size_type, ALLOC(StateSpace::size_type) >&
|
||||
states_on_path,
|
||||
StateSpace::size_type loop_state)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* 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 from which the path is
|
||||
* extracted.
|
||||
* states_on_path -- Mapping between states in the path and
|
||||
* the states in `statespace' such that
|
||||
* `statespace[states_on_path[i]]'
|
||||
* corresponds to the ith state of the path.
|
||||
* loop_state -- Number of the state in the path to which
|
||||
* the ``last'' state of the path is
|
||||
* connected.
|
||||
*
|
||||
* Returns: `true' if and only if the LTL formula holds in the path.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
reset();
|
||||
|
||||
if (states_on_path.empty() || loop_state >= states_on_path.size())
|
||||
return false;
|
||||
|
||||
current_formula = &formula;
|
||||
current_path = &statespace;
|
||||
current_loop_state = loop_state;
|
||||
path_states = states_on_path;
|
||||
|
||||
return eval();
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
bool PathEvaluator::evaluate
|
||||
(const LtlFormula& formula, const StateSpace& statespace)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Evaluates an LTL formula in a state space in which the states
|
||||
* are connected into a non-branching sequence that ends in a
|
||||
* loop.
|
||||
*
|
||||
* Arguments: formula -- Formula to be evaluated.
|
||||
* statespace -- State space in which the formula should be
|
||||
* evaluated.
|
||||
*
|
||||
* Returns: `true' if and only if the LTL formula holds in the path.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
reset();
|
||||
|
||||
if (statespace.empty())
|
||||
return false;
|
||||
|
||||
current_formula = &formula;
|
||||
current_path = &statespace;
|
||||
|
||||
map<StateSpace::size_type, StateSpace::size_type,
|
||||
less<StateSpace::size_type>, ALLOC(StateSpace::size_type) > ordering;
|
||||
|
||||
StateSpace::size_type state = statespace.initialState();
|
||||
StateSpace::size_type state_count = 0;
|
||||
|
||||
/*
|
||||
* Construct a vector of state identifiers representing the path by
|
||||
* traversing the state space until some state is encountered twice.
|
||||
*/
|
||||
|
||||
while (1)
|
||||
{
|
||||
path_states.push_back(state);
|
||||
ordering[state] = state_count;
|
||||
state_count++;
|
||||
|
||||
if (statespace[state].edges().empty())
|
||||
throw Exception
|
||||
("PathEvaluator::compute: not a total transition relation");
|
||||
|
||||
state = (*(statespace[state].edges().begin()))->targetNode();
|
||||
|
||||
if (ordering.find(state) != ordering.end())
|
||||
break;
|
||||
}
|
||||
|
||||
current_loop_state = ordering[state];
|
||||
|
||||
return eval();
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
bool PathEvaluator::eval()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Implements the model checking algorithm for paths.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: `true' if and only if `this->current_formula' holds in
|
||||
* the path described by the contents of `this->path_states'.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
stack<const LtlFormula*, deque<const LtlFormula*,
|
||||
ALLOC(const LtlFormula*) > >
|
||||
subformula_stack;
|
||||
|
||||
const LtlFormula* f;
|
||||
BitArray* val;
|
||||
|
||||
current_formula->collectSubformulae(subformula_stack);
|
||||
|
||||
try
|
||||
{
|
||||
while (!subformula_stack.empty())
|
||||
{
|
||||
if (::user_break)
|
||||
throw UserBreakException();
|
||||
|
||||
/*
|
||||
* Pop a formula from the subformula stack.
|
||||
*/
|
||||
|
||||
f = subformula_stack.top();
|
||||
subformula_stack.pop();
|
||||
|
||||
/*
|
||||
* Discard the current formula if its truth value is already known.
|
||||
*/
|
||||
|
||||
if (eval_info.find(f) != eval_info.end())
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Otherwise allocate space for the evaluation results of the current
|
||||
* formula and then evaluate it in all states of the path, using the
|
||||
* truth values of its subformulae which have already been computed.
|
||||
*/
|
||||
|
||||
val = eval_info[f] = new BitArray(path_states.size());
|
||||
val->clear(path_states.size());
|
||||
|
||||
switch (f->what())
|
||||
{
|
||||
case LTL_UNTIL :
|
||||
case LTL_FINALLY :
|
||||
case LTL_V :
|
||||
case LTL_GLOBALLY :
|
||||
case LTL_BEFORE :
|
||||
{
|
||||
StateSpace::size_type marker_state;
|
||||
const LtlFormula* g, *h;
|
||||
bool lfp, check_value_1, check_value_2, marker_valid = false;
|
||||
|
||||
switch (f->what())
|
||||
{
|
||||
case LTL_UNTIL :
|
||||
g = static_cast<const Until*>(f)->subformula1;
|
||||
h = static_cast<const Until*>(f)->subformula2;
|
||||
check_value_1 = check_value_2 = true;
|
||||
lfp = true;
|
||||
break;
|
||||
|
||||
case LTL_FINALLY :
|
||||
g = 0;
|
||||
h = static_cast<const Finally*>(f)->subformula;
|
||||
check_value_1 = check_value_2 = true;
|
||||
lfp = true;
|
||||
break;
|
||||
|
||||
case LTL_V :
|
||||
val->set(path_states.size());
|
||||
g = static_cast<const V*>(f)->subformula1;
|
||||
h = static_cast<const V*>(f)->subformula2;
|
||||
check_value_1 = check_value_2 = false;
|
||||
lfp = false;
|
||||
break;
|
||||
|
||||
case LTL_GLOBALLY :
|
||||
val->set(path_states.size());
|
||||
g = 0;
|
||||
h = static_cast<const Globally*>(f)->subformula;
|
||||
check_value_1 = check_value_2 = false;
|
||||
lfp = false;
|
||||
break;
|
||||
|
||||
default : /* LTL_BEFORE */
|
||||
val->set(path_states.size());
|
||||
g = static_cast<const Before*>(f)->subformula1;
|
||||
h = static_cast<const Before*>(f)->subformula2;
|
||||
check_value_1 = false;
|
||||
check_value_2 = true;
|
||||
lfp = false;
|
||||
break;
|
||||
}
|
||||
|
||||
for (StateSpace::size_type state = 0; state < path_states.size();
|
||||
state++)
|
||||
{
|
||||
if (eval_info[h]->test(state) == check_value_2)
|
||||
{
|
||||
val->flipBit(state);
|
||||
|
||||
if (marker_valid)
|
||||
{
|
||||
while (marker_state < state)
|
||||
{
|
||||
val->flipBit(marker_state);
|
||||
marker_state++;
|
||||
}
|
||||
marker_valid = false;
|
||||
}
|
||||
}
|
||||
else if (g == 0 || eval_info[g]->test(state) == check_value_1)
|
||||
{
|
||||
if (!marker_valid)
|
||||
{
|
||||
marker_valid = true;
|
||||
marker_state = state;
|
||||
}
|
||||
}
|
||||
else
|
||||
marker_valid = false;
|
||||
}
|
||||
|
||||
if (marker_valid && eval_info[f]->test(current_loop_state) == lfp)
|
||||
{
|
||||
while (marker_state < path_states.size())
|
||||
{
|
||||
val->flipBit(marker_state);
|
||||
marker_state++;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case LTL_WEAK_UNTIL :
|
||||
case LTL_STRONG_RELEASE :
|
||||
{
|
||||
StateSpace::size_type marker_state;
|
||||
const LtlFormula* g, *h;
|
||||
bool check_value;
|
||||
bool marker_valid = false;
|
||||
|
||||
if (f->what() == LTL_WEAK_UNTIL)
|
||||
{
|
||||
val->set(path_states.size());
|
||||
h = static_cast<const WeakUntil*>(f)->subformula1;
|
||||
g = static_cast<const WeakUntil*>(f)->subformula2;
|
||||
check_value = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
h = static_cast<const StrongRelease*>(f)->subformula1;
|
||||
g = static_cast<const StrongRelease*>(f)->subformula2;
|
||||
check_value = true;
|
||||
}
|
||||
|
||||
for (StateSpace::size_type state = 0; state < path_states.size();
|
||||
state++)
|
||||
{
|
||||
if (eval_info[g]->test(state) == check_value
|
||||
&& eval_info[h]->test(state) == check_value)
|
||||
{
|
||||
val->flipBit(state);
|
||||
|
||||
if (marker_valid)
|
||||
{
|
||||
while (marker_state < state)
|
||||
{
|
||||
val->flipBit(marker_state);
|
||||
marker_state++;
|
||||
}
|
||||
marker_valid = false;
|
||||
}
|
||||
}
|
||||
else if (eval_info[g]->test(state) == check_value)
|
||||
{
|
||||
if (!marker_valid)
|
||||
{
|
||||
marker_valid = true;
|
||||
marker_state = state;
|
||||
}
|
||||
}
|
||||
else
|
||||
marker_valid = false;
|
||||
}
|
||||
|
||||
if (marker_valid
|
||||
&& eval_info[f]->test(current_loop_state) == check_value)
|
||||
{
|
||||
while (marker_state < path_states.size())
|
||||
{
|
||||
val->flipBit(marker_state);
|
||||
marker_state++;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case LTL_TRUE :
|
||||
val->set(path_states.size());
|
||||
break;
|
||||
|
||||
case LTL_FALSE :
|
||||
break;
|
||||
|
||||
case LTL_ATOM :
|
||||
{
|
||||
for (StateSpace::size_type s = 0; s < path_states.size(); s++)
|
||||
{
|
||||
/*
|
||||
* Note: BitArray operations cannot be used directly, since the
|
||||
* width of the array in `current_path' might be less than the
|
||||
* atomic proposition identifier.
|
||||
*/
|
||||
|
||||
if (f->evaluate((*current_path)[path_states[s]].positiveAtoms(),
|
||||
current_path->numberOfPropositions()))
|
||||
val->setBit(s);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case LTL_NEGATION :
|
||||
{
|
||||
const LtlFormula* g = static_cast<const Not*>(f)->subformula;
|
||||
|
||||
for (StateSpace::size_type s = 0; s < path_states.size(); s++)
|
||||
{
|
||||
if (!eval_info[g]->test(s))
|
||||
val->setBit(s);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case LTL_CONJUNCTION :
|
||||
{
|
||||
const LtlFormula* g = static_cast<const And*>(f)->subformula1;
|
||||
const LtlFormula* h = static_cast<const And*>(f)->subformula2;
|
||||
|
||||
for (StateSpace::size_type s = 0; s < path_states.size(); s++)
|
||||
{
|
||||
if (eval_info[g]->test(s) && eval_info[h]->test(s))
|
||||
val->setBit(s);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case LTL_DISJUNCTION :
|
||||
{
|
||||
const LtlFormula* g = static_cast<const Or*>(f)->subformula1;
|
||||
const LtlFormula* h = static_cast<const Or*>(f)->subformula2;
|
||||
|
||||
for (StateSpace::size_type s = 0; s < path_states.size(); s++)
|
||||
{
|
||||
if (eval_info[g]->test(s) || eval_info[h]->test(s))
|
||||
val->setBit(s);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case LTL_IMPLICATION :
|
||||
{
|
||||
const LtlFormula* g = static_cast<const Imply*>(f)->subformula1;
|
||||
const LtlFormula* h = static_cast<const Imply*>(f)->subformula2;
|
||||
|
||||
for (StateSpace::size_type s = 0; s < path_states.size(); s++)
|
||||
{
|
||||
if (!eval_info[g]->test(s) || eval_info[h]->test(s))
|
||||
val->setBit(s);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case LTL_EQUIVALENCE :
|
||||
{
|
||||
const LtlFormula* g = static_cast<const Equiv*>(f)->subformula1;
|
||||
const LtlFormula* h = static_cast<const Equiv*>(f)->subformula2;
|
||||
|
||||
for (StateSpace::size_type s = 0; s < path_states.size(); s++)
|
||||
{
|
||||
if (eval_info[g]->test(s) == eval_info[h]->test(s))
|
||||
val->setBit(s);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case LTL_XOR :
|
||||
{
|
||||
const LtlFormula* g = static_cast<const Xor*>(f)->subformula1;
|
||||
const LtlFormula* h = static_cast<const Xor*>(f)->subformula2;
|
||||
|
||||
for (StateSpace::size_type s = 0; s < path_states.size(); s++)
|
||||
{
|
||||
if (eval_info[g]->test(s) != eval_info[h]->test(s))
|
||||
val->setBit(s);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default : /* LTL_NEXT */
|
||||
{
|
||||
const LtlFormula* g = static_cast<const Next*>(f)->subformula;
|
||||
StateSpace::size_type s;
|
||||
|
||||
for (s = 0; (s + 1) < path_states.size(); s++)
|
||||
{
|
||||
if (eval_info[g]->test(s + 1))
|
||||
val->setBit(s);
|
||||
}
|
||||
|
||||
if (eval_info[g]->test(current_loop_state))
|
||||
val->setBit(s);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
reset();
|
||||
throw;
|
||||
}
|
||||
|
||||
return eval_info[current_formula]->test(0);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
bool PathEvaluator::getResult(StateSpace::size_type state) const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Returns the model checking result in the path that begins at
|
||||
* the `state'th state of the path described by the vector
|
||||
* `this->path_states'.
|
||||
*
|
||||
* Arguments: state -- Index of a state in the path.
|
||||
*
|
||||
* Returns: `true' if and only if the LTL formula `this->current_formula'
|
||||
* holds in the path that begins at the given index.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
if (eval_info.empty())
|
||||
return false;
|
||||
|
||||
return eval_info.find(current_formula)->second->test(state);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
void PathEvaluator::print(ostream& stream, const int indent) const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Displays a proof or a refutation for the formula
|
||||
* `this->current_formula' in the state space described by the
|
||||
* contents of `this->path_states'.
|
||||
*
|
||||
* Arguments: stream -- A reference to an output stream.
|
||||
* indent -- Number of spaces to leave on the left of output.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
if (eval_info.empty())
|
||||
return;
|
||||
|
||||
Exceptional_ostream estream(&stream, ios::failbit | ios::badbit);
|
||||
|
||||
recPrint(estream, indent, current_formula, 0);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
void PathEvaluator::recPrint
|
||||
(Exceptional_ostream& estream, const int indent, const LtlFormula* f,
|
||||
StateSpace::size_type state) const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Displays a recursive proof or a refutation for the formula
|
||||
* `f' in the `state'th state of the state space described by
|
||||
* the contents of `this->path_states'.
|
||||
*
|
||||
* Arguments: estream -- A reference to an exception-aware output
|
||||
* stream.
|
||||
* indent -- Number of spaces to leave to the left of output.
|
||||
* state -- Index of a state in the path.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
static string line_prefix = "";
|
||||
|
||||
const bool prove_true = eval_info.find(f)->second->test(state);
|
||||
|
||||
estream << string(indent, ' ')
|
||||
+ (line_prefix.size() == 0
|
||||
? ""
|
||||
: line_prefix.substr(0, line_prefix.size() - 4) + "+-> ")
|
||||
+ "M,<s"
|
||||
<< path_states[state]
|
||||
<< string(", ...> |") + (prove_true ? '=' : '/') + "= "
|
||||
<< *f;
|
||||
|
||||
switch (f->what())
|
||||
{
|
||||
case LTL_ATOM :
|
||||
case LTL_TRUE :
|
||||
case LTL_FALSE :
|
||||
estream << '\n';
|
||||
return;
|
||||
|
||||
case LTL_NEGATION :
|
||||
/*
|
||||
* To display a proof (refutation) for a negated formula, display a
|
||||
* refutation (proof) for the non-negated formula.
|
||||
*/
|
||||
|
||||
line_prefix += " ";
|
||||
|
||||
estream << " :\n";
|
||||
recPrint(estream, indent, static_cast<const Not*>(f)->subformula, state);
|
||||
|
||||
break;
|
||||
|
||||
case LTL_NEXT :
|
||||
{
|
||||
/*
|
||||
* To display a proof or refutation for a Next formula, display a
|
||||
* proof or refutation for the subformula of the Next operator in
|
||||
* the next state of the path.
|
||||
*/
|
||||
|
||||
estream << " :\n" + string(indent, ' ') + line_prefix + "+-> s"
|
||||
<< path_states[state]
|
||||
<< " --> s";
|
||||
|
||||
state++;
|
||||
if (state == path_states.size())
|
||||
state = current_loop_state;
|
||||
|
||||
estream << path_states[state] << '\n';
|
||||
|
||||
line_prefix += " ";
|
||||
|
||||
recPrint(estream, indent, static_cast<const Next*>(f)->subformula,
|
||||
state);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case LTL_CONJUNCTION : case LTL_DISJUNCTION : case LTL_IMPLICATION :
|
||||
case LTL_EQUIVALENCE : case LTL_XOR :
|
||||
{
|
||||
/*
|
||||
* Formula: f1 OP f2
|
||||
*
|
||||
* proof/refutation OP what will be shown
|
||||
* ------------------------------------------------------------------
|
||||
* proof /\ proofs for `f1' and `f2'
|
||||
*
|
||||
* refutation /\ refutation for `f1' or `f2'
|
||||
*
|
||||
* proof \/ proof for `f1' or `f2'
|
||||
*
|
||||
* refutation \/ refutation for `f1 and `f2'
|
||||
*
|
||||
* proof -> proof for `f2' or refutation for
|
||||
* `f1'
|
||||
*
|
||||
* refutation -> proof for `f1' and refutation for
|
||||
* `f2'
|
||||
*
|
||||
* proof <-> proofs or refutations for both
|
||||
* `f1' and `f2'
|
||||
*
|
||||
* refutation <-> proof for `f1' and refutation for
|
||||
* `f2' or vice versa
|
||||
*
|
||||
* proof xor proof for `f1' and refutation for
|
||||
* `f2' or vice versa
|
||||
*
|
||||
* refutation xor proofs or refutations for both
|
||||
* `f1' and `f2'
|
||||
*/
|
||||
|
||||
estream << " :\n";
|
||||
|
||||
line_prefix += "| ";
|
||||
|
||||
const LtlFormula* f1, *f2;
|
||||
bool branch, val1, val2;
|
||||
|
||||
switch (f->what())
|
||||
{
|
||||
case LTL_CONJUNCTION :
|
||||
f1 = static_cast<const And*>(f)->subformula1;
|
||||
f2 = static_cast<const And*>(f)->subformula2;
|
||||
branch = prove_true;
|
||||
val1 = val2 = false;
|
||||
break;
|
||||
|
||||
case LTL_DISJUNCTION :
|
||||
f1 = static_cast<const Or*>(f)->subformula1;
|
||||
f2 = static_cast<const Or*>(f)->subformula2;
|
||||
branch = !prove_true;
|
||||
val1 = val2 = true;
|
||||
break;
|
||||
|
||||
case LTL_IMPLICATION :
|
||||
f1 = static_cast<const Imply*>(f)->subformula1;
|
||||
f2 = static_cast<const Imply*>(f)->subformula2;
|
||||
branch = !prove_true;
|
||||
val1 = false;
|
||||
val2 = true;
|
||||
break;
|
||||
|
||||
case LTL_EQUIVALENCE :
|
||||
f1 = static_cast<const Equiv*>(f)->subformula1;
|
||||
f2 = static_cast<const Equiv*>(f)->subformula2;
|
||||
branch = true;
|
||||
break;
|
||||
|
||||
default : /* LTL_XOR */
|
||||
f1 = static_cast<const Xor*>(f)->subformula1;
|
||||
f2 = static_cast<const Xor*>(f)->subformula2;
|
||||
branch = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (branch)
|
||||
{
|
||||
recPrint(estream, indent, f1, state);
|
||||
line_prefix[line_prefix.size() - 4] = ' ';
|
||||
recPrint(estream, indent, f2, state);
|
||||
}
|
||||
else
|
||||
{
|
||||
line_prefix[line_prefix.size() - 4] = ' ';
|
||||
|
||||
if (eval_info.find(f2)->second->test(state) != val2)
|
||||
recPrint(estream, indent, f1, state);
|
||||
else if (eval_info.find(f1)->second->test(state) != val1)
|
||||
recPrint(estream, indent, f2, state);
|
||||
else if ((f1->propositional() && !f2->propositional())
|
||||
|| (f1->constant() && !f2->constant()))
|
||||
recPrint(estream, indent, f1, state);
|
||||
else if ((f2->propositional() && !f1->propositional())
|
||||
|| (f2->constant() && !f1->constant()))
|
||||
recPrint(estream, indent, f2, state);
|
||||
else if (f1->size() <= f2->size())
|
||||
recPrint(estream, indent, f1, state);
|
||||
else
|
||||
recPrint(estream, indent, f2, state);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default : /* LTL_UNTIL || LTL_FINALLY || LTL_V || LTL_GLOBALLY
|
||||
|| LTL_BEFORE || LTL_WEAK_UNTIL || LTL_STRONG_RELEASE */
|
||||
{
|
||||
/*
|
||||
* Formula: f1 OP f2
|
||||
*
|
||||
* proof/refutation OP what will be shown
|
||||
* ------------------------------------------------------------------
|
||||
* proof U proofs for `f1' until finding a
|
||||
* state in which `f2' holds;
|
||||
* then show a proof for `f2'
|
||||
*
|
||||
* refutation U refutations for `f2' until
|
||||
* finding a state in which `f1'
|
||||
* does not hold OR until some
|
||||
* state is visited twice (in
|
||||
* which case `f2' never holds in
|
||||
* the path); if the search ends
|
||||
* in a state where `f1' does not
|
||||
* hold, show a refutation for
|
||||
* `f1' and `f2' in the state
|
||||
*
|
||||
* proof <> proof for `f2' in the first state
|
||||
* in which `f2' holds
|
||||
*
|
||||
* refutation <> refutation for `f2' in all states
|
||||
* of the path
|
||||
*
|
||||
* proof V proofs for `f2' until finding a
|
||||
* state in which `f1' holds OR
|
||||
* until some state is visited
|
||||
* twice (in which case `f2'
|
||||
* always holds in the path); if
|
||||
* the search ends in a state
|
||||
* where `f1' holds, show a proof
|
||||
* for `f1' and `f2' in the state
|
||||
*
|
||||
* refutation V refutations for `f1' until
|
||||
* finding a state in which `f2'
|
||||
* does not hold; then show a
|
||||
* refutation for `f2'
|
||||
*
|
||||
* proof [] proof for `f2' in all states of
|
||||
* the path
|
||||
*
|
||||
* refutation [] refutation for `f2' in the first
|
||||
* state in which `f2' does not
|
||||
* hold
|
||||
*
|
||||
* proof W proofs for `f1' until finding a
|
||||
* state in which `f2' holds or
|
||||
* until some state is visited
|
||||
* twice (in which case `f1'
|
||||
* always holds in the path);
|
||||
* if the search ends in a state
|
||||
* in which `f2' holds, show a
|
||||
* proof for `f2'
|
||||
*
|
||||
* refutation W refutations for `f2' until
|
||||
* finding a state in which
|
||||
* neither `f1' and `f2' hold;
|
||||
* then show a refutation for
|
||||
* `f1' and `f2'
|
||||
*
|
||||
* proof M proofs for `f2' until finding a
|
||||
* state in which both `f1' and
|
||||
* `f2' hold; then show a proof
|
||||
* for `f1' and `f2'
|
||||
*
|
||||
* refutation M refutations for `f1' until
|
||||
* finding a state in which `f2'
|
||||
* does not hold or until some
|
||||
* state is visited twice (in
|
||||
* which case `f1' never holds in
|
||||
* the path); if the search ends
|
||||
* in a state in which `f2' does
|
||||
* not hold, show a refutation
|
||||
* for `f2'
|
||||
*
|
||||
* proof B refutations for `f2' until
|
||||
* finding a state in which `f1'
|
||||
* holds OR until some state is
|
||||
* visited twice (in which case
|
||||
* `f2' never holds in the path);
|
||||
* if the search ends in a state
|
||||
* where `f1' holds, show a proof
|
||||
* for `f1' and a refutation for
|
||||
* `f2' in the state
|
||||
*
|
||||
* refutation B refutations for `f1' until
|
||||
* finding a state in which `f2'
|
||||
* holds; then show a proof for
|
||||
* `f2'
|
||||
*
|
||||
*/
|
||||
|
||||
estream << " :\n";
|
||||
|
||||
line_prefix += "| ";
|
||||
|
||||
const LtlFormula* f1;
|
||||
const LtlFormula* f2;
|
||||
bool eventuality, check_value_1, check_value_2;
|
||||
|
||||
switch (f->what())
|
||||
{
|
||||
case LTL_UNTIL :
|
||||
f1 = static_cast<const Until*>(f)->subformula1;
|
||||
f2 = static_cast<const Until*>(f)->subformula2;
|
||||
eventuality = true;
|
||||
check_value_1 = check_value_2 = true;
|
||||
break;
|
||||
|
||||
case LTL_FINALLY :
|
||||
f1 = 0;
|
||||
f2 = static_cast<const Finally*>(f)->subformula;
|
||||
eventuality = true;
|
||||
check_value_1 = check_value_2 = true;
|
||||
break;
|
||||
|
||||
case LTL_V :
|
||||
f1 = static_cast<const V*>(f)->subformula1;
|
||||
f2 = static_cast<const V*>(f)->subformula2;
|
||||
eventuality = false;
|
||||
check_value_1 = check_value_2 = false;
|
||||
break;
|
||||
|
||||
case LTL_GLOBALLY :
|
||||
f1 = 0;
|
||||
f2 = static_cast<const Globally*>(f)->subformula;
|
||||
eventuality = false;
|
||||
check_value_1 = check_value_2 = false;
|
||||
break;
|
||||
|
||||
case LTL_BEFORE :
|
||||
f1 = static_cast<const Before*>(f)->subformula1;
|
||||
f2 = static_cast<const Before*>(f)->subformula2;
|
||||
eventuality = false;
|
||||
check_value_1 = false;
|
||||
check_value_2 = true;
|
||||
break;
|
||||
|
||||
case LTL_WEAK_UNTIL : /* note the order of `f1' and `f2' */
|
||||
f1 = static_cast<const WeakUntil*>(f)->subformula2;
|
||||
f2 = static_cast<const WeakUntil*>(f)->subformula1;
|
||||
eventuality = false;
|
||||
check_value_1 = check_value_2 = false;
|
||||
break;
|
||||
|
||||
default : /* LTL_STRONG_RELEASE; note the order of `f1' and `f2' */
|
||||
f1 = static_cast<const StrongRelease*>(f)->subformula2;
|
||||
f2 = static_cast<const StrongRelease*>(f)->subformula1;
|
||||
eventuality = true;
|
||||
check_value_1 = check_value_2 = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (prove_true == eventuality)
|
||||
{
|
||||
while (eval_info.find(f2)->second->test(state) != check_value_2)
|
||||
{
|
||||
if (f1 != 0)
|
||||
recPrint(estream, indent, f1, state);
|
||||
|
||||
estream << string(indent, ' ')
|
||||
+ line_prefix.substr(0, line_prefix.size() - 4)
|
||||
+ "+-> s"
|
||||
<< path_states[state]
|
||||
<< " --> s";
|
||||
|
||||
state++;
|
||||
if (state == path_states.size())
|
||||
state = current_loop_state;
|
||||
|
||||
estream << path_states[state] << '\n';
|
||||
}
|
||||
|
||||
if (f->what() == LTL_WEAK_UNTIL || f->what() == LTL_STRONG_RELEASE)
|
||||
{
|
||||
recPrint(estream, indent, f2, state);
|
||||
line_prefix[line_prefix.size() - 4] = ' ';
|
||||
recPrint(estream, indent, f1, state);
|
||||
}
|
||||
else
|
||||
{
|
||||
line_prefix[line_prefix.size() - 4] = ' ';
|
||||
recPrint(estream, indent, f2, state);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
StateSpace::size_type start_state = state;
|
||||
|
||||
while (f1 == 0
|
||||
|| eval_info.find(f1)->second->test(state) == check_value_1)
|
||||
{
|
||||
recPrint(estream, indent, f2, state);
|
||||
|
||||
estream << string(indent, ' ')
|
||||
+ line_prefix.substr(0, line_prefix.size() - 4)
|
||||
+ "+-> s"
|
||||
<< path_states[state]
|
||||
<< " --> s";
|
||||
|
||||
state++;
|
||||
if (state == path_states.size())
|
||||
{
|
||||
state = current_loop_state;
|
||||
if (start_state < current_loop_state)
|
||||
{
|
||||
estream << path_states[state] << '\n';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
estream << path_states[state] << '\n';
|
||||
|
||||
if (state == start_state)
|
||||
break;
|
||||
}
|
||||
|
||||
if (f1 != 0
|
||||
&& eval_info.find(f1)->second->test(state) != check_value_1)
|
||||
{
|
||||
if (f->what() == LTL_WEAK_UNTIL || f->what() == LTL_STRONG_RELEASE)
|
||||
{
|
||||
line_prefix[line_prefix.size() - 4] = ' ';
|
||||
recPrint(estream, indent, f1, state);
|
||||
}
|
||||
else
|
||||
{
|
||||
recPrint(estream, indent, f1, state);
|
||||
line_prefix[line_prefix.size() - 4] = ' ';
|
||||
recPrint(estream, indent, f2, state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
line_prefix.resize(line_prefix.size() - 4);
|
||||
}
|
||||
|
||||
}
|
||||
169
lbtt/src/PathEvaluator.h
Normal file
169
lbtt/src/PathEvaluator.h
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
/*
|
||||
* Copyright (C) 1999, 2000, 2001, 2002
|
||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef PATHEVALUATOR_H
|
||||
#define PATHEVALUATOR_H
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma interface
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include "Alloc.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& statespace, /* state space. */
|
||||
const vector<StateSpace::size_type,
|
||||
ALLOC(StateSpace::size_type) >&
|
||||
states_on_path,
|
||||
StateSpace::size_type loop_state);
|
||||
|
||||
bool evaluate /* Same as above. */
|
||||
(const LtlFormula& formula,
|
||||
const StateSpace& statespace);
|
||||
|
||||
bool getResult(StateSpace::size_type state) /* Returns the result of */
|
||||
const; /* the evaluation in a
|
||||
* given state of the
|
||||
* current path after a
|
||||
* call to `evaluate'.
|
||||
*/
|
||||
|
||||
void print /* Displays the results */
|
||||
(ostream& stream = cout, /* after a call to */
|
||||
const int indent = 0) const; /* `evaluate'. */
|
||||
|
||||
private:
|
||||
PathEvaluator(const PathEvaluator&); /* Prevent copying and */
|
||||
PathEvaluator& operator=(const PathEvaluator&); /* assignment of
|
||||
* PathEvaluator
|
||||
* objects.
|
||||
*/
|
||||
|
||||
bool eval(); /* Evaluates a formula
|
||||
* on a path.
|
||||
*/
|
||||
|
||||
void recPrint /* Recursively prints */
|
||||
(Exceptional_ostream& estream, /* a proof or a */
|
||||
const int indent, /* refutation for a */
|
||||
const LtlFormula* f, /* formula. */
|
||||
StateSpace::size_type state) const;
|
||||
|
||||
const LtlFormula* current_formula; /* LTL formula associated
|
||||
* with the path evaluator.
|
||||
*/
|
||||
|
||||
const StateSpace* current_path; /* State space associated
|
||||
* with the path evaluator.
|
||||
*/
|
||||
|
||||
StateSpace::size_type current_loop_state; /* Number of the target
|
||||
* state of the loop on
|
||||
* the current path.
|
||||
*/
|
||||
|
||||
vector<StateSpace::size_type, /* Correspondence */
|
||||
ALLOC(StateSpace::size_type) > /* between states of the */
|
||||
path_states; /* path and the states
|
||||
* of the current state
|
||||
* space.
|
||||
*/
|
||||
|
||||
map<const LtlFormula*, BitArray*, /* Information about the */
|
||||
LtlFormula::ptr_less, ALLOC(BitArray*) > /* truth values of the */
|
||||
eval_info; /* subformulae of the
|
||||
* formula to be
|
||||
* evaluated.
|
||||
*/
|
||||
};
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Inline function definitions for class PathEvaluator.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* ========================================================================= */
|
||||
inline PathEvaluator::PathEvaluator() :
|
||||
current_formula(static_cast<const LtlFormula*>(0)),
|
||||
current_path(static_cast<const StateSpace*>(0)),
|
||||
current_loop_state(0)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Constructor for class PathEvaluator.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline PathEvaluator::~PathEvaluator()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Destructor for class PathEvaluator.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif /* !PATHEVALUATOR_H */
|
||||
202
lbtt/src/PathIterator.cc
Normal file
202
lbtt/src/PathIterator.cc
Normal file
|
|
@ -0,0 +1,202 @@
|
|||
/*
|
||||
* Copyright (C) 1999, 2000, 2001, 2002
|
||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma implementation
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#include <config.h>
|
||||
#include "BitArray.h"
|
||||
#include "PathIterator.h"
|
||||
|
||||
namespace Graph
|
||||
{
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Function definitions for class PathIterator.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* ========================================================================= */
|
||||
PathIterator::PathIterator
|
||||
(unsigned long int propositions_per_state,
|
||||
StateSpace::size_type number_of_states) :
|
||||
path(propositions_per_state, number_of_states), loop_target_state(0)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Constructor for class PathIterator. Creates a new object for
|
||||
* enumerating all paths with a given number of states and
|
||||
* atomic propositions.
|
||||
*
|
||||
* Arguments: propositions_per_state -- Number of atomic propositions
|
||||
* per a state in the path.
|
||||
* number_of_states -- Number of states in the path.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
StateSpace::size_type state;
|
||||
|
||||
for (state = 0; (state + 1) < number_of_states; state++)
|
||||
path.connect(state, state + 1);
|
||||
|
||||
path.connect(state, 0);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
bool PathIterator::operator==(const PathIterator& it) const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Equivalence operator for class PathIterator. Two
|
||||
* PathIterators are equivalent if and only if all of the
|
||||
* following conditions hold:
|
||||
* (1) Both iterators point to paths of equal size with the
|
||||
* same number of atomic propositions in each state.
|
||||
* (2) Starting from the initial states of the paths pointed
|
||||
* to by the individual iterators, the paths agree on
|
||||
* the truth values of the atomic propositions in the
|
||||
* corresponding states of the paths.
|
||||
* (3) Both paths contain a cycle of an equal length.
|
||||
*
|
||||
* Argument: it -- A constant reference to a PathIterator.
|
||||
*
|
||||
* Returns: A truth value according to the result of the test.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
if (loop_target_state != it.loop_target_state
|
||||
|| path.size() != it.path.size()
|
||||
|| path.numberOfPropositions() != it.path.numberOfPropositions())
|
||||
return false;
|
||||
|
||||
StateSpace::size_type state;
|
||||
|
||||
for (state = 0;
|
||||
state < path.size()
|
||||
&& path[state].positiveAtoms().equal(it.path[state].positiveAtoms(),
|
||||
path.numberOfPropositions());
|
||||
state++)
|
||||
;
|
||||
|
||||
return (state == path.size());
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
bool PathIterator::operator!=(const PathIterator& it) const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Inequivalence operator for class PathIterator. See above for
|
||||
* the definition of equivalence between two PathIterators; two
|
||||
* PathIterators are inequal if and only if they are not equal.
|
||||
*
|
||||
* Argument: it -- A constant reference to a PathIterator.
|
||||
*
|
||||
* Returns: A truth value according to the result of the test.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
if (loop_target_state != it.loop_target_state
|
||||
|| path.size() != it.path.size()
|
||||
|| path.numberOfPropositions() != it.path.numberOfPropositions())
|
||||
return true;
|
||||
|
||||
StateSpace::size_type state;
|
||||
|
||||
for (state = 0;
|
||||
state < path.size()
|
||||
&& path[state].positiveAtoms().equal(it.path[state].positiveAtoms(),
|
||||
path.numberOfPropositions());
|
||||
state++)
|
||||
;
|
||||
|
||||
return (state != path.size());
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
void PathIterator::computeNextPath()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Updates the path pointed to by the PathIterator to the
|
||||
* `next' path in the sequence. The sequence is constructed by
|
||||
* identifying the sequence as a binary integer (obtained by
|
||||
* concatenating the truth valuations for the atomic
|
||||
* propositions in each state) which is then incremented. If
|
||||
* there is an overflow, the `loop state' is changed until it
|
||||
* exceeds the length of the path.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
if (atEnd())
|
||||
return;
|
||||
|
||||
StateSpace::size_type state;
|
||||
const unsigned long int number_of_propositions(path.numberOfPropositions());
|
||||
|
||||
/*
|
||||
* Find the first state in the current path where some proposition has the
|
||||
* value `false'. Change the truth value of all propositions to `false'
|
||||
* in all states preceding this state.
|
||||
*/
|
||||
|
||||
for (state = 0;
|
||||
state < path.size()
|
||||
&& path[state].positiveAtoms().count(number_of_propositions)
|
||||
== number_of_propositions;
|
||||
state++)
|
||||
path[state].positiveAtoms().clear(number_of_propositions);
|
||||
|
||||
if (state == path.size())
|
||||
{
|
||||
/*
|
||||
* If the path did not contain a state in which some proposition had the
|
||||
* value `false', update the `loop state' in the path.
|
||||
*/
|
||||
|
||||
path.disconnect(path.size() - 1, loop_target_state);
|
||||
|
||||
loop_target_state++;
|
||||
|
||||
if (loop_target_state < path.size())
|
||||
path.connect(path.size() - 1, loop_target_state);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* In other case, change the truth value of the proposition to `true' in
|
||||
* the state and reset the truth values of all propositions with smaller
|
||||
* identifiers to `false'.
|
||||
*/
|
||||
|
||||
BitArray& truth_assignment = path[state].positiveAtoms();
|
||||
unsigned long int proposition;
|
||||
|
||||
for (proposition = 0; truth_assignment[proposition]; proposition++)
|
||||
truth_assignment.clearBit(proposition);
|
||||
|
||||
truth_assignment.setBit(proposition);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
208
lbtt/src/PathIterator.h
Normal file
208
lbtt/src/PathIterator.h
Normal file
|
|
@ -0,0 +1,208 @@
|
|||
/*
|
||||
* Copyright (C) 1999, 2000, 2001, 2002
|
||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef PATHITERATOR_H
|
||||
#define PATHITERATOR_H
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma interface
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#include <config.h>
|
||||
#include "StateSpace.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace Graph
|
||||
{
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* An iterator class for systematically enumerating all state spaces consisting
|
||||
* of a single infinite path (a prefix and a loop) with a given number of
|
||||
* states and a given number of atomic propositions in each state.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
class PathIterator
|
||||
{
|
||||
public:
|
||||
PathIterator /* Constructor. */
|
||||
(unsigned long int propositions_per_state,
|
||||
StateSpace::size_type number_of_states);
|
||||
|
||||
/* default copy constructor */
|
||||
|
||||
~PathIterator(); /* Destructor. */
|
||||
|
||||
/* default assignment operator */
|
||||
|
||||
bool operator==(const PathIterator& it) /* Equivalence operator. */
|
||||
const;
|
||||
|
||||
bool operator!=(const PathIterator& it) /* Inequivalence operator.
|
||||
*/
|
||||
const;
|
||||
|
||||
const StateSpace& operator*() const; /* Dereferencing */
|
||||
const StateSpace* operator->() const; /* operators. */
|
||||
|
||||
const StateSpace& operator++(); /* Increment operators. */
|
||||
const StateSpace operator++(int);
|
||||
|
||||
bool atEnd() const; /* Tells whether the
|
||||
* iterator has enumerated
|
||||
* all the state spaces in
|
||||
* the range determined by
|
||||
* the parameters with
|
||||
* which the iterator was
|
||||
* initialized.
|
||||
*/
|
||||
|
||||
private:
|
||||
void computeNextPath(); /* Updates the state space
|
||||
* currently pointed to by
|
||||
* the iterator.
|
||||
*/
|
||||
|
||||
StateSpace path; /* The state space (the
|
||||
* path) currently pointed
|
||||
* to by the iterator.
|
||||
*/
|
||||
|
||||
StateSpace::size_type loop_target_state; /* Identifier of the target
|
||||
* state of the last state
|
||||
* in the path.
|
||||
*/
|
||||
};
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Inline function definitions for class PathIterator.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* ========================================================================= */
|
||||
inline PathIterator::~PathIterator()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Destructor for class PathIterator.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline const StateSpace& PathIterator::operator*() const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Dereferencing operator for class PathIterator. Gives access
|
||||
* to the state space currently pointed to by the iterator.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: A constant reference to the state space currently pointed to
|
||||
* by the iterator.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return path;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline const StateSpace* PathIterator::operator->() const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Dereferencing operator for class PathIterator. Gives access
|
||||
* to the state space currently pointed to by the iterator.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: A pointer to a constant state space currently pointed to by
|
||||
* the iterator.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return &path;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline const StateSpace& PathIterator::operator++()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Prefix increment operator for class PathIterator. Computes
|
||||
* the next path in the graph sequence and returns a constant
|
||||
* reference to it.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: A constant reference to the updated state space pointer to by
|
||||
* the iterator.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
computeNextPath();
|
||||
return path;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline const StateSpace PathIterator::operator++(int)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Postfix increment operator for class PathIterator. Computes
|
||||
* the next path in the graph sequence and returns the graph
|
||||
* pointed to by the iterator after this operation.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: A constant reference to the state space pointed to by the
|
||||
* iterator before computing the next path in the sequence.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
StateSpace old_path(path);
|
||||
computeNextPath();
|
||||
return old_path;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline bool PathIterator::atEnd() const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Tells whether all possible paths have been enumerated by the
|
||||
* iterator.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: A truth value according to the result of the test.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return (loop_target_state == path.size());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif /* !PATHITERATOR_H */
|
||||
1061
lbtt/src/ProductAutomaton.cc
Normal file
1061
lbtt/src/ProductAutomaton.cc
Normal file
File diff suppressed because it is too large
Load diff
600
lbtt/src/ProductAutomaton.h
Normal file
600
lbtt/src/ProductAutomaton.h
Normal file
|
|
@ -0,0 +1,600 @@
|
|||
/*
|
||||
* Copyright (C) 1999, 2000, 2001, 2002
|
||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef PRODUCTAUTOMATON_H
|
||||
#define PRODUCTAUTOMATON_H
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma interface
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#include <config.h>
|
||||
#include <deque>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include "Alloc.h"
|
||||
#include "BitArray.h"
|
||||
#include "BuchiAutomaton.h"
|
||||
#include "EdgeContainer.h"
|
||||
#include "Exception.h"
|
||||
#include "Graph.h"
|
||||
#include "StateSpace.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
extern bool user_break;
|
||||
|
||||
namespace UserCommands
|
||||
{
|
||||
extern void printAutomatonAnalysisResults
|
||||
(ostream&, int, unsigned long int, unsigned long int);
|
||||
}
|
||||
|
||||
namespace Graph
|
||||
{
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* A class for representing the synchronous product of a Büchi automaton and
|
||||
* a state space.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
class ProductAutomaton : public Graph<GraphEdgeContainer>
|
||||
{
|
||||
private:
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
class ProductState : /* A class for */
|
||||
public Graph<GraphEdgeContainer>::Node /* representing the */
|
||||
{ /* states of the product
|
||||
* automaton.
|
||||
*/
|
||||
public:
|
||||
explicit ProductState /* Constructor. */
|
||||
(const size_type hash_val = 0);
|
||||
|
||||
~ProductState(); /* Destructor. */
|
||||
|
||||
/* `edges' inherited from Graph<GraphEdgeContainer>::Node */
|
||||
|
||||
size_type hashValue() const; /* Get or set the hash */
|
||||
size_type& hashValue(); /* value for the product
|
||||
* state (this value can
|
||||
* be used to extract
|
||||
* the identifiers of
|
||||
* the original state
|
||||
* space and the Büchi
|
||||
* automaton with which
|
||||
* the product state is
|
||||
* associated).
|
||||
*/
|
||||
|
||||
void print /* Writes information */
|
||||
(ostream& stream = cout, /* about the product */
|
||||
const int indent = 0, /* state to a stream. */
|
||||
const GraphOutputFormat fmt = NORMAL) const;
|
||||
|
||||
private:
|
||||
friend class ProductAutomaton;
|
||||
|
||||
ProductState(const ProductState&); /* Prevent copying and */
|
||||
ProductState& operator=(const ProductState&); /* assignment of
|
||||
* ProductState objects.
|
||||
*/
|
||||
|
||||
size_type hash_value; /* Hash value for the
|
||||
* product state (can be
|
||||
* used to extract the
|
||||
* identifiers of the
|
||||
* original state space and
|
||||
* the Büchi automaton with
|
||||
* which the product state
|
||||
* is associated).
|
||||
*/
|
||||
|
||||
Edge* incoming_edge; /* The unique edge pointing
|
||||
* to `this' ProductState.
|
||||
*/
|
||||
};
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
class ProductScc : /* A class for storing */
|
||||
public vector<ProductAutomaton::size_type, /* maximal strongly */
|
||||
ALLOC(ProductAutomaton::size_type) > /* connected components */
|
||||
{ /* of the product.
|
||||
*/
|
||||
public:
|
||||
ProductScc(); /* Constructor. */
|
||||
|
||||
/* default copy constructor */
|
||||
|
||||
~ProductScc(); /* Destructor. */
|
||||
|
||||
/* default assignment operator */
|
||||
|
||||
bool fair /* Tests whether the */
|
||||
(const ProductAutomaton& product_automaton) /* component is fair, */
|
||||
const; /* i.e. it is a
|
||||
* nontrivial component
|
||||
* with a state from
|
||||
* each acceptance set
|
||||
* of the Büchi
|
||||
* automaton used for
|
||||
* constructing a
|
||||
* given product.
|
||||
*/
|
||||
|
||||
void insert /* Inserts a state into */
|
||||
(const ProductAutomaton::size_type /* the container. */
|
||||
product_state);
|
||||
};
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
public:
|
||||
class ProductSizeException; /* An exception class for
|
||||
* reporting the situation
|
||||
* where the size of the
|
||||
* product automaton may
|
||||
* be too big.
|
||||
*/
|
||||
|
||||
friend class ProductScc;
|
||||
friend void UserCommands::printAutomatonAnalysisResults
|
||||
(ostream&, int, unsigned long int, unsigned long int);
|
||||
|
||||
ProductAutomaton(); /* Constructor. */
|
||||
|
||||
~ProductAutomaton(); /* Destructor. */
|
||||
|
||||
ProductState& operator[](const size_type index) /* Indexing operator. No */
|
||||
const; /* range check is performed
|
||||
* on the argument.
|
||||
*/
|
||||
|
||||
ProductState& node(const size_type index) const; /* Synonym for the indexing
|
||||
* operator. This function
|
||||
* also checks the range of
|
||||
* the argument.
|
||||
*/
|
||||
|
||||
/* `size' inherited from Graph<GraphEdgeContainer> */
|
||||
|
||||
/* `empty' inherited from Graph<GraphEdgeContainer> */
|
||||
|
||||
void clear(); /* Makes the automaton
|
||||
* empty.
|
||||
*/
|
||||
|
||||
void connect /* Connects two states */
|
||||
(const size_type father, /* of the product */
|
||||
const size_type child); /* automaton. */
|
||||
|
||||
void disconnect /* Disconnects two */
|
||||
(const size_type father, /* states of the product */
|
||||
const size_type child); /* automaton. */
|
||||
|
||||
/* `connected' inherited from Graph<GraphEdgeContainer> */
|
||||
|
||||
/* `stats' inherited from Graph<GraphEdgeContainer> */
|
||||
|
||||
/* `subgraphStats' inherited from Graph<GraphEdgeContainer> */
|
||||
|
||||
void computeProduct /* Function for */
|
||||
(const BuchiAutomaton& automaton, /* initializing the */
|
||||
const StateSpace& statespace, /* product automaton. */
|
||||
const bool global_product);
|
||||
|
||||
StateSpace::size_type systemState /* Returns the */
|
||||
(const size_type state) const; /* identifier of the
|
||||
* state of the original
|
||||
* state space with
|
||||
* which a given product
|
||||
* state is associated.
|
||||
*/
|
||||
|
||||
BuchiAutomaton::size_type buchiState /* Returns the */
|
||||
(const size_type state) const; /* identifier of the
|
||||
* state of the original
|
||||
* automaton with which
|
||||
* a given product state
|
||||
* is associated.
|
||||
*/
|
||||
|
||||
void emptinessCheck(Bitset& result) const; /* Performs an emptiness
|
||||
* check on the product.
|
||||
*/
|
||||
|
||||
void findAcceptingExecution /* Extracts an accepting */
|
||||
(const StateSpace::size_type initial_state, /* execution from the */
|
||||
pair<deque<StateIdPair, ALLOC(StateIdPair) >, /* product automaton. */
|
||||
deque<StateIdPair,
|
||||
ALLOC(StateIdPair) > >&
|
||||
execution) const;
|
||||
|
||||
void print /* Writes information */
|
||||
(ostream& stream = cout, /* about the product */
|
||||
const int indent = 0, /* automaton to a */
|
||||
const GraphOutputFormat fmt = NORMAL) const; /* stream. */
|
||||
|
||||
private:
|
||||
ProductAutomaton(const ProductAutomaton&); /* Prevent copying and */
|
||||
ProductAutomaton& operator= /* assignment of */
|
||||
(const ProductAutomaton&); /* ProductAutomaton
|
||||
* objects.
|
||||
*/
|
||||
|
||||
size_type expand(size_type node_count = 1); /* Inserts states to the
|
||||
* product automaton.
|
||||
*/
|
||||
|
||||
const BuchiAutomaton* buchi_automaton; /* A pointer to the
|
||||
* Büchi automaton used for
|
||||
* constructing the
|
||||
* product.
|
||||
*/
|
||||
|
||||
StateSpace::size_type statespace_size; /* Size of the state space
|
||||
* used for constructing
|
||||
* the product automaton.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_OBSTACK_H /* Storage for product */
|
||||
ObstackAllocator store; /* states and */
|
||||
#endif /* HAVE_OBSTACK_H */ /* transitions. */
|
||||
};
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* An exception class for reporting the situation where the product may be too
|
||||
* big to compute.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
class ProductAutomaton::ProductSizeException : public Exception
|
||||
{
|
||||
public:
|
||||
ProductSizeException(); /* Constructor. */
|
||||
|
||||
/* default copy constructor */
|
||||
|
||||
~ProductSizeException() throw(); /* Destructor. */
|
||||
|
||||
ProductSizeException& /* Assignment operator. */
|
||||
operator=(const ProductSizeException& e);
|
||||
|
||||
/* `what' inherited from class Exception */
|
||||
};
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Inline function definitions for class ProductAutomaton.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* ========================================================================= */
|
||||
inline ProductAutomaton::ProductAutomaton() :
|
||||
buchi_automaton(0), statespace_size(0)
|
||||
#ifdef HAVE_OBSTACK_H
|
||||
, store()
|
||||
#endif /* HAVE_OBSTACK_H */
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Constructor for class ProductAutomaton. Initializes a
|
||||
* new object for storing the product of a Büchi automaton and a
|
||||
* state space. The product must then be explicitly initialized
|
||||
* by calling the function `computeProduct' on the object.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline ProductAutomaton::~ProductAutomaton()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Destructor for class ProductAutomaton.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline ProductAutomaton::ProductState&
|
||||
ProductAutomaton::operator[](const size_type index) const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Indexing operator for class ProductAutomaton. Can be used to
|
||||
* refer to the individual states of the product automaton. No
|
||||
* range check will be performed on the argument.
|
||||
*
|
||||
* Argument: index -- Index of a state of the product automaton.
|
||||
*
|
||||
* Returns: A reference to the product state corresponding to the index.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return static_cast<ProductState&>(*nodes[index]);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline ProductAutomaton::ProductState&
|
||||
ProductAutomaton::node(const size_type index) const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Function for referring to a single state of a
|
||||
* ProductAutomaton. This function will also check the range
|
||||
* argument.
|
||||
*
|
||||
* Argument: index -- Index of a state of the product automaton.
|
||||
*
|
||||
* Returns: A reference to the corresponding product state.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return static_cast<ProductState&>(Graph<GraphEdgeContainer>::node(index));
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline StateSpace::size_type ProductAutomaton::systemState
|
||||
(const size_type state) const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Returns the identifier of the system state with which a
|
||||
* given product state is associated. This function will perform
|
||||
* no range checks on its argument.
|
||||
*
|
||||
* Argument: state -- Identifier of a product state.
|
||||
*
|
||||
* Returns: Identifier of a state in a state space.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return operator[](state).hashValue() % statespace_size;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline StateSpace::size_type ProductAutomaton::buchiState
|
||||
(const size_type state) const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Returns the identifier of the state of the Büchi automaton
|
||||
* with which a given product state is associated. This function
|
||||
* will perform no range checks on its argument.
|
||||
*
|
||||
* Argument: state -- Identifier of a product state.
|
||||
*
|
||||
* Returns: Identifier of a state in a Büchi automaton.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return operator[](state).hashValue() / statespace_size;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Inline function definitions for class ProductAutomaton::ProductState.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* ========================================================================= */
|
||||
inline ProductAutomaton::ProductState::ProductState(const size_type hash_val) :
|
||||
Graph<GraphEdgeContainer>::Node(), hash_value(hash_val), incoming_edge(0)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Constructor for class ProductAutomaton::ProductState. Creates
|
||||
* a new object representing a synchronous product of a state of
|
||||
* a Büchi automaton with a state of a state space.
|
||||
*
|
||||
* Arguments: hash_val -- Hash value for the product state.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline ProductAutomaton::ProductState::~ProductState()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Destructor for class ProductAutomaton::ProductState.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
if (incoming_edge != 0)
|
||||
{
|
||||
#ifdef HAVE_OBSTACK_H
|
||||
incoming_edge->~Edge();
|
||||
#else
|
||||
delete incoming_edge;
|
||||
#endif /* HAVE_OBSTACK_H */
|
||||
}
|
||||
outgoing_edges.clear();
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline ProductAutomaton::size_type ProductAutomaton::ProductState::hashValue()
|
||||
const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Returns the product state's hash value by value.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: The hash value of the product state.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return hash_value;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline ProductAutomaton::size_type& ProductAutomaton::ProductState::hashValue()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Returns the product state's hash value by reference. (This
|
||||
* function can therefore be used to change the value.)
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: A reference to the hash value of the product state.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return hash_value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Inline function definitions for class ProductAutomaton::ProductScc.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* ========================================================================= */
|
||||
inline ProductAutomaton::ProductScc::ProductScc()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Constructor for class ProductAutomaton::ProductScc. Creates a
|
||||
* new container for storing a maximal strongly connected
|
||||
* component of a ProductAutomaton.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline ProductAutomaton::ProductScc::~ProductScc()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Destructor for class ProductAutomaton::ProductScc.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline void ProductAutomaton::ProductScc::insert
|
||||
(const ProductAutomaton::size_type product_state)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Inserts a new product state identifier to the container.
|
||||
*
|
||||
* Argument: product_state -- Identifier of a product state.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
push_back(product_state);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Inline function definitions for class
|
||||
* ProductAutomaton::ProductSizeException.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* ========================================================================= */
|
||||
inline ProductAutomaton::ProductSizeException::ProductSizeException() :
|
||||
Exception("product may be too large")
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Constructor for class ProductAutomaton::ProductSizeException.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline ProductAutomaton::ProductSizeException::~ProductSizeException() throw()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Destructor for class ProductAutomaton::ProductSizeException.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline ProductAutomaton::ProductSizeException&
|
||||
ProductAutomaton::ProductSizeException::operator=
|
||||
(const ProductAutomaton::ProductSizeException& e)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Assignment operator for class
|
||||
* ProductAutomaton::ProductSizeException. Assigns the value of
|
||||
* another ProductAutomaton::ProductSizeException to `this' one.
|
||||
*
|
||||
* Arguments: e -- A reference to a constant
|
||||
* ProductAutomaton::ProductSizeException.
|
||||
*
|
||||
* Returns: A reference to the object whose value was changed.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
Exception::operator=(e);
|
||||
return *this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif /* !PRODUCTAUTOMATON_H */
|
||||
96
lbtt/src/Random.h
Normal file
96
lbtt/src/Random.h
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* Copyright (C) 1999, 2000, 2001, 2002
|
||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef RANDOM_H
|
||||
#define RANDOM_H
|
||||
|
||||
#include <config.h>
|
||||
#include <cstdlib>
|
||||
|
||||
#ifdef HAVE_RAND48
|
||||
#define rand lrand48
|
||||
#define srand srand48
|
||||
static const double MAXRAND = static_cast<double>(1 << 30) * 2.0;
|
||||
#else
|
||||
static const double MAXRAND = RAND_MAX + 1.0;
|
||||
#endif /* HAVE_RAND48 */
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Functions for random number generation. If HAVE_RAND48 is defined, the
|
||||
* functions rely on the lrand48() function for generating a random integer
|
||||
* between 0 and 2^31 and srand48() for setting the seed for the random
|
||||
* number generator; otherwise, the rand() and srand() functions are used,
|
||||
* respectively.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* ========================================================================= */
|
||||
inline void SRAND(unsigned int seed)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Initializes the random number generator with a seed value.
|
||||
*
|
||||
* Argument: seed -- Seed for the random number generator.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
srand (seed);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline double DRAND()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Generates a random double.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: A random double in the half-open interval [0.0,1.0).
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return rand () / MAXRAND;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline long int LRAND(long int min, long int max)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Generates a random long integer in a given interval.
|
||||
*
|
||||
* Arguments: min, max -- Bounds for the interval.
|
||||
*
|
||||
* Returns: A random long integer in the half-open interval [min,max).
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return min + static_cast<long int>(DRAND() * (max - min));
|
||||
}
|
||||
|
||||
#ifdef HAVE_RAND48
|
||||
#undef rand
|
||||
#undef srand
|
||||
#endif /* HAVE_RAND48 */
|
||||
|
||||
#endif /* !RANDOM_H */
|
||||
752
lbtt/src/SccIterator.h
Normal file
752
lbtt/src/SccIterator.h
Normal file
|
|
@ -0,0 +1,752 @@
|
|||
/*
|
||||
* Copyright (C) 1999, 2000, 2001, 2002
|
||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef SCCITERATOR_H
|
||||
#define SCCITERATOR_H
|
||||
|
||||
#include <config.h>
|
||||
#include <deque>
|
||||
#include <set>
|
||||
#include <stack>
|
||||
#include <vector>
|
||||
#include "Alloc.h"
|
||||
#include "Graph.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace Graph
|
||||
{
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* A template iterator class for computing the maximal strongly connected
|
||||
* components of a graph represented as an object of class
|
||||
* Graph<EdgeContainer>.
|
||||
*
|
||||
* The iterator class has three template arguments:
|
||||
* class EdgeContainer -- Container class storing the edges in the
|
||||
* graph with which the iterator is associated.
|
||||
*
|
||||
* class SccContainer -- Container for storing the identifiers of the
|
||||
* nodes belonging to some maximal strongly
|
||||
* connected component. The container class
|
||||
* must be able to store elements of type
|
||||
* Graph<EdgeContainer>::size_type. The container
|
||||
* class interface must support the following
|
||||
* operations:
|
||||
*
|
||||
* Default constructor which can be called
|
||||
* without any arguments
|
||||
* Copy constructor
|
||||
* Assignment operator
|
||||
* clear()
|
||||
* [makes the container empty]
|
||||
* insert(Graph<EdgeContainer>::size_type s)
|
||||
* [inserts an element into the
|
||||
* container]
|
||||
*
|
||||
* If the container class is left unspecified,
|
||||
* it defaults to
|
||||
* set<Graph<EdgeContainer>::size_type,
|
||||
* less<Graph<EdgeContainer>::size_type>,
|
||||
* ALLOC(Graph<EdgeContainer>::size_type)>.
|
||||
*
|
||||
* class Filter -- Class for representing function objects that
|
||||
* can be used to restrict the iterator
|
||||
* dereferencing operators to return only
|
||||
* those nodes of a strongly connected component
|
||||
* which satisfy a certain condition that can be
|
||||
* tested using Filter::operator(). This function
|
||||
* has to accept a single parameter of type
|
||||
* Graph<EdgeContainer>::Node*. It must return a
|
||||
* Boolean value. The nodes for which the
|
||||
* function returns `false' will then not be
|
||||
* included in the collection of nodes returned
|
||||
* by the iterator dereferencing operators.
|
||||
*
|
||||
* If the Filter class is left unspecified, it
|
||||
* defaults to the NullSccFilter<EdgeContainer>
|
||||
* class, which does not restrict the set of
|
||||
* nodes in any way.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
template<class EdgeContainer>
|
||||
class NullSccFilter;
|
||||
|
||||
template<class EdgeContainer,
|
||||
class SccContainer
|
||||
= set<typename Graph<EdgeContainer>::size_type,
|
||||
less<typename Graph<EdgeContainer>::size_type>,
|
||||
ALLOC(typename Graph<EdgeContainer>::size_type) >,
|
||||
class Filter = NullSccFilter<EdgeContainer> >
|
||||
class SccIterator
|
||||
{
|
||||
public:
|
||||
SccIterator(const Graph<EdgeContainer>& g); /* Constructor. */
|
||||
|
||||
/* default copy constructor */
|
||||
|
||||
~SccIterator(); /* Destructor. */
|
||||
|
||||
/* default assignment operator */
|
||||
|
||||
bool operator== /* Equality test for */
|
||||
(const SccIterator<EdgeContainer, /* two iterators. */
|
||||
SccContainer,
|
||||
Filter>& it) const;
|
||||
|
||||
bool operator!= /* Inequality test for */
|
||||
(const SccIterator<EdgeContainer, /* two iterators. */
|
||||
SccContainer,
|
||||
Filter>& it) const;
|
||||
|
||||
bool operator< /* `Less than' relation */
|
||||
(const SccIterator<EdgeContainer, /* between two */
|
||||
SccContainer, /* iterators. */
|
||||
Filter>& it) const;
|
||||
|
||||
bool operator<= /* `Less than or equal' */
|
||||
(const SccIterator<EdgeContainer, /* relation between two */
|
||||
SccContainer, /* iterators. */
|
||||
Filter>& it) const;
|
||||
|
||||
bool operator> /* `Greater than' */
|
||||
(const SccIterator<EdgeContainer, /* relation between two */
|
||||
SccContainer, /* iterators. */
|
||||
Filter>& it) const;
|
||||
|
||||
bool operator>= /* `Greater than or */
|
||||
(const SccIterator<EdgeContainer, /* equal' relation */
|
||||
SccContainer, /* between two */
|
||||
Filter>& it) const; /* iterators. */
|
||||
|
||||
const SccContainer& operator*() const; /* Dereferencing */
|
||||
const SccContainer* operator->() const; /* operators. */
|
||||
|
||||
const SccContainer& operator++(); /* Prefix and postfix */
|
||||
const SccContainer operator++(int); /* increment operators. */
|
||||
|
||||
bool atEnd() const; /* Tests whether the
|
||||
* iterator has scanned
|
||||
* through all the
|
||||
* strongly connected
|
||||
* components of the
|
||||
* graph.
|
||||
*/
|
||||
|
||||
private:
|
||||
const Graph<EdgeContainer>& graph; /* Reference to the graph
|
||||
* with which the iterator
|
||||
* is associated.
|
||||
*/
|
||||
|
||||
typename Graph<EdgeContainer>::size_type /* Number of graph */
|
||||
dfs_number; /* nodes processed by
|
||||
* the iterator.
|
||||
*/
|
||||
|
||||
vector<typename Graph<EdgeContainer>::size_type, /* dfs_ordering[i] */
|
||||
ALLOC(typename Graph<EdgeContainer> /* indicates the */
|
||||
::size_type) > /* position of graph */
|
||||
dfs_ordering; /* node i in the depth-
|
||||
* first search order.
|
||||
* (If the node has not
|
||||
* yet been visited,
|
||||
* dfs_ordering[i]==0.)
|
||||
*/
|
||||
|
||||
vector<typename Graph<EdgeContainer>::size_type, /* lowlink[i] indicates */
|
||||
ALLOC(typename Graph<EdgeContainer> /* the least graph node */
|
||||
::size_type) > /* (in the depth-first */
|
||||
lowlink; /* search order) that
|
||||
* is reachable from
|
||||
* graph node i and
|
||||
* does not belong to
|
||||
* any strongly
|
||||
* connected component
|
||||
* which has already been
|
||||
* processed.
|
||||
*/
|
||||
|
||||
typedef pair<typename Graph<EdgeContainer>::size_type,
|
||||
typename EdgeContainer::const_iterator>
|
||||
NodeStackElement;
|
||||
|
||||
stack<NodeStackElement, /* Depth-first search */
|
||||
deque<NodeStackElement, /* backtracking stack. */
|
||||
ALLOC(NodeStackElement) > >
|
||||
node_stack;
|
||||
|
||||
typename Graph<EdgeContainer>::size_type /* Current graph node */
|
||||
current_node; /* the depth-first
|
||||
* search.
|
||||
*/
|
||||
|
||||
typename EdgeContainer::const_iterator edge; /* Iterator to scan
|
||||
* through the successors
|
||||
* of the current node.
|
||||
*/
|
||||
|
||||
stack<typename Graph<EdgeContainer>::size_type, /* Stack used for */
|
||||
deque<typename Graph<EdgeContainer> /* collecting the nodes */
|
||||
::size_type, /* in a strongly */
|
||||
ALLOC(typename Graph<EdgeContainer> /* connected component. */
|
||||
::size_type)
|
||||
>
|
||||
>
|
||||
scc_stack;
|
||||
|
||||
SccContainer current_scc; /* Container of nodes
|
||||
* forming the maximal
|
||||
* strongly connected
|
||||
* graph component
|
||||
* currently `pointed to'
|
||||
* by the iterator.
|
||||
*/
|
||||
|
||||
Filter cond; /* Function object for
|
||||
* filtering out a subset
|
||||
* of nodes in the
|
||||
* strongly connected
|
||||
* components.
|
||||
*/
|
||||
|
||||
void reset(); /* Initializes the
|
||||
* iterator to point to
|
||||
* the first strongly
|
||||
* connected component of
|
||||
* the graph.
|
||||
*/
|
||||
|
||||
void computeNextScc(); /* Updates the iterator to
|
||||
* point to the next
|
||||
* strongly connected
|
||||
* component.
|
||||
*/
|
||||
};
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Default test for collecting the nodes in a strongly connected component.
|
||||
* (See documentation on class SccIterator for information about the purpose
|
||||
* of the class.)
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
template<class EdgeContainer>
|
||||
class NullSccFilter
|
||||
{
|
||||
public:
|
||||
bool operator()(const typename Graph<EdgeContainer>::Node*) const;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Inline function definitions for template class
|
||||
* SccIterator<EdgeContainer, SccContainer, Filter>.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* ========================================================================= */
|
||||
template<class EdgeContainer, class SccContainer, class Filter>
|
||||
inline SccIterator<EdgeContainer, SccContainer, Filter>::SccIterator
|
||||
(const Graph<EdgeContainer>& g) :
|
||||
graph(g), dfs_ordering(graph.size()), lowlink(graph.size())
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Constructor for class
|
||||
* SccIterator<EdgeContainer, SccContainer, Filter>.
|
||||
* Initializes a new iterator for scanning the maximal strongly
|
||||
* connected components of a graph.
|
||||
*
|
||||
* Arguments: g -- The graph with which the iterator is to be associated
|
||||
* (a Graph<EdgeContainer> object).
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
reset();
|
||||
computeNextScc();
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
template<class EdgeContainer, class SccContainer, class Filter>
|
||||
inline SccIterator<EdgeContainer, SccContainer, Filter>::~SccIterator()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Destructor for class
|
||||
* SccIterator<EdgeContainer, SccContainer, Filter>.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
template<class EdgeContainer, class SccContainer, class Filter>
|
||||
inline bool SccIterator<EdgeContainer, SccContainer, Filter>::operator==
|
||||
(const SccIterator<EdgeContainer, SccContainer, Filter>& it) const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Equality test for two SccIterators. Two SccIterators are
|
||||
* `equal' if and only if both of them are associated with
|
||||
* exactly the same graph object in memory and the iterators
|
||||
* have processed the same amount of graph nodes.
|
||||
*
|
||||
* Arguments: it -- A constant reference to another SccIterator.
|
||||
*
|
||||
* Returns: A truth value according to the result of the equality test.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return (&graph == &(it.graph) && dfs_number == it.dfs_number);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
template<class EdgeContainer, class SccContainer, class Filter>
|
||||
inline bool SccIterator<EdgeContainer, SccContainer, Filter>::operator!=
|
||||
(const SccIterator<EdgeContainer, SccContainer, Filter>& it) const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Inequality test for two SccIterators. Two SccIterators are
|
||||
* not equal if and only if they are associated with different
|
||||
* graphs or they are associated with the same graph object in
|
||||
* memory but the iterators have processed a different number of
|
||||
* graph nodes.
|
||||
*
|
||||
* Arguments: it -- A constant reference to another SccIterator.
|
||||
*
|
||||
* Returns: A truth value according to the result of the inequality test.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return (&graph != &(it.graph) || dfs_number != it.dfs_number);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
template<class EdgeContainer, class SccContainer, class Filter>
|
||||
inline bool SccIterator<EdgeContainer, SccContainer, Filter>::operator<
|
||||
(const SccIterator<EdgeContainer, SccContainer, Filter>& it) const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: `Less than' relation between two SccIterators. An
|
||||
* SccIterator is `less than' another if and only if the
|
||||
* iterators relate to the same graph object in memory and
|
||||
* the first iterator has processed a smaller number of nodes
|
||||
* than the second one.
|
||||
*
|
||||
* Arguments: it -- A constant reference to another SccIterator.
|
||||
*
|
||||
* Returns: A truth value according to the result of the test.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return (&graph == &(it.graph) && dfs_number < it.dfs_number);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
template<class EdgeContainer, class SccContainer, class Filter>
|
||||
inline bool SccIterator<EdgeContainer, SccContainer, Filter>::operator<=
|
||||
(const SccIterator<EdgeContainer, SccContainer, Filter>& it) const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: `Less than or equal' relation between two SccIterators. An
|
||||
* SccIterator is `less than or equal to' another if and only
|
||||
* if the iterators relate to the same graph object in memory
|
||||
* and the first iterator has processed a number of nodes not
|
||||
* exceeding the number of nodes the second iterator has
|
||||
* processed.
|
||||
*
|
||||
* Arguments: it -- A constant reference to another SccIterator.
|
||||
*
|
||||
* Returns: A truth value according to the result of the test.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return (&graph == &(it.graph) && dfs_number <= it.dfs_number);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
template<class EdgeContainer, class SccContainer, class Filter>
|
||||
inline bool SccIterator<EdgeContainer, SccContainer, Filter>::operator>
|
||||
(const SccIterator<EdgeContainer, SccContainer, Filter>& it) const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: `Greater than' relation between two SccIterators. An
|
||||
* SccIterator is `greater than' another if and only if the
|
||||
* iterators relate to the same graph object in memory and
|
||||
* the first iterator has processed a greater number of nodes
|
||||
* than the second one.
|
||||
*
|
||||
* Arguments: it -- A constant reference to another SccIterator.
|
||||
*
|
||||
* Returns: A truth value according to the result of the test.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return (&graph == &(it.graph) && dfs_number > it.dfs_number);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
template<class EdgeContainer, class SccContainer, class Filter>
|
||||
inline bool SccIterator<EdgeContainer, SccContainer, Filter>::operator>=
|
||||
(const SccIterator<EdgeContainer, SccContainer, Filter>& it) const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: `Greater than or equal' relation between two SccIterators. An
|
||||
* SccIterator is `greater than or equal to' another if and
|
||||
* only if the iterators relate to the same graph object in
|
||||
* memory and the first iterator has processed at least as many
|
||||
* nodes as the second iterator has processed.
|
||||
*
|
||||
* Arguments: it -- A constant reference to another SccIterator.
|
||||
*
|
||||
* Returns: A truth value according to the result of the test.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return (&graph == &(it.graph) && dfs_number >= it.dfs_number);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
template<class EdgeContainer, class SccContainer, class Filter>
|
||||
inline const SccContainer&
|
||||
SccIterator<EdgeContainer, SccContainer, Filter>::operator*() const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Dereferencing operator for a SccIterator. Returns the
|
||||
* collection of nodes which belong to the maximal strongly
|
||||
* connected component that the iterator currently points to.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: A collection of nodes representing some maximal strongly
|
||||
* connected component.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return current_scc;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
template<class EdgeContainer, class SccContainer, class Filter>
|
||||
inline const SccContainer*
|
||||
SccIterator<EdgeContainer, SccContainer, Filter>::operator->() const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Dereferencing operator for a SccIterator. Returns the
|
||||
* collection of nodes which belong to the maximal strongly
|
||||
* connected component that the iterator currently points to.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: A collection of nodes representing some maximal strongly
|
||||
* connected component.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return ¤t_scc;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
template<class EdgeContainer, class SccContainer, class Filter>
|
||||
inline const SccContainer&
|
||||
SccIterator<EdgeContainer, SccContainer, Filter>::operator++()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Prefix increment operator for a SccIterator. Computes the
|
||||
* next maximal strongly connected component of the graph and
|
||||
* then returns it.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: A collection of nodes representing some maximal strongly
|
||||
* connected component.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
computeNextScc();
|
||||
return current_scc;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
template<class EdgeContainer, class SccContainer, class Filter>
|
||||
inline const SccContainer
|
||||
SccIterator<EdgeContainer, SccContainer, Filter>::operator++(int)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Postfix increment operator for a SccIterator. Effectively
|
||||
* returns the maximal strongly connected component of the graph
|
||||
* currently pointed to by the iterator and then updates the
|
||||
* iterator to point to the next strongly connected component.
|
||||
*
|
||||
* Arguments: None (the `int' is only required to distinguish this operator
|
||||
* from the prefix increment operator).
|
||||
*
|
||||
* Returns: A collection of nodes representing some maximal strongly
|
||||
* connected component.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
SccContainer old_scc = current_scc;
|
||||
computeNextScc();
|
||||
return old_scc;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
template<class EdgeContainer, class SccContainer, class Filter>
|
||||
inline bool SccIterator<EdgeContainer, SccContainer, Filter>::atEnd() const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Tells whether there are still more strongly connected
|
||||
* components in the graph for the iterator to process.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: A truth value.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return (current_node == graph.size());
|
||||
}
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Function definitions for template class
|
||||
* SccIterator<EdgeContainer, SccContainer, Filter>.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* ========================================================================= */
|
||||
template<class EdgeContainer, class SccContainer, class Filter>
|
||||
void SccIterator<EdgeContainer, SccContainer, Filter>::reset()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Initializes the iterator to point to the first maximal
|
||||
* strongly connected component of the graph with which the
|
||||
* iterator it associated.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
dfs_number = 0;
|
||||
|
||||
for (typename vector<typename Graph<EdgeContainer>::size_type,
|
||||
ALLOC(typename Graph<EdgeContainer>::size_type) >
|
||||
::iterator node = dfs_ordering.begin();
|
||||
node != dfs_ordering.end();
|
||||
++node)
|
||||
*node = 0;
|
||||
|
||||
while (!node_stack.empty())
|
||||
node_stack.pop();
|
||||
|
||||
while (!scc_stack.empty())
|
||||
scc_stack.pop();
|
||||
|
||||
current_scc.clear();
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
template<class EdgeContainer, class SccContainer, class Filter>
|
||||
void SccIterator<EdgeContainer, SccContainer, Filter>::computeNextScc()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Updates the state of the iterator to `point to' the next
|
||||
* maximal strongly connected component of the graph, using the
|
||||
* algorithm due to Tarjan [R. Tarjan. Depth-first search and
|
||||
* linear graph algorithms. SIAM Journal on Computing,
|
||||
* 1(2):146--160, June 1972] for computing the next maximal
|
||||
* strongly connected component of the graph.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
current_scc.clear();
|
||||
|
||||
if (scc_stack.empty() && node_stack.empty())
|
||||
{
|
||||
/*
|
||||
* If both `scc_stack' and `node_stack' are empty (this holds if we have
|
||||
* recently finished processing some component of the graph), try to find
|
||||
* a graph node that has not yet been visited. If no such node is found,
|
||||
* all nodes have been visited and there are no more strongly connected
|
||||
* components to be found in the graph.
|
||||
*/
|
||||
|
||||
current_node = 0;
|
||||
for (typename vector<typename Graph<EdgeContainer>::size_type,
|
||||
ALLOC(typename Graph<EdgeContainer>::size_type) >
|
||||
::const_iterator node = dfs_ordering.begin();
|
||||
node != dfs_ordering.end() && (*node) != 0;
|
||||
++node)
|
||||
++current_node;
|
||||
|
||||
if (current_node == graph.size())
|
||||
return;
|
||||
|
||||
/*
|
||||
* Prepare to continue the depth-first search in the unvisited node.
|
||||
*/
|
||||
|
||||
edge = graph[current_node].edges().begin();
|
||||
|
||||
scc_stack.push(current_node);
|
||||
++dfs_number;
|
||||
dfs_ordering[current_node] = lowlink[current_node] = dfs_number;
|
||||
}
|
||||
|
||||
typename Graph<EdgeContainer>::size_type child_node;
|
||||
|
||||
while (1)
|
||||
{
|
||||
/*
|
||||
* If there are still nodes left in the depth-first search backtracking
|
||||
* stack, pop a node and its next unprocessed outgoing edge off the stack.
|
||||
* Before continuing the depth-first search in the popped node, update
|
||||
* its lowlink value if necessary. (This has to be done if the lowlink of
|
||||
* the current node---a successor of the popped node---is less than the
|
||||
* lowlink of the popped node but not equal to zero.)
|
||||
*/
|
||||
|
||||
if (!node_stack.empty())
|
||||
{
|
||||
typename Graph<EdgeContainer>::size_type father_node
|
||||
= node_stack.top().first;
|
||||
edge = node_stack.top().second;
|
||||
node_stack.pop();
|
||||
|
||||
if (lowlink[current_node] < lowlink[father_node]
|
||||
&& lowlink[current_node] != 0)
|
||||
lowlink[father_node] = lowlink[current_node];
|
||||
|
||||
current_node = father_node;
|
||||
}
|
||||
|
||||
/*
|
||||
* Scan through the successors of the current node.
|
||||
*
|
||||
* If the current nodes has an unvisited successor node (a successor i
|
||||
* with dfs_ordering[i] == 0), push the current node and its next
|
||||
* unprocessed edge onto the backtracking stack and then continue the
|
||||
* search in the successor node. Push also the successor node onto the
|
||||
* strongly connected component stack.
|
||||
*
|
||||
* Otherwise, update the lowlink of the current node to the lowlink of
|
||||
* its already visited successor if necessary.
|
||||
*/
|
||||
|
||||
while (edge != graph[current_node].edges().end())
|
||||
{
|
||||
child_node = (*edge)->targetNode();
|
||||
++edge;
|
||||
|
||||
if (dfs_ordering[child_node] == 0)
|
||||
{
|
||||
node_stack.push(make_pair(current_node, edge));
|
||||
scc_stack.push(child_node);
|
||||
|
||||
++dfs_number;
|
||||
dfs_ordering[child_node] = lowlink[child_node] = dfs_number;
|
||||
|
||||
current_node = child_node;
|
||||
edge = graph[current_node].edges().begin();
|
||||
}
|
||||
else if (lowlink[child_node] < lowlink[current_node]
|
||||
&& lowlink[child_node] != 0)
|
||||
lowlink[current_node] = lowlink[child_node];
|
||||
}
|
||||
|
||||
/*
|
||||
* If the least node in the depth-first search order reachable from the
|
||||
* current node is the current node itself at the end of the previous
|
||||
* loop, we have found a maximal strongly connected component of the
|
||||
* graph. In this case, collect the states satisfying `cond' in the
|
||||
* strongly connected component stack to form the component and exit.
|
||||
* (Otherwise, return to the start of the outermost while loop and
|
||||
* continue by popping a state off the depth-first search backtracking
|
||||
* stack.)
|
||||
*/
|
||||
|
||||
if (dfs_ordering[current_node] == lowlink[current_node])
|
||||
{
|
||||
do
|
||||
{
|
||||
child_node = scc_stack.top();
|
||||
scc_stack.pop();
|
||||
if (cond(&graph[child_node]))
|
||||
current_scc.insert(child_node);
|
||||
lowlink[child_node] = 0;
|
||||
}
|
||||
while (child_node != current_node);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Inline function definitions for template class NullSccFilter<EdgeContainer>.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* ========================================================================= */
|
||||
template<class EdgeContainer>
|
||||
inline bool NullSccFilter<EdgeContainer>::operator()
|
||||
(const typename Graph<EdgeContainer>::Node*) const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Default test for filtering the nodes in a strongly connected
|
||||
* graph component. The default is to simply include all nodes
|
||||
* in the result.
|
||||
*
|
||||
* Arguments: A constant pointer to a Graph<EdgeContainer>::Node (required
|
||||
* only to satisfy the class interface requirements).
|
||||
*
|
||||
* Returns: true, so the test will succeed for every node in the
|
||||
* component.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif /* !SCCITERATOR_H */
|
||||
55
lbtt/src/SharedTestData.h
Normal file
55
lbtt/src/SharedTestData.h
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright (C) 1999, 2000, 2001, 2002
|
||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef SHAREDTESTDATA_H
|
||||
#define SHAREDTESTDATA_H
|
||||
|
||||
#include <vector>
|
||||
#include "Alloc.h"
|
||||
#include "Exception.h"
|
||||
#include "TestRoundInfo.h"
|
||||
#include "TestStatistics.h"
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Declarations of variables for storing test results and maintaining test
|
||||
* state information.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
namespace SharedTestData
|
||||
{
|
||||
|
||||
extern TestRoundInfo round_info; /* Data structure for
|
||||
* storing information
|
||||
* about the current test
|
||||
* round.
|
||||
*/
|
||||
|
||||
extern vector<AlgorithmTestResults, /* Test results for each */
|
||||
ALLOC(AlgorithmTestResults) > /* implementation. */
|
||||
test_results;
|
||||
|
||||
extern vector<TestStatistics, /* Overall test */
|
||||
ALLOC(TestStatistics) > /* statistics for each */
|
||||
final_statistics; /* implementation. */
|
||||
|
||||
}
|
||||
|
||||
#endif /* !SHAREDTESTDATA_H */
|
||||
123
lbtt/src/SpinWrapper.cc
Normal file
123
lbtt/src/SpinWrapper.cc
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
* Copyright (C) 1999, 2000, 2001, 2002
|
||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma implementation
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#include <config.h>
|
||||
#ifdef HAVE_SSTREAM
|
||||
#include <sstream>
|
||||
#else
|
||||
#include <strstream>
|
||||
#endif /* HAVE_SSTREAM */
|
||||
#include "Exception.h"
|
||||
#include "FormulaWriter.h"
|
||||
#include "NeverClaimAutomaton.h"
|
||||
#include "SpinWrapper.h"
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Definitions for operator symbols specific to Spin.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
const char SpinWrapper::SPIN_AND[] = "&&";
|
||||
const char SpinWrapper::SPIN_OR[] = "||";
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Function definitions for class SpinWrapper.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* ========================================================================= */
|
||||
void SpinWrapper::translateFormula
|
||||
(const ::Ltl::LtlFormula& formula, string& translated_formula)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Translates an LtlFormula into a string which contains the
|
||||
* formula in the input syntax of Spin.
|
||||
*
|
||||
* Arguments: formula -- The LtlFormula to be translated.
|
||||
* translated_formula -- A reference to a string for storing
|
||||
* the results.
|
||||
*
|
||||
* Returns: Nothing. The result of the translation can be found in
|
||||
* the string `translated_formula'.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
using namespace Ltl;
|
||||
|
||||
#ifdef HAVE_SSTREAM
|
||||
ostringstream translated_formula_stream;
|
||||
#else
|
||||
ostrstream translated_formula_stream;
|
||||
#endif /* HAVE_SSTREAM */
|
||||
Exceptional_ostream estream(&translated_formula_stream, ios::goodbit);
|
||||
|
||||
FormulaWriter<ConstantWriter<LtlTrue::infix_symbol>,
|
||||
ConstantWriter<LtlFalse::infix_symbol>,
|
||||
AtomWriter,
|
||||
UnaryOperatorWriter<LtlNegation::infix_symbol>,
|
||||
UnaryOperatorWriter<LtlNext::infix_symbol>,
|
||||
UnaryOperatorWriter<LtlFinally::infix_symbol>,
|
||||
UnaryOperatorWriter<LtlGlobally::infix_symbol>,
|
||||
BinaryOperatorInfixWriter<SPIN_AND>,
|
||||
BinaryOperatorInfixWriter<SPIN_OR>,
|
||||
BinaryOperatorInfixWriter<LtlImplication::infix_symbol>,
|
||||
BinaryOperatorInfixWriter<LtlEquivalence::infix_symbol>,
|
||||
WriterErrorReporter,
|
||||
BinaryOperatorInfixWriter<LtlUntil::infix_symbol>,
|
||||
BinaryOperatorInfixWriter<LtlV::infix_symbol>,
|
||||
WriterErrorReporter,
|
||||
WriterErrorReporter,
|
||||
WriterErrorReporter>
|
||||
fw(estream);
|
||||
|
||||
formula.traverse(fw, LTL_PREORDER | LTL_INORDER | LTL_POSTORDER);
|
||||
|
||||
translated_formula = translated_formula_stream.str();
|
||||
#ifndef HAVE_SSTREAM
|
||||
translated_formula_stream.freeze(0);
|
||||
#endif /* HAVE_SSTREAM */
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
void SpinWrapper::parseAutomaton
|
||||
(const string& input_filename, const string& output_filename)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Parses the never claim in the output returned by Spin and
|
||||
* converts it into lbtt format.
|
||||
*
|
||||
* Arguments: input_filename -- Name of the input file.
|
||||
* output_filename -- Name of the output file.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
NeverClaimAutomaton automaton;
|
||||
automaton.read(input_filename.c_str());
|
||||
automaton.write(output_filename.c_str());
|
||||
}
|
||||
126
lbtt/src/SpinWrapper.h
Normal file
126
lbtt/src/SpinWrapper.h
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
/*
|
||||
* Copyright (C) 1999, 2000, 2001, 2002
|
||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef SPINWRAPPER_H
|
||||
#define SPINWRAPPER_H
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma interface
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#include <config.h>
|
||||
#include <string>
|
||||
#include "ExternalTranslator.h"
|
||||
#include "LtlFormula.h"
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Interface class for Spin.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
class SpinWrapper : public ExternalTranslator
|
||||
{
|
||||
public:
|
||||
SpinWrapper(); /* Constructor. */
|
||||
|
||||
~SpinWrapper(); /* Destructor. */
|
||||
|
||||
void translateFormula /* Translates a formula */
|
||||
(const ::Ltl::LtlFormula& formula, /* into a Büchi */
|
||||
string& translated_formula); /* automaton. */
|
||||
|
||||
/* `formatInput' inherited from ExternalTranslator */
|
||||
|
||||
string commandLine /* Prepares the command */
|
||||
(const string& input_filename, /* line for executing */
|
||||
const string& output_filename); /* Spin. */
|
||||
|
||||
/* `execSuccess' inherited from ExternalTranslator */
|
||||
|
||||
void parseAutomaton /* Translates the output */
|
||||
(const string& input_filename, /* of the translation */
|
||||
const string& output_filename); /* algorithm into lbtt
|
||||
* format.
|
||||
*/
|
||||
|
||||
private:
|
||||
SpinWrapper(const SpinWrapper&); /* Prevent copying and */
|
||||
SpinWrapper& operator=(const SpinWrapper&); /* assignment of
|
||||
* SpinWrapper objects.
|
||||
*/
|
||||
|
||||
static const char SPIN_AND[]; /* Symbols for */
|
||||
static const char SPIN_OR[]; /* operators. */
|
||||
};
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Inline function definitions for class SpinWrapper.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* ========================================================================= */
|
||||
inline SpinWrapper::SpinWrapper()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Constructor for class SpinWrapper.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline SpinWrapper::~SpinWrapper()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Destructor for class SpinWrapper.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline string SpinWrapper::commandLine
|
||||
(const string& input_filename, const string& output_filename)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Prepares the command line for Spin.
|
||||
*
|
||||
* Arguments: input_filename -- Name of the input file.
|
||||
* output_filename -- Name of the output file.
|
||||
*
|
||||
* Returns: The command line string.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return string(" -F ") + input_filename + " >" + output_filename;
|
||||
}
|
||||
|
||||
#endif /* !SPINWRAPPER_H */
|
||||
1455
lbtt/src/StatDisplay.cc
Normal file
1455
lbtt/src/StatDisplay.cc
Normal file
File diff suppressed because it is too large
Load diff
117
lbtt/src/StatDisplay.h
Normal file
117
lbtt/src/StatDisplay.h
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
* Copyright (C) 1999, 2000, 2001, 2002
|
||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef STATDISPLAY_H
|
||||
#define STATDISPLAY_H
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma interface
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#include <config.h>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include "Alloc.h"
|
||||
#include "Configuration.h"
|
||||
#include "TestStatistics.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
extern Configuration configuration;
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Functions for displaying test statistics.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
namespace StatDisplay
|
||||
{
|
||||
|
||||
void printBuchiAutomatonStats /* Displays information */
|
||||
(ostream& stream, /* about a Büchi */
|
||||
int indent, /* automaton. */
|
||||
vector<AlgorithmTestResults,
|
||||
ALLOC(AlgorithmTestResults) >::size_type
|
||||
algorithm,
|
||||
int result_id);
|
||||
|
||||
void printProductAutomatonStats /* Displays information */
|
||||
(ostream& stream, /* about a product */
|
||||
int indent, /* automaton. */
|
||||
vector<AlgorithmTestResults,
|
||||
ALLOC(AlgorithmTestResults) >::size_type
|
||||
algorithm,
|
||||
int result_id);
|
||||
|
||||
void printAcceptanceCycleStats /* Displays information */
|
||||
(ostream& stream, /* about the acceptance */
|
||||
int indent, /* cycles of a product */
|
||||
vector<AlgorithmTestResults, /* automaton. */
|
||||
ALLOC(AlgorithmTestResults) >::size_type
|
||||
algorithm,
|
||||
int result_id);
|
||||
|
||||
void printConsistencyCheckStats /* Displays the result */
|
||||
(ostream& stream, /* of the consistency */
|
||||
int indent, /* check for a given */
|
||||
vector<AlgorithmTestResults, /* algorithm. */
|
||||
ALLOC(AlgorithmTestResults) >::size_type
|
||||
algorithm);
|
||||
|
||||
void printCrossComparisonStats /* Displays information */
|
||||
(ostream& stream, /* about the model */
|
||||
int indent, /* checking result */
|
||||
vector<AlgorithmTestResults, /* cross-comparison */
|
||||
ALLOC(AlgorithmTestResults) >::size_type /* check. */
|
||||
algorithm);
|
||||
|
||||
void printBuchiIntersectionCheckStats /* Displays the results */
|
||||
(ostream& stream, int indent, /* of the Büchi automata */
|
||||
vector<AlgorithmTestResults, /* intersection */
|
||||
ALLOC(AlgorithmTestResults) >::size_type /* emptiness checks. */
|
||||
algorithm);
|
||||
|
||||
void printAllStats /* A shorthand for */
|
||||
(ostream& stream, /* showing all the */
|
||||
int indent, /* information displayed */
|
||||
vector<TestStatistics, /* by the previous five */
|
||||
ALLOC(TestStatistics)>::size_type /* functions. */
|
||||
algorithm);
|
||||
|
||||
void printCollectiveCrossComparisonStats /* Displays a single */
|
||||
(ostream& stream, /* `cell' of the final */
|
||||
vector<TestStatistics, /* result cross- */
|
||||
ALLOC(TestStatistics) >::size_type /* comparison table. */
|
||||
algorithm_y,
|
||||
vector<TestStatistics,
|
||||
ALLOC(TestStatistics) >::size_type
|
||||
algorithm_x,
|
||||
int data_type);
|
||||
|
||||
void printCollectiveStats /* Displays average test */
|
||||
(ostream& stream, int indent); /* data over all the
|
||||
* test rounds
|
||||
* performed so far.
|
||||
*/
|
||||
}
|
||||
|
||||
#endif /* !STATDISPLAY_H */
|
||||
459
lbtt/src/StateSpace.cc
Normal file
459
lbtt/src/StateSpace.cc
Normal file
|
|
@ -0,0 +1,459 @@
|
|||
/*
|
||||
* Copyright (C) 1999, 2000, 2001, 2002
|
||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma implementation
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#include <config.h>
|
||||
#include <map>
|
||||
#include "DispUtil.h"
|
||||
#include "Exception.h"
|
||||
#include "StateSpace.h"
|
||||
#include "StringUtil.h"
|
||||
|
||||
namespace Graph
|
||||
{
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Function definitions for class StateSpace.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* ========================================================================= */
|
||||
StateSpace::StateSpace
|
||||
(const unsigned long int propositions_per_state,
|
||||
const size_type initial_number_of_states) :
|
||||
atoms_per_state(propositions_per_state), initial_state(0)
|
||||
#ifdef HAVE_OBSTACK_H
|
||||
, store()
|
||||
#endif /* HAVE_OBSTACK_H */
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Constructor for class StateSpace. Initializes a state space
|
||||
* with a given number of states and with a given number of
|
||||
* atomic propositions per state.
|
||||
*
|
||||
* Arguments: propositions_per_state -- Atomic propositions per state.
|
||||
* initial_number_of_states -- Initial size of the state space
|
||||
* (can be grown later).
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
expand(initial_number_of_states);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
StateSpace::StateSpace(const StateSpace& statespace) :
|
||||
Graph<GraphEdgeContainer>(), atoms_per_state(statespace.atoms_per_state),
|
||||
initial_state(statespace.initial_state)
|
||||
#ifdef HAVE_OBSTACK_H
|
||||
, store()
|
||||
#endif /* HAVE_OBSTACK_H */
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Copy constructor for class StateSpace. Creates a copy of a
|
||||
* StateSpace object.
|
||||
*
|
||||
* Argument: statespace -- StateSpace to be copied.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
expand(statespace.size());
|
||||
|
||||
for (size_type state = 0; state < size(); ++state)
|
||||
{
|
||||
for (GraphEdgeContainer::const_iterator transition
|
||||
= statespace[state].edges().begin();
|
||||
transition != statespace[state].edges().end();
|
||||
++transition)
|
||||
connect(state, (*transition)->targetNode());
|
||||
|
||||
operator[](state).positiveAtoms().copy(statespace[state].positiveAtoms(),
|
||||
atoms_per_state);
|
||||
}
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
StateSpace& StateSpace::operator=(const StateSpace& statespace)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Assignment operator for class StateSpace. Assigns the
|
||||
* contents of a state space to another one.
|
||||
*
|
||||
* Argument: statespace -- A reference to the constant StateSpace whose
|
||||
* contents are to be copied.
|
||||
*
|
||||
* Returns: A reference to the StateSpace assigned to.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
if (&statespace != this)
|
||||
{
|
||||
clear();
|
||||
expand(statespace.size());
|
||||
atoms_per_state = statespace.atoms_per_state;
|
||||
initial_state = statespace.initial_state;
|
||||
|
||||
for (size_type state = 0; state < size(); ++state)
|
||||
{
|
||||
for (GraphEdgeContainer::const_iterator transition
|
||||
= statespace[state].edges().begin();
|
||||
transition != statespace[state].edges().end();
|
||||
++transition)
|
||||
connect(state, (*transition)->targetNode());
|
||||
|
||||
operator[](state).positiveAtoms().copy(statespace[state].positiveAtoms(),
|
||||
atoms_per_state);
|
||||
}
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
void StateSpace::clear()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Makes the automaton empty.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
atoms_per_state = 0;
|
||||
initial_state = 0;
|
||||
|
||||
#ifdef HAVE_OBSTACK_H
|
||||
for (vector<Node*, ALLOC(Node*) >::iterator state = nodes.begin();
|
||||
state != nodes.end();
|
||||
++state)
|
||||
static_cast<State*>(*state)->~State();
|
||||
|
||||
if (!nodes.empty())
|
||||
{
|
||||
store.free(*nodes.begin());
|
||||
nodes.clear();
|
||||
nodes.reserve(0);
|
||||
}
|
||||
#endif /* HAVE_OBSTACK_H */
|
||||
|
||||
Graph<GraphEdgeContainer>::clear();
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
StateSpace::size_type StateSpace::expand(size_type node_count)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Inserts a given number of states to a StateSpace.
|
||||
*
|
||||
* Argument: node_count -- Number of states to be inserted.
|
||||
*
|
||||
* Returns: The index of the last inserted state.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
nodes.reserve(nodes.size() + node_count);
|
||||
|
||||
while (node_count > 0)
|
||||
{
|
||||
#ifdef HAVE_OBSTACK_H
|
||||
void* state_storage = store.alloc(sizeof(State));
|
||||
State* new_state = new(state_storage) State(atoms_per_state);
|
||||
#else
|
||||
State* new_state = new State(atoms_per_state);
|
||||
#endif /* HAVE_OBSTACK_H */
|
||||
|
||||
try
|
||||
{
|
||||
nodes.push_back(new_state);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
#ifdef HAVE_OBSTACK_H
|
||||
new_state->~State();
|
||||
store.free(state_storage);
|
||||
#else
|
||||
delete new_state;
|
||||
#endif /* HAVE_OBSTACK_H */
|
||||
throw;
|
||||
}
|
||||
node_count--;
|
||||
}
|
||||
|
||||
return size() - 1;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
void StateSpace::connect(const size_type father, const size_type child)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Connects two states of the state space.
|
||||
*
|
||||
* Arguments: father, child -- Identifiers of two states.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
Edge* edge = operator[](child).incoming_edge;
|
||||
|
||||
if (edge != 0)
|
||||
{
|
||||
nodes[father]->outgoing_edges.insert(edge);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef HAVE_OBSTACK_H
|
||||
void* edge_storage = store.alloc(sizeof(Edge));
|
||||
edge = new(edge_storage) Edge(child);
|
||||
#else
|
||||
edge = new Edge(child);
|
||||
#endif /* HAVE_OBSTACK_H */
|
||||
|
||||
try
|
||||
{
|
||||
nodes[father]->outgoing_edges.insert(edge);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
#ifdef HAVE_OBSTACK_H
|
||||
edge->~Edge();
|
||||
store.free(edge_storage);
|
||||
#else
|
||||
delete edge;
|
||||
#endif /* HAVE_OBSTACK_H */
|
||||
throw;
|
||||
}
|
||||
|
||||
operator[](child).incoming_edge = edge;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
void StateSpace::disconnect(const size_type father, const size_type child)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Disconnects two states of the state space.
|
||||
*
|
||||
* Arguments: father, child -- Identifiers for two states.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
Edge e(child);
|
||||
|
||||
/*
|
||||
* Scan the set of `father''s outgoing transitions for a transition to the
|
||||
* given target state and remove it if such a transition exists.
|
||||
*/
|
||||
|
||||
GraphEdgeContainer::iterator search_edge
|
||||
= nodes[father]->outgoing_edges.find(&e);
|
||||
|
||||
if (search_edge != nodes[father]->outgoing_edges.end())
|
||||
nodes[father]->outgoing_edges.erase(search_edge);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
void StateSpace::print
|
||||
(ostream& stream, const int indent, const GraphOutputFormat fmt) const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Writes information about a StateSpace to a stream.
|
||||
*
|
||||
* Arguments: stream -- A reference to an output stream.
|
||||
* indent -- Number of spaces to leave to the left of output.
|
||||
* fmt -- Determines the output format.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
Exceptional_ostream estream(&stream, ios::failbit | ios::badbit);
|
||||
|
||||
if (fmt == DOT)
|
||||
estream << string(indent, ' ') + "digraph G {\n";
|
||||
|
||||
if (nodes.empty())
|
||||
{
|
||||
if (fmt == NORMAL)
|
||||
estream << string(indent, ' ') + "The state space is empty.\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fmt == NORMAL)
|
||||
{
|
||||
pair<size_type, unsigned long int> statistics = stats();
|
||||
pair<size_type, unsigned long int> reachable_part_statistics =
|
||||
subgraphStats(initial_state);
|
||||
|
||||
estream << string(indent, ' ') + "The state space consists of\n"
|
||||
+ string(indent + 4, ' ')
|
||||
<< statistics.first
|
||||
<< " states and\n" + string(indent + 4, ' ')
|
||||
<< statistics.second
|
||||
<< " transitions.\n" + string(indent, ' ')
|
||||
+ "The reachable part of the state space contains\n"
|
||||
+ string(indent + 4, ' ')
|
||||
<< reachable_part_statistics.first
|
||||
<< " states and\n" + string(indent + 4, ' ')
|
||||
<< reachable_part_statistics.second
|
||||
<< " transitions.\n" + string(indent, ' ') + "Initial state: "
|
||||
<< initial_state << '\n';
|
||||
}
|
||||
|
||||
size_type s = nodes.size();
|
||||
for (size_type state = 0; state < s; ++state)
|
||||
{
|
||||
estream << string(indent, ' ');
|
||||
if (fmt == NORMAL)
|
||||
{
|
||||
estream << "State " << state << ":\n";
|
||||
operator[](state).print(stream, indent + 4, NORMAL, atoms_per_state);
|
||||
}
|
||||
else if (fmt == DOT)
|
||||
{
|
||||
GraphEdgeContainer::const_iterator transition;
|
||||
|
||||
estream << " n" << state << " [";
|
||||
if (state == 0)
|
||||
estream << "style=filled,";
|
||||
estream << "shape=ellipse,label=\"" << state << ": ";
|
||||
operator[](state).print(stream, 0, DOT, atoms_per_state);
|
||||
estream << "\",fontsize=12];\n";
|
||||
|
||||
for (transition = nodes[state]->edges().begin();
|
||||
transition != nodes[state]->edges().end();
|
||||
++transition)
|
||||
{
|
||||
estream << string(indent + 2, ' ') + 'n' << state;
|
||||
(*transition)->print(stream, indent, fmt);
|
||||
estream << ";\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fmt == DOT)
|
||||
estream << string(indent, ' ') + "}\n";
|
||||
|
||||
estream.flush();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Function definitions for class StateSpace::State.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* ========================================================================= */
|
||||
void StateSpace::State::print
|
||||
(ostream& stream, const int indent, const GraphOutputFormat fmt,
|
||||
const unsigned long int number_of_atoms) const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Writes information about a state of a state space.
|
||||
*
|
||||
* Arguments: stream -- A reference to an output stream.
|
||||
* indent -- Number of spaces to leave to the left of
|
||||
* output.
|
||||
* fmt -- Determines the format of output.
|
||||
* number_of_atoms -- Number of atoms associated with the
|
||||
* state.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
Exceptional_ostream estream(&stream, ios::failbit | ios::badbit);
|
||||
|
||||
if (positive_atoms.count(number_of_atoms) == 0)
|
||||
{
|
||||
if (fmt == NORMAL)
|
||||
estream << string(indent, ' ') + "No true propositions in this state.\n";
|
||||
else if (fmt == DOT)
|
||||
estream << "{}";
|
||||
}
|
||||
else
|
||||
{
|
||||
bool first_printed = false;
|
||||
|
||||
if (fmt == NORMAL)
|
||||
estream << string(indent, ' ') + "True propositions:\n";
|
||||
|
||||
string text = "{";
|
||||
|
||||
for (unsigned long int atom = 0; atom < number_of_atoms; ++atom)
|
||||
{
|
||||
if (positive_atoms[atom])
|
||||
{
|
||||
if (first_printed)
|
||||
text += ", ";
|
||||
else
|
||||
first_printed = true;
|
||||
text += 'p' + ::StringUtil::toString(atom);
|
||||
}
|
||||
}
|
||||
text += '}';
|
||||
if (fmt == NORMAL)
|
||||
::DispUtil::printTextBlock(stream, indent + 2, text, 78);
|
||||
else
|
||||
estream << text;
|
||||
}
|
||||
|
||||
if (fmt == NORMAL)
|
||||
{
|
||||
if (edges().empty())
|
||||
estream << string(indent, ' ') + "No transitions to other states.\n";
|
||||
else
|
||||
{
|
||||
bool first_printed = false;
|
||||
estream << string(indent, ' ') + "Transitions to states\n";
|
||||
|
||||
string text = "{";
|
||||
|
||||
for (GraphEdgeContainer::const_iterator edge = edges().begin();
|
||||
edge != edges().end();
|
||||
++edge)
|
||||
{
|
||||
if (first_printed)
|
||||
text += ", ";
|
||||
else
|
||||
first_printed = true;
|
||||
text += ::StringUtil::toString((*edge)->targetNode());
|
||||
}
|
||||
text += '}';
|
||||
::DispUtil::printTextBlock(stream, indent + 2, text, 78);
|
||||
}
|
||||
}
|
||||
|
||||
estream.flush();
|
||||
}
|
||||
|
||||
}
|
||||
454
lbtt/src/StateSpace.h
Normal file
454
lbtt/src/StateSpace.h
Normal file
|
|
@ -0,0 +1,454 @@
|
|||
/*
|
||||
* Copyright (C) 1999, 2000, 2001, 2002
|
||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef STATESPACE_H
|
||||
#define STATESPACE_H
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma interface
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#include <config.h>
|
||||
#include "Alloc.h"
|
||||
#include "BitArray.h"
|
||||
#include "EdgeContainer.h"
|
||||
#include "Graph.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
extern bool user_break;
|
||||
|
||||
namespace Graph
|
||||
{
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* A class for representing state spaces.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
class StateSpace : public Graph<GraphEdgeContainer>
|
||||
{
|
||||
private:
|
||||
unsigned long int atoms_per_state; /* Number of propositional
|
||||
* variables per state in
|
||||
* the state space.
|
||||
*/
|
||||
|
||||
size_type initial_state; /* Index of the initial
|
||||
* state of the state
|
||||
* space.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_OBSTACK_H /* Storage for states */
|
||||
ObstackAllocator store; /* and transitions. */
|
||||
#endif /* HAVE_OBSTACK_H */
|
||||
|
||||
public:
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
class State : /* A class for */
|
||||
public Graph<GraphEdgeContainer>::Node /* representing the */
|
||||
{ /* states of the state
|
||||
* space.
|
||||
*/
|
||||
public:
|
||||
explicit State /* Constructs a state */
|
||||
(const unsigned long int /* with a false truth */
|
||||
number_of_atoms = 0); /* assignment for the
|
||||
* atomic propositions.
|
||||
*/
|
||||
|
||||
State /* Constructs a state */
|
||||
(const BitArray& atoms, /* from a given truth */
|
||||
const unsigned long int number_of_atoms); /* assignment. */
|
||||
|
||||
~State(); /* Destructor. */
|
||||
|
||||
/* `edges' inherited from Graph<GraphEdgeContainer>::Node */
|
||||
|
||||
bool holds /* Test whether a given */
|
||||
(const unsigned long int atom, /* atomic proposition */
|
||||
const unsigned long int number_of_atoms) /* holds in the state. */
|
||||
const;
|
||||
|
||||
const BitArray& positiveAtoms() const; /* Get or set the truth */
|
||||
BitArray& positiveAtoms(); /* assignment for the
|
||||
* propositional atoms in
|
||||
* a state.
|
||||
*/
|
||||
|
||||
void print /* Writes information */
|
||||
(ostream& stream, /* about the state to a */
|
||||
const int indent, /* stream. */
|
||||
const GraphOutputFormat fmt) const;
|
||||
|
||||
void print /* Writes information */
|
||||
(ostream& stream, /* about the state to a */
|
||||
const int indent, /* stream. */
|
||||
const GraphOutputFormat fmt,
|
||||
const unsigned long int number_of_atoms)
|
||||
const;
|
||||
|
||||
private:
|
||||
friend class StateSpace;
|
||||
|
||||
State(const State&); /* Prevent copying and */
|
||||
State& operator=(const State&); /* assignment of State
|
||||
* objects.
|
||||
*/
|
||||
|
||||
BitArray positive_atoms; /* The set of propositions
|
||||
* holding in the state.
|
||||
*/
|
||||
|
||||
Edge* incoming_edge; /* The unique edge pointing
|
||||
* to `this' state.
|
||||
*/
|
||||
};
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
explicit StateSpace /* Constructor. */
|
||||
(const unsigned long int
|
||||
propositions_per_state = 0,
|
||||
const size_type initial_number_of_states = 0);
|
||||
|
||||
StateSpace(const StateSpace& statespace); /* Copy constructor. */
|
||||
|
||||
~StateSpace(); /* Destructor. */
|
||||
|
||||
StateSpace& operator= /* Assignment operator. */
|
||||
(const StateSpace& statespace);
|
||||
|
||||
State& operator[](const size_type index) const; /* Indexing operator. No
|
||||
* range checks are
|
||||
* performed on the
|
||||
* argument.
|
||||
*/
|
||||
|
||||
State& node(const size_type index) const; /* Synonym for the indexing
|
||||
* operator. This function
|
||||
* will also check the
|
||||
* range of its argument.
|
||||
*/
|
||||
|
||||
/* `size' inherited from Graph<GraphEdgeContainer> */
|
||||
|
||||
/* `empty' inherited from Graph<GraphEdgeContainer> */
|
||||
|
||||
void clear(); /* Makes the state space
|
||||
* empty.
|
||||
*/
|
||||
|
||||
size_type expand(size_type node_count = 1); /* Inserts states to the
|
||||
* state space.
|
||||
*/
|
||||
|
||||
void connect /* Connects two states */
|
||||
(const size_type father, /* of the state space. */
|
||||
const size_type child);
|
||||
|
||||
void disconnect /* Disconnects two */
|
||||
(const size_type father, /* states of the state */
|
||||
const size_type child); /* space. */
|
||||
|
||||
/* `connected' inherited from Graph<GraphEdgeContainer> */
|
||||
|
||||
/* `stats' inherited from Graph<GraphEdgeContainer> */
|
||||
|
||||
/* `subgraphStats' inherited from Graph<GraphEdgeContainer> */
|
||||
|
||||
unsigned long int numberOfPropositions() const; /* Get the number of atomic
|
||||
* propositions associated
|
||||
* with each state of the
|
||||
* state space.
|
||||
*/
|
||||
|
||||
size_type initialState() const; /* Get or set the */
|
||||
size_type& initialState(); /* initial state of the
|
||||
* state space.
|
||||
*/
|
||||
|
||||
void print /* Writes information */
|
||||
(ostream& stream = cout, /* about the state space */
|
||||
const int indent = 0, /* to a stream. */
|
||||
const GraphOutputFormat fmt = NORMAL) const;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Inline function definitions for class StateSpace.
|
||||
*
|
||||
*************************************************************************** */
|
||||
|
||||
/* ========================================================================= */
|
||||
inline StateSpace::~StateSpace()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Destructor for class StateSpace.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline StateSpace::State& StateSpace::operator[](const size_type index) const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Indexing operator for class StateSpace. This function can
|
||||
* be used to refer to the individual states of the state space
|
||||
* This function does not perform any range checks on its
|
||||
* argument.
|
||||
*
|
||||
* Argument: index -- Index of a state.
|
||||
*
|
||||
* Returns: A reference to a state of the state space.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return static_cast<State&>(*nodes[index]);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline StateSpace::State& StateSpace::node(const size_type index) const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Function for referring to a single state of a StateSpace.
|
||||
* This function also performs a range check on its argument.
|
||||
*
|
||||
* Argument: index -- Index of a state.
|
||||
*
|
||||
* Returns: A reference to a state of the state space.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return static_cast<State&>(Graph<GraphEdgeContainer>::node(index));
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline unsigned long int StateSpace::numberOfPropositions() const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Tells the number of atomic propositions associated with each
|
||||
* state of the state space.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Number of propositions associated with each state of the
|
||||
* state space.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return atoms_per_state;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline StateSpace::size_type StateSpace::initialState() const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Returns the number of the initial state of the StateSpace by
|
||||
* value.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Index of the initial state of the state space.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return initial_state;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline StateSpace::size_type& StateSpace::initialState()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Returns the number of the initial state of the StateSpace by
|
||||
* reference. This function can therefore be used to change the
|
||||
* initial state.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: A reference to the index of the initial state.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return initial_state;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Inline function definitions for class StateSpace::State.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* ========================================================================= */
|
||||
inline StateSpace::State::State(const unsigned long int number_of_atoms) :
|
||||
Graph<GraphEdgeContainer>::Node(), positive_atoms(number_of_atoms),
|
||||
incoming_edge(0)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Constructor for class StateSpace::State. Creates a new state
|
||||
* with a given number of atomic propositions, all of which are
|
||||
* initially false.
|
||||
*
|
||||
* Argument: number_of_atoms -- Number of atomic propositions in the
|
||||
* state.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
positive_atoms.clear(number_of_atoms);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline StateSpace::State::State
|
||||
(const BitArray& atoms, const unsigned long int number_of_atoms) :
|
||||
Graph<GraphEdgeContainer>::Node()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Constructor for class StateSpace::State. Creates a new state,
|
||||
* using a given truth assignment for propositional variables
|
||||
* for initialization.
|
||||
*
|
||||
* Argument: atoms -- A truth assignment for atomic
|
||||
* propositions.
|
||||
* number_of_atoms -- Number of atomic propositions in the
|
||||
* truth assignment.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
positive_atoms.copy(atoms, number_of_atoms);
|
||||
incoming_edge = 0;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline StateSpace::State::~State()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Destructor for class StateSpace::State.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
if (incoming_edge != 0)
|
||||
{
|
||||
#ifdef HAVE_OBSTACK_H
|
||||
incoming_edge->~Edge();
|
||||
#else
|
||||
delete incoming_edge;
|
||||
#endif /* HAVE_OBSTACK_H */
|
||||
}
|
||||
outgoing_edges.clear();
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline bool StateSpace::State::holds
|
||||
(const unsigned long int atom, const unsigned long int number_of_atoms) const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Tests whether a given proposition holds in a state.
|
||||
*
|
||||
* Arguments: atom -- Identifier of the proposition.
|
||||
* number_of_atoms -- Number of atomic propositions associated
|
||||
* with the state.
|
||||
*
|
||||
* Returns: Truth value of the proposition in the state.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
if (atom >= number_of_atoms)
|
||||
return false;
|
||||
|
||||
return positive_atoms[atom];
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline const BitArray& StateSpace::State::positiveAtoms() const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Returns the truth assignment for the propositions in a state.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: A reference to the truth assignment, represented as a
|
||||
* constant BitArray.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return positive_atoms;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline BitArray& StateSpace::State::positiveAtoms()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Returns the truth assignment for the propositions in a state.
|
||||
* This function can be also used to change the truth
|
||||
* assignment.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: A reference to the truth assignment, represented as a
|
||||
* BitArray.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return positive_atoms;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline void StateSpace::State::print
|
||||
(ostream& stream, const int indent, const GraphOutputFormat fmt) const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Writes information about a state of a state space, assuming
|
||||
* that there are no propositions associated with the state.
|
||||
* [Note: This function is used to override the `print' function
|
||||
* defined in the base class `Graph::node'.]
|
||||
*
|
||||
* Arguments: stream -- A reference to an output stream.
|
||||
* indent -- Number of spaces to leave to the left of output.
|
||||
* fmt -- Determines the format of output.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
this->print(stream, indent, fmt, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif /* !STATESPACE_H */
|
||||
291
lbtt/src/StateSpaceRandomizer.cc
Normal file
291
lbtt/src/StateSpaceRandomizer.cc
Normal file
|
|
@ -0,0 +1,291 @@
|
|||
/*
|
||||
* Copyright (C) 1999, 2000, 2001, 2002
|
||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma implementation
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#include <climits>
|
||||
#include <config.h>
|
||||
#include <map>
|
||||
#include "Alloc.h"
|
||||
#include "BitArray.h"
|
||||
#include "Exception.h"
|
||||
#include "StateSpaceRandomizer.h"
|
||||
|
||||
namespace Graph
|
||||
{
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Function definitions for class StateSpaceRandomizer.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* ========================================================================= */
|
||||
void StateSpaceRandomizer::reset()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: (Re)initializes the StateSpaceRandomizer object with default
|
||||
* state space generation parameters.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
min_size = max_size = 20;
|
||||
atoms_per_state = 5;
|
||||
edge_probability = 0.2;
|
||||
truth_probability = 0.5;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
StateSpace* StateSpaceRandomizer::generateGraph() const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Generates a random state space with the current graph
|
||||
* generation parameters.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: A pointer to a newly allocated StateSpace object.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
StateSpace::size_type size = chooseSize();
|
||||
|
||||
StateSpace* statespace = new StateSpace(atoms_per_state, size);
|
||||
|
||||
statespace->initialState() = 0;
|
||||
|
||||
if (size > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
bool has_successor;
|
||||
|
||||
for (StateSpace::size_type i = 0; i < size; i++)
|
||||
{
|
||||
if (::user_break)
|
||||
throw UserBreakException();
|
||||
|
||||
has_successor = false;
|
||||
|
||||
for (StateSpace::size_type j = 0; j < size; j++)
|
||||
{
|
||||
if (DRAND() < edge_probability)
|
||||
{
|
||||
statespace->connect(i, j);
|
||||
has_successor = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!has_successor)
|
||||
statespace->connect(i, LRAND(0, size));
|
||||
|
||||
for (unsigned long int j = 0; j < atoms_per_state; j++)
|
||||
{
|
||||
if (DRAND() < truth_probability)
|
||||
(*statespace)[i].positiveAtoms().setBit(j);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
delete statespace;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
return statespace;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
StateSpace* StateSpaceRandomizer::generateConnectedGraph() const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Initializes a random connected state space whose each state
|
||||
* is reachable from its initial state 0.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: A pointer to a newly allocated StateSpace object.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
StateSpace::size_type size = chooseSize();
|
||||
|
||||
StateSpace* statespace = new StateSpace(atoms_per_state, size);
|
||||
|
||||
statespace->initialState() = 0;
|
||||
|
||||
if (size > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
/* Random graph generation algorithm:
|
||||
----------------------------------
|
||||
|
||||
allocate number_of_states nodes;
|
||||
|
||||
insert node 0 to the set of `reachable but unprocessed' nodes (nodes
|
||||
that are reachable from the root node but whose children have not yet
|
||||
been selected)
|
||||
|
||||
while the set of `reachable but unprocessed' nodes in nonempty
|
||||
{
|
||||
select a (random) node X from the set;
|
||||
|
||||
if there exists a node Y that is not yet reachable from root node
|
||||
{
|
||||
connect X to Y by making X the parent node of Y;
|
||||
insert Y to the set of `reachable but unprocessed' nodes;
|
||||
}
|
||||
|
||||
for each node Z (excluding node Y) in the graph
|
||||
{
|
||||
randomly connect X to Z (making X the parent of Z);
|
||||
|
||||
if Z was not previously reachable from the root node
|
||||
insert Z to the set of `reachable but unprocessed' nodes;
|
||||
}
|
||||
|
||||
remove X from the set of `reachable but unprocessed' nodes;
|
||||
}
|
||||
|
||||
In the following implementation, the random truth value allocation
|
||||
for propositions that hold in a state is interleaved with the
|
||||
previous algorithm.
|
||||
*/
|
||||
|
||||
StateSpace::size_type first_unreachable_state = 1, random_node;
|
||||
|
||||
multimap<long int, StateSpace::size_type, less<long int>,
|
||||
ALLOC(StateSpace::size_type) >
|
||||
reachable_but_unprocessed;
|
||||
|
||||
reachable_but_unprocessed.insert(make_pair(0, 0));
|
||||
|
||||
while (!reachable_but_unprocessed.empty())
|
||||
{
|
||||
if (::user_break)
|
||||
throw UserBreakException();
|
||||
|
||||
random_node = (*(reachable_but_unprocessed.begin())).second;
|
||||
reachable_but_unprocessed.erase(reachable_but_unprocessed.begin());
|
||||
|
||||
for (StateSpace::size_type n = 0; n < first_unreachable_state; ++n)
|
||||
{
|
||||
if (DRAND() < edge_probability)
|
||||
statespace->connect(random_node, n);
|
||||
}
|
||||
|
||||
if (first_unreachable_state < size)
|
||||
{
|
||||
statespace->connect(random_node, first_unreachable_state);
|
||||
reachable_but_unprocessed.insert(make_pair(LRAND(0, LONG_MAX),
|
||||
first_unreachable_state));
|
||||
++first_unreachable_state;
|
||||
|
||||
for (StateSpace::size_type i = first_unreachable_state; i < size;
|
||||
++i)
|
||||
{
|
||||
if (DRAND() < edge_probability)
|
||||
{
|
||||
statespace->connect(random_node, first_unreachable_state);
|
||||
reachable_but_unprocessed.insert
|
||||
(make_pair(LRAND(0, LONG_MAX), first_unreachable_state));
|
||||
++first_unreachable_state;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((*statespace)[random_node].edges().empty())
|
||||
statespace->connect(random_node, random_node);
|
||||
|
||||
BitArray& atoms = (*statespace)[random_node].positiveAtoms();
|
||||
for (unsigned long int i = 0; i < atoms_per_state; ++i)
|
||||
{
|
||||
if (DRAND() < truth_probability)
|
||||
atoms.setBit(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
delete statespace;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
return statespace;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
StateSpace* StateSpaceRandomizer::generatePath() const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Generates a random Kripke structure that consists of a finite
|
||||
* prefix of states that ends in a loop. The initial state of
|
||||
* the generated structure will be at index 0.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: A pointer to a newly allocated StateSpace object.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
StateSpace::size_type size = chooseSize();
|
||||
|
||||
StateSpace* statespace = new StateSpace(atoms_per_state, size);
|
||||
|
||||
statespace->initialState() = 0;
|
||||
|
||||
if (size > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
for (StateSpace::size_type i = 0; i + 1 < size; i++)
|
||||
{
|
||||
if (::user_break)
|
||||
throw UserBreakException();
|
||||
|
||||
statespace->connect(i, i + 1);
|
||||
for (unsigned long int j = 0; j < atoms_per_state; j++)
|
||||
{
|
||||
if (DRAND() < truth_probability)
|
||||
(*statespace)[i].positiveAtoms().setBit(j);
|
||||
}
|
||||
}
|
||||
|
||||
statespace->connect(size - 1, LRAND(0, size));
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
delete statespace;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
return statespace;
|
||||
}
|
||||
|
||||
}
|
||||
158
lbtt/src/StateSpaceRandomizer.h
Normal file
158
lbtt/src/StateSpaceRandomizer.h
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
/*
|
||||
* Copyright (C) 1999, 2000, 2001, 2002
|
||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef STATESPACERANDOMIZER_H
|
||||
#define STATESPACERANDOMIZER_H
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma interface
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#include <config.h>
|
||||
#include "Random.h"
|
||||
#include "StateSpace.h"
|
||||
|
||||
namespace Graph
|
||||
{
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* A class for generating random state spaces.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
class StateSpaceRandomizer
|
||||
{
|
||||
public:
|
||||
StateSpaceRandomizer(); /* Constructor. */
|
||||
|
||||
~StateSpaceRandomizer(); /* Destructor. */
|
||||
|
||||
StateSpace* generateGraph() const; /* Generates a random
|
||||
* state space.
|
||||
*/
|
||||
|
||||
StateSpace* generateConnectedGraph() const; /* Generates a random
|
||||
* state space whose all
|
||||
* states are reachable
|
||||
* from its initial state.
|
||||
*/
|
||||
|
||||
StateSpace* generatePath() const; /* Generates a random path.
|
||||
*/
|
||||
|
||||
void reset(); /* (Re)initializes the
|
||||
* object with default
|
||||
* state space generation
|
||||
* parameters.
|
||||
*/
|
||||
|
||||
StateSpace::size_type min_size; /* Minimum size for the
|
||||
* generated state spaces.
|
||||
*/
|
||||
|
||||
StateSpace::size_type max_size; /* Maximum size for the
|
||||
* generated state spaces.
|
||||
*/
|
||||
|
||||
unsigned long int atoms_per_state; /* Number of atomic
|
||||
* propositions associated
|
||||
* with each state of the
|
||||
* generated state spaces.
|
||||
*/
|
||||
|
||||
double edge_probability; /* Probability for adding
|
||||
* random edges between
|
||||
* state space states.
|
||||
*/
|
||||
|
||||
double truth_probability; /* Probability of assigning
|
||||
* the value `true' for a
|
||||
* proposition in a state.
|
||||
*/
|
||||
|
||||
private:
|
||||
StateSpace::size_type chooseSize() const; /* Chooses a size for a
|
||||
* state space to be
|
||||
* generated.
|
||||
*/
|
||||
|
||||
StateSpaceRandomizer /* Prevent copying and */
|
||||
(const StateSpaceRandomizer&); /* assignment of */
|
||||
StateSpaceRandomizer& operator= /* StateSpaceRandomizer */
|
||||
(const StateSpaceRandomizer&); /* objects. */
|
||||
};
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Inline function definitions for class StateSpaceRandomizer.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* ========================================================================= */
|
||||
inline StateSpaceRandomizer::StateSpaceRandomizer()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Constructor for class StateSpaceRandomizer. Initializes a new
|
||||
* StateSpaceRandomizer object with default parameters.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline StateSpaceRandomizer::~StateSpaceRandomizer()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Destructor for class StateSpaceRandomizer.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline StateSpace::size_type StateSpaceRandomizer::chooseSize() const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Chooses a random size for a state space to be generated.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: A random integer in the interval
|
||||
* [this->min_size, this->max_size].
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return (min_size + LRAND(0, max_size - min_size + 1));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif /* STATESPACERANDOMIZER_H */
|
||||
227
lbtt/src/StringUtil.cc
Normal file
227
lbtt/src/StringUtil.cc
Normal file
|
|
@ -0,0 +1,227 @@
|
|||
/*
|
||||
* Copyright (C) 1999, 2000, 2001, 2002
|
||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma implementation
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#include <config.h>
|
||||
#include <cstdlib>
|
||||
#include "StringUtil.h"
|
||||
|
||||
namespace StringUtil
|
||||
{
|
||||
|
||||
/* ========================================================================= */
|
||||
string toString(const double d, const int precision, const ios::fmtflags flags)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Converts a double to a string with a given precision and
|
||||
* format. The function defaults to fixed-point format with a
|
||||
* precision of two decimals.
|
||||
*
|
||||
* Arguments: d -- The double to be converted.
|
||||
* precision -- Precision.
|
||||
* flags -- Formatting flags.
|
||||
*
|
||||
* Returns: The double as a string.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
#ifdef HAVE_SSTREAM
|
||||
ostringstream stream;
|
||||
stream.precision(precision);
|
||||
stream.flags(flags);
|
||||
stream << d;
|
||||
return stream.str();
|
||||
#else
|
||||
ostrstream stream;
|
||||
stream.precision(precision);
|
||||
stream.flags(flags);
|
||||
stream << d << ends;
|
||||
string result(stream.str());
|
||||
stream.freeze(0);
|
||||
return result;
|
||||
#endif /* HAVE_SSTREAM */
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
void sliceString
|
||||
(const string& s, const char* slice_chars,
|
||||
vector<string, ALLOC(string) >& slices)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Slices a string into a vector of strings, using a given set
|
||||
* of characters as separators.
|
||||
*
|
||||
* Arguments: s -- A reference to the constant original string.
|
||||
* slice_chars -- A C-style string containing the characters
|
||||
* to be used as separators.
|
||||
* slices -- A reference to a vector for storing the
|
||||
* string components.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
string::size_type last_non_slicechar_pos = 0;
|
||||
string::size_type last_slicechar_pos = 0;
|
||||
|
||||
slices.clear();
|
||||
|
||||
do
|
||||
{
|
||||
last_non_slicechar_pos =
|
||||
s.find_first_not_of(slice_chars, last_slicechar_pos);
|
||||
if (last_non_slicechar_pos != s.npos)
|
||||
{
|
||||
last_slicechar_pos = s.find_first_of(slice_chars,
|
||||
last_non_slicechar_pos);
|
||||
if (last_slicechar_pos == s.npos)
|
||||
slices.push_back(s.substr(last_non_slicechar_pos));
|
||||
else
|
||||
slices.push_back(s.substr(last_non_slicechar_pos,
|
||||
last_slicechar_pos
|
||||
- last_non_slicechar_pos));
|
||||
}
|
||||
}
|
||||
while (last_non_slicechar_pos != s.npos && last_slicechar_pos != s.npos);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
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')
|
||||
throw NotANumberException("expected a nonnegative integer, got `"
|
||||
+ number_string + "'");
|
||||
|
||||
return number;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
void parseInterval
|
||||
(const string& token,
|
||||
set<unsigned long int, less<unsigned long int>, ALLOC(unsigned long int) >&
|
||||
number_set,
|
||||
unsigned long int min, unsigned long int max)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Parses a string for a list of number intervals, storing all
|
||||
* the numbers into a set.
|
||||
*
|
||||
* Arguments: token -- A reference to a constant string containing
|
||||
* the list of intervals. A legal list of
|
||||
* intervals has the following syntax:
|
||||
*
|
||||
* <interval_list>
|
||||
* ::= <number>
|
||||
* | '*' // all numbers in the
|
||||
* // interval
|
||||
* // [min, max]
|
||||
* | '-'<number> // all numbers in the
|
||||
* // interval
|
||||
* // [min, number]
|
||||
* | <number>'-' // all numbers in the
|
||||
* // interval
|
||||
* // [number, max]
|
||||
* | <number>'-'<number>
|
||||
* | <interval_list>','<interval_list>
|
||||
*
|
||||
* number_set -- A reference to a set of unsigned long
|
||||
* integers for storing the result.
|
||||
* min -- Minimum bound for the numbers.
|
||||
* max -- Maximum bound for the numbers.
|
||||
*
|
||||
* Note: `min' and `max' are only used to determine the limits
|
||||
* for only partially defined intervals. The check that
|
||||
* the explicitly specified values in the interval list
|
||||
* are within these bounds is left to the caller when
|
||||
* examining the result set.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
vector<string, ALLOC(string) > intervals;
|
||||
|
||||
sliceString(token, ",", intervals);
|
||||
string::size_type dash_pos;
|
||||
|
||||
number_set.clear();
|
||||
|
||||
for (vector<string, ALLOC(string) >::const_iterator
|
||||
interval = intervals.begin();
|
||||
interval != intervals.end();
|
||||
++interval)
|
||||
{
|
||||
if (*interval == "*")
|
||||
{
|
||||
for (unsigned long int i = min; i <= max; i++)
|
||||
number_set.insert(i);
|
||||
break;
|
||||
}
|
||||
|
||||
dash_pos = (*interval).find_first_of("-");
|
||||
|
||||
if (dash_pos == (*interval).npos)
|
||||
number_set.insert(parseNumber(*interval));
|
||||
else
|
||||
{
|
||||
if (dash_pos == 0)
|
||||
{
|
||||
unsigned long int number = parseNumber((*interval).substr(1));
|
||||
for (unsigned long int i = min; i <= number; i++)
|
||||
number_set.insert(i);
|
||||
}
|
||||
else if (dash_pos == (*interval).length() - 1)
|
||||
{
|
||||
unsigned long int number =
|
||||
parseNumber((*interval).substr(0, (*interval).length() - 1));
|
||||
for (unsigned long int i = number; i <= max; i++)
|
||||
number_set.insert(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned long int min_bound =
|
||||
parseNumber((*interval).substr(0, dash_pos));
|
||||
unsigned long int max_bound =
|
||||
parseNumber((*interval).substr(dash_pos + 1));
|
||||
|
||||
for (unsigned long int i = min_bound; i <= max_bound; i++)
|
||||
number_set.insert(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
198
lbtt/src/StringUtil.h
Normal file
198
lbtt/src/StringUtil.h
Normal file
|
|
@ -0,0 +1,198 @@
|
|||
/*
|
||||
* Copyright (C) 1999, 2000, 2001, 2002
|
||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef STRINGUTIL_H
|
||||
#define STRINGUTIL_H
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma interface
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#include <config.h>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#ifdef HAVE_SSTREAM
|
||||
#include <sstream>
|
||||
#else
|
||||
#include <strstream>
|
||||
#endif /* HAVE_SSTREAM */
|
||||
#include <vector>
|
||||
#include "Alloc.h"
|
||||
#include "Exception.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Miscellaneous routines extracting data from strings or converting data types
|
||||
* to strings.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
namespace StringUtil
|
||||
{
|
||||
|
||||
string toString /* Function for */
|
||||
(const double d, /* converting a double */
|
||||
const int precision = 2, /* to a string. */
|
||||
const ios::fmtflags flags = ios::fixed);
|
||||
|
||||
template<typename T> string toString(const T& t); /* Template function for
|
||||
* converting data types
|
||||
* supporting stream output
|
||||
* operations into strings.
|
||||
*/
|
||||
|
||||
void sliceString /* Breaks a string into */
|
||||
(const string& s, const char* slice_chars, /* `slices', using a */
|
||||
vector<string, ALLOC(string) >& slices); /* given set of
|
||||
* characters as
|
||||
* separators.
|
||||
*/
|
||||
|
||||
unsigned long int parseNumber /* Converts a string to */
|
||||
(const string& number_string); /* an unsigned long
|
||||
* integer.
|
||||
*/
|
||||
|
||||
void parseInterval /* Converts a string of */
|
||||
(const string& token, /* number intervals to */
|
||||
set<unsigned long int, less<unsigned long int>, /* the corresponding set */
|
||||
ALLOC(unsigned long int) >& number_set, /* of unsigned long */
|
||||
unsigned long int min, /* integers. */
|
||||
unsigned long int max);
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Template function definitions in namespace StringUtil.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* ========================================================================= */
|
||||
template<typename T>
|
||||
string toString(const T& t)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Converts any data type supporting stream output (the <<
|
||||
* operator) into a string.
|
||||
*
|
||||
* Arguments: t -- The object to be converted into a string.
|
||||
*
|
||||
* Returns: The object as a string.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
#ifdef HAVE_SSTREAM
|
||||
ostringstream stream;
|
||||
stream << t;
|
||||
return stream.str();
|
||||
#else
|
||||
ostrstream stream;
|
||||
stream << t << ends;
|
||||
string result(stream.str());
|
||||
stream.freeze(0);
|
||||
return result;
|
||||
#endif /* HAVE_SSTREAM */
|
||||
}
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* A class for reporting number conversion errors.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
class NotANumberException : public Exception
|
||||
{
|
||||
public:
|
||||
NotANumberException /* Constructor. */
|
||||
(const string& message = "not a number");
|
||||
|
||||
/* default copy constructor */
|
||||
|
||||
~NotANumberException() throw(); /* Destructor. */
|
||||
|
||||
NotANumberException& operator= /* Assignment operator. */
|
||||
(const NotANumberException& e);
|
||||
};
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif /* !STRINGUTIL_H */
|
||||
1668
lbtt/src/TestOperations.cc
Normal file
1668
lbtt/src/TestOperations.cc
Normal file
File diff suppressed because it is too large
Load diff
539
lbtt/src/TestOperations.h
Normal file
539
lbtt/src/TestOperations.h
Normal file
|
|
@ -0,0 +1,539 @@
|
|||
/*
|
||||
* Copyright (C) 1999, 2000, 2001, 2002
|
||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef TESTOPERATIONS_H
|
||||
#define TESTOPERATIONS_H
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma interface
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#include <config.h>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "Alloc.h"
|
||||
#include "Configuration.h"
|
||||
#include "Exception.h"
|
||||
#include "StateSpace.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 removeFile /* Removes a file. */
|
||||
(const char* filename, int indent = 0);
|
||||
|
||||
void printFileContents /* Displays the contents */
|
||||
(ostream& stream, const char* message, /* of a file. */
|
||||
const char* filename, int indent,
|
||||
const char* line_prefix = "");
|
||||
|
||||
void writeToTranscript /* Writes a message */
|
||||
(const string& message, /* into the transcript */
|
||||
bool show_formula_in_header = true); /* file. */
|
||||
|
||||
void generateStateSpace(); /* Generates a state space.
|
||||
*/
|
||||
|
||||
void generateFormulae /* Generates a random */
|
||||
(istream* formula_input_stream = 0); /* LTL formula and
|
||||
* stores the formula,
|
||||
* its negation and the
|
||||
* NNFs of the two
|
||||
* formulae into a
|
||||
* given array.
|
||||
*/
|
||||
|
||||
void verifyFormulaOnPath(); /* Evaluates the LTL
|
||||
* formula (accessed
|
||||
* through `round_info')
|
||||
* on a path directly
|
||||
* (if using paths as
|
||||
* state spaces).
|
||||
*/
|
||||
|
||||
void writeFormulaeToFiles(); /* Writes LTL formulas */
|
||||
/* into a file. */
|
||||
|
||||
void generateBuchiAutomaton /* Generates a Büchi */
|
||||
(int f, /* automaton from a LTL */
|
||||
vector<Configuration::AlgorithmInformation, /* formula stored in a */
|
||||
ALLOC(Configuration::AlgorithmInformation) > /* given file, using a */
|
||||
::size_type /* given LTL-to-Büchi */
|
||||
algorithm_id); /* translation algorithm
|
||||
* for the conversion.
|
||||
*/
|
||||
|
||||
void generateProductAutomaton /* Computes the */
|
||||
(int f, /* synchronous product */
|
||||
vector<Configuration::AlgorithmInformation, /* of a Büchi automaton */
|
||||
ALLOC(Configuration::AlgorithmInformation) > /* and a state space. */
|
||||
::size_type
|
||||
algorithm_id);
|
||||
|
||||
void performEmptinessCheck /* Performs an emptiness */
|
||||
(int f, /* check on a product */
|
||||
vector<Configuration::AlgorithmInformation, /* automaton. */
|
||||
ALLOC(Configuration::AlgorithmInformation) >
|
||||
::size_type
|
||||
algorithm_id);
|
||||
|
||||
void performConsistencyCheck /* Performs a */
|
||||
(vector<Configuration::AlgorithmInformation, /* consistency check on */
|
||||
ALLOC(Configuration::AlgorithmInformation) > /* the test results */
|
||||
::size_type /* for a formula and its */
|
||||
algorithm_id); /* negation. */
|
||||
|
||||
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 */
|
||||
246
lbtt/src/TestRoundInfo.h
Normal file
246
lbtt/src/TestRoundInfo.h
Normal file
|
|
@ -0,0 +1,246 @@
|
|||
/*
|
||||
* Copyright (C) 1999, 2000, 2001, 2002
|
||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef TESTROUNDINFO_H
|
||||
#define TESTROUNDINFO_H
|
||||
|
||||
#include <config.h>
|
||||
#include <cstdio>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include "Alloc.h"
|
||||
#include "Exception.h"
|
||||
#include "LtlFormula.h"
|
||||
#include "ProductAutomaton.h"
|
||||
#include "PathIterator.h"
|
||||
#include "StateSpace.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.
|
||||
*/
|
||||
|
||||
ifstream formula_input_file; /* Stream 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 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.
|
||||
*/
|
||||
|
||||
const Graph::ProductAutomaton* product_automaton; /* Pointer to the product
|
||||
* automaton used in the
|
||||
* current test round.
|
||||
*/
|
||||
|
||||
unsigned long int real_emptiness_check_size; /* Number of states in the
|
||||
* state space where the
|
||||
* emptiness check should
|
||||
* be performed.
|
||||
*/
|
||||
|
||||
unsigned long int /* Number of the round */
|
||||
next_round_to_change_statespace; /* in which to generate
|
||||
* a new state space.
|
||||
*/
|
||||
|
||||
unsigned long int /* Number of the round */
|
||||
next_round_to_change_formula; /* in which to generate
|
||||
* (or read) a new LTL
|
||||
* formula.
|
||||
*/
|
||||
|
||||
bool fresh_formula; /* True is a new formula
|
||||
* was generated (or read
|
||||
* from a file) in the
|
||||
* current round.
|
||||
*/
|
||||
|
||||
vector<class ::Ltl::LtlFormula*, /* Formulae used in the */
|
||||
ALLOC(class ::Ltl::LtlFormula*) > /* current round: */
|
||||
formulae; /* formulae[0]:
|
||||
* positive formula in
|
||||
* negation normal
|
||||
* form
|
||||
* formulae[1]:
|
||||
* negated formula in
|
||||
* negation normal
|
||||
* form
|
||||
* formulae[2]:
|
||||
* positive formula as
|
||||
* generated
|
||||
* formulae[3]:
|
||||
* negative formula as
|
||||
* generated
|
||||
*/
|
||||
|
||||
vector<bool, ALLOC(bool) > formula_in_file; /* The values in this
|
||||
* vector will be set to
|
||||
* true when the
|
||||
* corresponding
|
||||
* formulae have been
|
||||
* written to files
|
||||
* successfully. Index
|
||||
* 0 corresponds to the
|
||||
* positive formula and
|
||||
* 1 to the negative
|
||||
* formula.
|
||||
*/
|
||||
|
||||
char formula_file_name[2][L_tmpnam + 1]; /* Storage space for the */
|
||||
char automaton_file_name[L_tmpnam + 1]; /* names of several */
|
||||
char cout_capture_file[L_tmpnam + 1]; /* temporary files. */
|
||||
char cerr_capture_file[L_tmpnam + 1];
|
||||
|
||||
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), skip(false), abort(false),
|
||||
num_generated_statespaces(0), total_statespace_states(0),
|
||||
total_statespace_transitions(0), num_processed_formulae(0),
|
||||
fresh_statespace(false), statespace(0), path_iterator(0),
|
||||
product_automaton(0), real_emptiness_check_size(0),
|
||||
next_round_to_change_statespace(1), next_round_to_change_formula(1),
|
||||
fresh_formula(false), formulae(4, static_cast<class ::Ltl::LtlFormula*>(0)),
|
||||
formula_in_file(2, false)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Constructor for class TestRoundInfo. Creates a new
|
||||
* TestRoundInfo object.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline TestRoundInfo::~TestRoundInfo()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Destructor for class TestRoundInfo.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif /* !TESTROUNDINFO_H */
|
||||
100
lbtt/src/TestStatistics.cc
Normal file
100
lbtt/src/TestStatistics.cc
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* Copyright (C) 1999, 2000, 2001, 2002
|
||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma implementation
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#include <config.h>
|
||||
#include "TestStatistics.h"
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Function definitions for struct AlgorithmTestResults.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* ========================================================================= */
|
||||
void AlgorithmTestResults::emptinessReset()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Resets the emptiness checking information in an
|
||||
* AlgorithmTestResults structure.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
consistency_check_result = -1;
|
||||
consistency_check_comparisons = 0;
|
||||
failed_consistency_check_comparisons = 0;
|
||||
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
automaton_stats[i].number_of_product_states = 0;
|
||||
automaton_stats[i].number_of_product_transitions = 1;
|
||||
automaton_stats[i].emptiness_check_result.clear();
|
||||
automaton_stats[i].emptiness_check_performed = false;
|
||||
|
||||
for (vector<AutomatonStats::CrossComparisonStats,
|
||||
ALLOC(AutomatonStats::CrossComparisonStats) >::iterator it
|
||||
= automaton_stats[i].cross_comparison_stats.begin();
|
||||
it != automaton_stats[i].cross_comparison_stats.end();
|
||||
++it)
|
||||
{
|
||||
it->first = false;
|
||||
it->second = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
void AlgorithmTestResults::fullReset()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Resets the contents of an AlgorithmTestResults structure.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
emptinessReset();
|
||||
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
if (automaton_stats[i].buchi_automaton != 0)
|
||||
delete automaton_stats[i].buchi_automaton;
|
||||
automaton_stats[i].buchi_automaton = 0;
|
||||
automaton_stats[i].number_of_buchi_states = 0;
|
||||
automaton_stats[i].number_of_buchi_transitions = 0;
|
||||
automaton_stats[i].number_of_acceptance_sets = 0;
|
||||
automaton_stats[i].number_of_msccs = 0;
|
||||
automaton_stats[i].buchi_generation_time = 0.0;
|
||||
|
||||
for (vector<int, ALLOC(int) >::iterator it
|
||||
= automaton_stats[i].buchi_intersection_check_stats.begin();
|
||||
it != automaton_stats[i].buchi_intersection_check_stats.end();
|
||||
++it)
|
||||
*it = -1;
|
||||
}
|
||||
}
|
||||
584
lbtt/src/TestStatistics.h
Normal file
584
lbtt/src/TestStatistics.h
Normal file
|
|
@ -0,0 +1,584 @@
|
|||
/*
|
||||
* Copyright (C) 1999, 2000, 2001, 2002
|
||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef TESTSTATISTICS_H
|
||||
#define TESTSTATISTICS_H
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma interface
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#include <config.h>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include "Alloc.h"
|
||||
#include "BuchiAutomaton.h"
|
||||
#include "Configuration.h"
|
||||
#include "ProductAutomaton.h"
|
||||
#include "StateSpace.h"
|
||||
|
||||
using namespace std;
|
||||
using Graph::BuchiAutomaton;
|
||||
using Graph::StateSpace;
|
||||
using Graph::ProductAutomaton;
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* A data structure for storing test data for a single formula.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
struct AutomatonStats
|
||||
{
|
||||
explicit AutomatonStats /* Constructor. */
|
||||
(vector<Configuration::AlgorithmInformation,
|
||||
ALLOC(Configuration::AlgorithmInformation) >
|
||||
::size_type number_of_algorithms,
|
||||
StateSpace::size_type max_statespace_size);
|
||||
|
||||
/* default copy constructor */
|
||||
|
||||
~AutomatonStats(); /* Destructor. */
|
||||
|
||||
/* default assignment operator */
|
||||
|
||||
bool buchiAutomatonComputed() const; /* Tests whether a Büchi
|
||||
* automaton has been
|
||||
* computed.
|
||||
*/
|
||||
|
||||
bool productAutomatonComputed() const; /* Tests whether a product
|
||||
* automaton has been
|
||||
* computed.
|
||||
*/
|
||||
|
||||
bool crossComparisonPerformed /* Tests whether the */
|
||||
(unsigned long int algorithm) const; /* result of the
|
||||
* emptiness check has
|
||||
* been compared against
|
||||
* the result computed
|
||||
* using some other
|
||||
* implementation.
|
||||
*/
|
||||
|
||||
bool buchiIntersectionCheckPerformed /* Tests whether the */
|
||||
(unsigned long int algorithm) const; /* Büchi automata
|
||||
* intersection check
|
||||
* has been performed
|
||||
* against a given
|
||||
* implementation.
|
||||
*/
|
||||
|
||||
BuchiAutomaton* buchi_automaton; /* A pointer to a Büchi
|
||||
* automaton.
|
||||
*/
|
||||
|
||||
BuchiAutomaton::size_type number_of_buchi_states; /* Number of states in the
|
||||
* automaton.
|
||||
*/
|
||||
|
||||
unsigned long int number_of_buchi_transitions; /* Number of transitions in
|
||||
* the automaton.
|
||||
*/
|
||||
|
||||
unsigned long int number_of_acceptance_sets; /* Number of acceptance
|
||||
* sets in the automaton.
|
||||
*/
|
||||
|
||||
unsigned long int number_of_msccs; /* Number of maximal
|
||||
* strongly connected
|
||||
* components in the
|
||||
* automaton.
|
||||
*/
|
||||
|
||||
double buchi_generation_time; /* Time used to generate a
|
||||
* Büchi automaton.
|
||||
*/
|
||||
|
||||
ProductAutomaton::size_type /* Number of stats in a */
|
||||
number_of_product_states; /* product automaton. */
|
||||
|
||||
unsigned long int number_of_product_transitions; /* Number of transitions in
|
||||
* a product automaton.
|
||||
*/
|
||||
|
||||
Bitset emptiness_check_result; /* Result of the emptiness
|
||||
* check for the product
|
||||
* automaton.
|
||||
*/
|
||||
|
||||
bool emptiness_check_performed; /* Tells whether the
|
||||
* contents of the previous
|
||||
* Bitset are valid.
|
||||
*/
|
||||
|
||||
typedef pair<bool, unsigned long int>
|
||||
CrossComparisonStats;
|
||||
|
||||
vector<CrossComparisonStats, /* Emptiness check */
|
||||
ALLOC(CrossComparisonStats) > /* cross-comparison */
|
||||
cross_comparison_stats; /* results. The `first'
|
||||
* element of the pair
|
||||
* tells whether a cross-
|
||||
* comparison with a given
|
||||
* algorithm has been
|
||||
* performed, and the
|
||||
* `second' element of the
|
||||
* pair gives the number
|
||||
* of system states in
|
||||
* which the results
|
||||
* differ.
|
||||
*/
|
||||
|
||||
vector<int, ALLOC(int) > /* Büchi automaton */
|
||||
buchi_intersection_check_stats; /* intersection
|
||||
* emptiness check
|
||||
* results. The elements
|
||||
* of the vector tell
|
||||
* whether the check has
|
||||
* been performed
|
||||
* against the automata
|
||||
* constructed from the
|
||||
* negated formula using
|
||||
* the other algorithms,
|
||||
* and if yes, the result
|
||||
* of the check
|
||||
* (-1 = check not
|
||||
* performed, 0 = check
|
||||
* failed, 1 = check
|
||||
* was successful).
|
||||
*/
|
||||
};
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* A data structure for storing test data for a single algorithm.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
struct AlgorithmTestResults
|
||||
{
|
||||
explicit AlgorithmTestResults /* Constructor. */
|
||||
(vector<Configuration::AlgorithmInformation,
|
||||
ALLOC(Configuration::AlgorithmInformation) >
|
||||
::size_type
|
||||
number_of_algorithms,
|
||||
StateSpace::size_type max_statespace_size);
|
||||
|
||||
/* default copy constructor */
|
||||
|
||||
~AlgorithmTestResults(); /* Destructor. */
|
||||
|
||||
/* default assignment operator */
|
||||
|
||||
void emptinessReset(); /* Resets the emptiness
|
||||
* checking information.
|
||||
*/
|
||||
|
||||
void fullReset(); /* Resets the test results
|
||||
* completely.
|
||||
*/
|
||||
|
||||
int consistency_check_result; /* Tells the consistency
|
||||
* check status for an
|
||||
* algorithm. The value
|
||||
* -1 means the check has
|
||||
* not been performed, a 0
|
||||
* stands for a failed
|
||||
* check, and the value 1
|
||||
* denotes that the check
|
||||
* was successful.
|
||||
*/
|
||||
|
||||
StateSpace::size_type /* Number of test cases */
|
||||
consistency_check_comparisons; /* in the consistency
|
||||
* check.
|
||||
*/
|
||||
|
||||
StateSpace::size_type /* Number of failed test */
|
||||
failed_consistency_check_comparisons; /* cases in the consistency
|
||||
* check.
|
||||
*/
|
||||
|
||||
vector<AutomatonStats, ALLOC(AutomatonStats) > /* A two-element vector */
|
||||
automaton_stats; /* storing test results
|
||||
* for an algorithm.
|
||||
*/
|
||||
};
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* A data structure for storing test statistics for a single algorithm over the
|
||||
* whole test session.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
struct TestStatistics
|
||||
{
|
||||
explicit TestStatistics /* Constructor. */
|
||||
(vector<TestStatistics,
|
||||
ALLOC(TestStatistics) >::size_type
|
||||
number_of_algorithms);
|
||||
|
||||
/* default copy constructor */
|
||||
|
||||
~TestStatistics();
|
||||
|
||||
/* default assignment operator */
|
||||
|
||||
unsigned long int /* Number of failed */
|
||||
failures_to_compute_buchi_automaton[2]; /* attempts to generate
|
||||
* a Büchi automaton.
|
||||
*/
|
||||
|
||||
unsigned long int buchi_automaton_count[2]; /* Number of attempts to
|
||||
* generate a Büchi
|
||||
* automaton.
|
||||
*/
|
||||
|
||||
unsigned long int /* Number of failed */
|
||||
failures_to_compute_product_automaton[2]; /* attempts to generate
|
||||
* a product automaton.
|
||||
*/
|
||||
|
||||
unsigned long int product_automaton_count[2]; /* Number of attempts to
|
||||
* generate a product
|
||||
* automaton.
|
||||
*/
|
||||
|
||||
unsigned long int consistency_check_failures; /* Number of failed
|
||||
* consistency checks.
|
||||
*/
|
||||
|
||||
unsigned long int consistency_checks_performed; /* Number of consistency
|
||||
* checks performed.
|
||||
*/
|
||||
|
||||
unsigned long int /* Total number of */
|
||||
total_number_of_buchi_states[2]; /* states in all the
|
||||
* generated Büchi
|
||||
* automata.
|
||||
*/
|
||||
|
||||
unsigned long int /* Total number of */
|
||||
total_number_of_buchi_transitions[2]; /* transitions in all
|
||||
* the generated Büchi
|
||||
* automata.
|
||||
*/
|
||||
|
||||
unsigned long int /* Total number of sets */
|
||||
total_number_of_acceptance_sets[2]; /* of accepting states
|
||||
* in all the generated
|
||||
* Büchi automata.
|
||||
*/
|
||||
|
||||
unsigned long int /* Total number of */
|
||||
total_number_of_msccs[2]; /* maximal strongly
|
||||
* connected components
|
||||
* in the generated
|
||||
* Büchi automata.
|
||||
*/
|
||||
|
||||
double total_buchi_generation_time[2]; /* Total time used when
|
||||
* generating Büchi
|
||||
* automata.
|
||||
*/
|
||||
|
||||
unsigned long int /* Total number of */
|
||||
total_number_of_product_states[2]; /* states in all the
|
||||
* generated product
|
||||
* automata.
|
||||
*/
|
||||
|
||||
unsigned long int /* Total number of */
|
||||
total_number_of_product_transitions[2]; /* transitions in all the
|
||||
* generated product
|
||||
* automata.
|
||||
*/
|
||||
|
||||
vector<unsigned long int, /* Number of failed */
|
||||
ALLOC(unsigned long int) > /* result cross- */
|
||||
cross_comparison_mismatches; /* comparisons. */
|
||||
|
||||
vector<unsigned long int, /* Number of failed */
|
||||
ALLOC(unsigned long int) > /* result cross- */
|
||||
initial_cross_comparison_mismatches; /* comparisons in the
|
||||
* initial state of the
|
||||
* state space.
|
||||
*/
|
||||
|
||||
vector<unsigned long int, /* Number of result */
|
||||
ALLOC(unsigned long int) > /* cross-comparisons */
|
||||
cross_comparisons_performed; /* performed. */
|
||||
|
||||
vector<unsigned long int, /* Number of failed */
|
||||
ALLOC(unsigned long int) > /* Büchi automaton */
|
||||
buchi_intersection_check_failures; /* emptiness checks
|
||||
* against the automata
|
||||
* constructed from the
|
||||
* negated formula
|
||||
* using the other
|
||||
* algorithms.
|
||||
*/
|
||||
|
||||
vector<unsigned long int, /* Number of Büchi */
|
||||
ALLOC(unsigned long int) > /* automaton emptiness */
|
||||
buchi_intersection_checks_performed; /* checks performed
|
||||
* against the automata
|
||||
* constructed from the
|
||||
* negated formula using
|
||||
* the other algorithms.
|
||||
*/
|
||||
};
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Inline function definitions for struct AutomatonStats.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* ========================================================================= */
|
||||
inline AutomatonStats::AutomatonStats
|
||||
(vector<Configuration::AlgorithmInformation,
|
||||
ALLOC(Configuration::AlgorithmInformation) >::size_type
|
||||
number_of_algorithms,
|
||||
StateSpace::size_type max_statespace_size) :
|
||||
buchi_automaton(0), number_of_buchi_states(0),
|
||||
number_of_buchi_transitions(0), number_of_acceptance_sets(0),
|
||||
number_of_msccs(0), buchi_generation_time(0.0), number_of_product_states(0),
|
||||
number_of_product_transitions(1),
|
||||
emptiness_check_result(max_statespace_size),
|
||||
emptiness_check_performed(false),
|
||||
cross_comparison_stats(number_of_algorithms, make_pair(false, 0)),
|
||||
buchi_intersection_check_stats(number_of_algorithms, -1)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Constructor for struct AutomatonStats.
|
||||
*
|
||||
* Arguments: number_of_algorithms -- Number of implementations taking
|
||||
* part in the tests.
|
||||
* max_statespace_size -- Maximum size of the state spaces
|
||||
* used in testing.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
emptiness_check_result.clear();
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline AutomatonStats::~AutomatonStats()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Destructor for struct AutomatonStats.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline bool AutomatonStats::buchiAutomatonComputed() const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Test whether a Büchi automaton has been computed (i.e.,
|
||||
* whether information about the automaton has been stored in
|
||||
* the AutomatonStats structure).
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return (buchi_automaton != 0);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline bool AutomatonStats::productAutomatonComputed() const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Test whether a product automaton has been computed (i.e.,
|
||||
* whether information about the automaton has been stored in
|
||||
* the AutomatonStats structure).
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return (number_of_product_states != 0
|
||||
|| number_of_product_transitions <= number_of_product_states);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline bool
|
||||
AutomatonStats::crossComparisonPerformed(unsigned long int algorithm) const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Test whether the emptiness check result for a product
|
||||
* automaton has been compared with another result computed
|
||||
* using a different implementation.
|
||||
*
|
||||
* Arguments: algorithm -- Implementation identifier.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return cross_comparison_stats[algorithm].first;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline bool
|
||||
AutomatonStats::buchiIntersectionCheckPerformed(unsigned long int algorithm)
|
||||
const
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Test whether the Büchi automata intersection check result
|
||||
* (against some other implementation) is available in the data
|
||||
* structure.
|
||||
*
|
||||
* Arguments: algorithm -- Implementation identifier.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
return (buchi_intersection_check_stats[algorithm] != -1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Inline function definitions for struct AlgorithmTestResults.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* ========================================================================= */
|
||||
inline AlgorithmTestResults::AlgorithmTestResults
|
||||
(vector<Configuration::AlgorithmInformation,
|
||||
ALLOC(Configuration::AlgorithmInformation) >::size_type
|
||||
number_of_algorithms,
|
||||
StateSpace::size_type max_statespace_size) :
|
||||
consistency_check_result(-1), consistency_check_comparisons(0),
|
||||
failed_consistency_check_comparisons(0),
|
||||
automaton_stats(2, AutomatonStats(number_of_algorithms,
|
||||
max_statespace_size))
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Constructor for struct AlgorithmTestResults.
|
||||
*
|
||||
* Arguments: number_of_algorithms -- Number of implementations taking
|
||||
* part in the tests.
|
||||
* max_statespace_size -- Maximum size of the state spaces
|
||||
* used in testing.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline AlgorithmTestResults::~AlgorithmTestResults()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Destructor for struct AlgorithmTestResults.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Inline function definitions for struct TestStatistics.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* ========================================================================= */
|
||||
inline TestStatistics::TestStatistics
|
||||
(vector<TestStatistics, ALLOC(TestStatistics) >::size_type
|
||||
number_of_algorithms) :
|
||||
consistency_check_failures(0), consistency_checks_performed(0),
|
||||
cross_comparison_mismatches(number_of_algorithms, 0),
|
||||
initial_cross_comparison_mismatches(number_of_algorithms, 0),
|
||||
cross_comparisons_performed(number_of_algorithms, 0),
|
||||
buchi_intersection_check_failures(number_of_algorithms, 0),
|
||||
buchi_intersection_checks_performed(number_of_algorithms, 0)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Constructor for struct TestStatistics.
|
||||
*
|
||||
* Arguments: number_of_algorithms -- Number of implementations taking
|
||||
* part in the tests.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
failures_to_compute_buchi_automaton[i] = 0;
|
||||
buchi_automaton_count[i] = 0;
|
||||
failures_to_compute_product_automaton[i] = 0;
|
||||
product_automaton_count[i] = 0;
|
||||
total_number_of_buchi_states[i] = 0;
|
||||
total_number_of_buchi_transitions[i] = 0;
|
||||
total_number_of_acceptance_sets[i] = 0;
|
||||
total_number_of_msccs[i] = 0;
|
||||
total_number_of_product_states[i] = 0;
|
||||
total_number_of_product_transitions[i] = 0;
|
||||
total_buchi_generation_time[i] = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline TestStatistics::~TestStatistics()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Destructor for struct TestStatistics.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
}
|
||||
|
||||
#endif /* !TESTSTATISTICS_H */
|
||||
91
lbtt/src/TranslatorInterface.h
Normal file
91
lbtt/src/TranslatorInterface.h
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* Copyright (C) 1999, 2000, 2001, 2002
|
||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef TRANSLATORINTERFACE_H
|
||||
#define TRANSLATORINTERFACE_H
|
||||
|
||||
#include <config.h>
|
||||
#include "LtlFormula.h"
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* General interface class for an LTL-to-Büchi translator. The interface
|
||||
* provides an abstract member function `translate' taking an LtlFormula
|
||||
* and an output file name as arguments. The purpose of an actual
|
||||
* implementation of the function is to translate the given LtlFormula into
|
||||
* an automaton and store the results in the given file.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
class TranslatorInterface
|
||||
{
|
||||
public:
|
||||
TranslatorInterface(); /* Constructor. */
|
||||
|
||||
virtual ~TranslatorInterface() = 0; /* Destructor. */
|
||||
|
||||
virtual void translate /* Interface for a */
|
||||
(const ::Ltl::LtlFormula& formula, /* translation */
|
||||
const char* filename) = 0; /* algorithm. */
|
||||
|
||||
private:
|
||||
TranslatorInterface(const TranslatorInterface&); /* Prevent copying and */
|
||||
TranslatorInterface& operator= /* assignment of */
|
||||
(const TranslatorInterface&); /* TranslatorInterface
|
||||
* objects.
|
||||
*/
|
||||
};
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Inline function definitions for class TranslatorInterface.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/* ========================================================================= */
|
||||
inline TranslatorInterface::TranslatorInterface()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Constructor for class TranslatorInterface.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
inline TranslatorInterface::~TranslatorInterface()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Destructor for class TranslatorInterface.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
}
|
||||
|
||||
#endif /* !TRANSLATORINTERFACE_H */
|
||||
927
lbtt/src/UserCommandReader.cc
Normal file
927
lbtt/src/UserCommandReader.cc
Normal file
|
|
@ -0,0 +1,927 @@
|
|||
/*
|
||||
* Copyright (C) 1999, 2000, 2001, 2002
|
||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma implementation
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#include <config.h>
|
||||
#include <csignal>
|
||||
#include <cstdio>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#ifdef HAVE_SSTREAM
|
||||
#include <sstream>
|
||||
#else
|
||||
#include <strstream>
|
||||
#endif /* HAVE_SSTREAM */
|
||||
#include "DispUtil.h"
|
||||
#include "ProductAutomaton.h"
|
||||
#include "SharedTestData.h"
|
||||
#include "StatDisplay.h"
|
||||
#include "StringUtil.h"
|
||||
#include "TestRoundInfo.h"
|
||||
#include "TestStatistics.h"
|
||||
#include "TestOperations.h"
|
||||
#include "UserCommandReader.h"
|
||||
#include "UserCommands.h"
|
||||
|
||||
#ifdef HAVE_READLINE
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <readline/readline.h>
|
||||
#include <readline/history.h>
|
||||
#endif /* HAVE_READLINE */
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Functions for reading and parsing user commands.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
namespace UserCommandInterface
|
||||
{
|
||||
|
||||
using namespace ::SharedTestData;
|
||||
using namespace ::StatDisplay;
|
||||
using namespace ::StringUtil;
|
||||
using namespace ::UserCommands;
|
||||
|
||||
/* ========================================================================= */
|
||||
void executeUserCommands()
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Loop for reading user commands and executing them after a
|
||||
* test round.
|
||||
*
|
||||
* Arguments: None.
|
||||
*
|
||||
* Returns: Nothing. However, changes `round_info.current_round',
|
||||
* `round_info.next_round_to_stop',
|
||||
* `round_info.next_round_to_run' and `round_info.abort' as a
|
||||
* side effect, depending on the user's wish to abort testing,
|
||||
* skip some number of test rounds or continue testing for a
|
||||
* number of rounds.
|
||||
*
|
||||
* ------------------------------------------------------------------------ */
|
||||
{
|
||||
string input_line;
|
||||
vector<string, ALLOC(string) > input_tokens;
|
||||
TokenType token;
|
||||
|
||||
bool formula_type = true;
|
||||
|
||||
pair<string, bool> redirection_info;
|
||||
string external_command;
|
||||
ofstream* output_file = 0;
|
||||
#ifdef HAVE_SSTREAM
|
||||
ostringstream* output_string = 0;
|
||||
#else
|
||||
ostrstream* output_string = 0;
|
||||
#endif /* HAVE_SSTREAM */
|
||||
ostream* output_stream = 0;
|
||||
|
||||
const string prompt = " ** [Round " + toString(round_info.current_round)
|
||||
+ " of " + toString(configuration.global_options.
|
||||
number_of_rounds)
|
||||
+ "] >> ";
|
||||
int indent;
|
||||
|
||||
#ifdef HAVE_READLINE
|
||||
char* prompt_c_str = new char[prompt.length() + 1];
|
||||
strcpy(prompt_c_str, prompt.c_str());
|
||||
|
||||
char* line;
|
||||
|
||||
try
|
||||
{
|
||||
#endif /* HAVE_READLINE */
|
||||
|
||||
ProductAutomaton* product_automaton = 0;
|
||||
pair<unsigned long int, bool> last_computed_product_automaton;
|
||||
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
|
||||
while (1)
|
||||
{
|
||||
try
|
||||
{
|
||||
input_line = "";
|
||||
#ifdef HAVE_READLINE
|
||||
line = readline(prompt_c_str);
|
||||
if (line != static_cast<char*>(0))
|
||||
input_line = line;
|
||||
else
|
||||
{
|
||||
round_info.cout << '\n';
|
||||
round_info.cout.flush();
|
||||
}
|
||||
#else
|
||||
round_info.cout << prompt;
|
||||
round_info.cout.flush();
|
||||
getline(cin, input_line, '\n');
|
||||
if (cin.eof())
|
||||
{
|
||||
round_info.cout << '\n';
|
||||
round_info.cout.flush();
|
||||
cin.clear();
|
||||
}
|
||||
#endif /* HAVE_READLINE */
|
||||
|
||||
external_command = "";
|
||||
string::size_type pipe_pos = input_line.find_first_of('|');
|
||||
if (pipe_pos != string::npos)
|
||||
{
|
||||
string::size_type nonspace_pos
|
||||
= input_line.find_first_not_of(" \t", pipe_pos + 1);
|
||||
if (nonspace_pos != string::npos)
|
||||
{
|
||||
external_command = input_line.substr(nonspace_pos);
|
||||
input_line = input_line.substr(0, pipe_pos);
|
||||
}
|
||||
}
|
||||
|
||||
sliceString(input_line, " \t", input_tokens);
|
||||
|
||||
user_break = false;
|
||||
|
||||
if (!input_tokens.empty())
|
||||
{
|
||||
#ifdef HAVE_READLINE
|
||||
add_history(line);
|
||||
free(line);
|
||||
#endif /* HAVE_READLINE */
|
||||
round_info.cout << '\n';
|
||||
round_info.cout.flush();
|
||||
|
||||
token = parseCommand(input_tokens[0]);
|
||||
|
||||
if (token == CONTINUE || token == SKIP)
|
||||
{
|
||||
verifyArgumentCount(input_tokens, 0, 1);
|
||||
|
||||
unsigned long int rounds_to_continue;
|
||||
|
||||
rounds_to_continue = (input_tokens.size() > 1
|
||||
? parseNumber(input_tokens[1])
|
||||
: 1);
|
||||
|
||||
if (rounds_to_continue == 0)
|
||||
throw CommandErrorException("Argument of the command must be "
|
||||
"positive.");
|
||||
|
||||
if (token == CONTINUE)
|
||||
{
|
||||
bool all_algorithms_disabled = true;
|
||||
|
||||
for (vector<Configuration::AlgorithmInformation,
|
||||
ALLOC(Configuration::AlgorithmInformation) >
|
||||
::const_iterator
|
||||
algorithm = configuration.algorithms.begin();
|
||||
algorithm != configuration.algorithms.end();
|
||||
++algorithm)
|
||||
{
|
||||
if (algorithm->enabled)
|
||||
{
|
||||
all_algorithms_disabled = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Show a warning if the `continue' command would result in no
|
||||
* further tests in the case that none of the implementations is
|
||||
* enabled for testing.
|
||||
*/
|
||||
|
||||
if (configuration.global_options.interactive
|
||||
!= Configuration::ALWAYS
|
||||
&& all_algorithms_disabled)
|
||||
{
|
||||
round_info.cout << " Warning! All algorithms are currently "
|
||||
"disabled.\n Are you sure you wish to "
|
||||
"continue? [y/n] ";
|
||||
round_info.cout.flush();
|
||||
|
||||
input_line = "";
|
||||
getline(cin, input_line, '\n');
|
||||
sliceString(input_line, " \t", input_tokens);
|
||||
|
||||
if (!input_tokens.empty()
|
||||
&& (input_tokens[0][0] == 'y' || input_tokens[0][0] == 'Y'))
|
||||
round_info.next_round_to_stop
|
||||
= configuration.global_options.number_of_rounds + 1;
|
||||
else
|
||||
{
|
||||
round_info.cout << '\n';
|
||||
round_info.cout.flush();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (round_info.next_round_to_run == round_info.current_round)
|
||||
round_info.next_round_to_run++;
|
||||
|
||||
if (configuration.global_options.interactive
|
||||
== Configuration::ALWAYS
|
||||
|| input_tokens.size() > 1)
|
||||
round_info.next_round_to_stop
|
||||
= round_info.current_round + rounds_to_continue;
|
||||
}
|
||||
else /* token == SKIP */
|
||||
{
|
||||
round_info.next_round_to_stop
|
||||
= round_info.current_round + rounds_to_continue;
|
||||
|
||||
round_info.next_round_to_run = round_info.next_round_to_stop + 1;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
else if (token == ENABLE || token == DISABLE)
|
||||
{
|
||||
verifyArgumentCount(input_tokens, 0, 1);
|
||||
changeAlgorithmState(input_tokens, token == ENABLE);
|
||||
continue;
|
||||
}
|
||||
else if (token == QUIT)
|
||||
{
|
||||
verifyArgumentCount(input_tokens, 0, 0);
|
||||
round_info.abort = true;
|
||||
break;
|
||||
}
|
||||
else if (token == VERBOSITY)
|
||||
{
|
||||
verifyArgumentCount(input_tokens, 0, 1);
|
||||
changeVerbosity(input_tokens);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (round_info.skip
|
||||
&& (token == BUCHI || token == BUCHIANALYZE
|
||||
|| token == CONSISTENCYANALYSIS || token == EVALUATE
|
||||
|| token == FORMULA || token == INCONSISTENCIES
|
||||
|| token == RESULTANALYZE || token == STATESPACE))
|
||||
throw CommandErrorException("This command is not available because "
|
||||
"the current test round was skipped.");
|
||||
|
||||
/*
|
||||
* If the command expects a formula identifier as a parameter,
|
||||
* determine the type of the formula to which the command refers.
|
||||
*/
|
||||
|
||||
if (token == BUCHI || token == EVALUATE
|
||||
|| token == FORMULA || token == RESULTANALYZE)
|
||||
formula_type = parseFormulaType(input_tokens);
|
||||
|
||||
if (!external_command.empty())
|
||||
{
|
||||
/*
|
||||
* If the command output should be piped to an external program,
|
||||
* prepare to collect the output into a string. In this case no
|
||||
* output redirection (> or >>) is allowed.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_SSTREAM
|
||||
output_string = new ostringstream();
|
||||
#else
|
||||
output_string = new ostrstream();
|
||||
#endif /* HAVE_SSTREAM */
|
||||
output_stream = output_string;
|
||||
indent = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Determine whether the output of the command should be saved or
|
||||
* appended to a file, instead of displaying it on the console. If
|
||||
* output redirection is required, open a file for output.
|
||||
*/
|
||||
|
||||
redirection_info = parseRedirection(input_tokens);
|
||||
|
||||
if (redirection_info.first.empty())
|
||||
{
|
||||
output_stream = &cout;
|
||||
indent = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
output_file = new ofstream();
|
||||
|
||||
try
|
||||
{
|
||||
TestOperations::openFile(redirection_info.first.c_str(),
|
||||
*output_file,
|
||||
ios::out | (redirection_info.second
|
||||
? ios::app
|
||||
: ios::trunc),
|
||||
2);
|
||||
}
|
||||
catch (const IOException& e)
|
||||
{
|
||||
delete output_file;
|
||||
output_file = 0;
|
||||
throw CommandErrorException(e.what());
|
||||
}
|
||||
|
||||
output_stream = output_file;
|
||||
indent = 0;
|
||||
}
|
||||
}
|
||||
|
||||
switch (token)
|
||||
{
|
||||
case ALGORITHMS :
|
||||
verifyArgumentCount(input_tokens, 0, 0);
|
||||
printAlgorithmList(*output_stream, indent);
|
||||
if (output_file != 0)
|
||||
round_info.cout << " List of algorithms";
|
||||
break;
|
||||
|
||||
case BUCHI :
|
||||
{
|
||||
bool use_dot = (input_tokens.size() == 3
|
||||
&& input_tokens[2] == "dot");
|
||||
|
||||
verifyArgumentCount(input_tokens, 1, 2);
|
||||
printBuchiAutomaton(*output_stream, indent,
|
||||
formula_type,
|
||||
input_tokens,
|
||||
(use_dot ? Graph::DOT : Graph::NORMAL));
|
||||
if (output_file != 0)
|
||||
{
|
||||
round_info.cout << " Büchi automaton information";
|
||||
if (use_dot)
|
||||
round_info.cout << " (in dot format)";
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case BUCHIANALYZE :
|
||||
verifyArgumentCount(input_tokens, 2, 2);
|
||||
printAutomatonAnalysisResults(*output_stream, indent,
|
||||
parseNumber(input_tokens[1]),
|
||||
parseNumber(input_tokens[2]));
|
||||
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, 0);
|
||||
printFormula(*output_stream, indent, formula_type);
|
||||
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,
|
||||
product_automaton, last_computed_product_automaton);
|
||||
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);
|
||||
int status = fputs(outstring.c_str(), output_pipe);
|
||||
if (status != EOF)
|
||||
fflush(output_pipe);
|
||||
pclose(output_pipe);
|
||||
round_info.cout << '\n';
|
||||
round_info.cout.flush();
|
||||
if (status == EOF)
|
||||
throw IOException("Error writing to pipe.");
|
||||
}
|
||||
else if (output_file != 0)
|
||||
{
|
||||
round_info.cout << string(redirection_info.second
|
||||
? " appended"
|
||||
: " written")
|
||||
+ " to `" + redirection_info.first + "'.\n\n";
|
||||
round_info.cout.flush();
|
||||
}
|
||||
}
|
||||
else if (!external_command.empty())
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
if (product_automaton != 0)
|
||||
{
|
||||
::DispUtil::printText
|
||||
("<cleaning up memory allocated for product automaton>", 4, 2);
|
||||
|
||||
delete product_automaton;
|
||||
|
||||
::DispUtil::printText(" ok\n", 4);
|
||||
}
|
||||
|
||||
#ifdef HAVE_READLINE
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
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.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
|
||||
/*
|
||||
* gcc versions prior to version 3 do not conform to the C++ standard in their
|
||||
* support for the string::compare functions. Use a macro to fix this if
|
||||
* necessary.
|
||||
*/
|
||||
|
||||
#ifdef __GNUC__
|
||||
#if __GNUC__ < 3
|
||||
#define compare(start,end,str,dummy) compare(str,start,end)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
TokenType token_type = UNKNOWN;
|
||||
string::size_type len = token.length();
|
||||
bool ambiguous = false;
|
||||
|
||||
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 (token.compare(1, len - 1, "nconsistencies", len - 1) == 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 'v' :
|
||||
if (token.compare(1, len - 1, "erbosity", len - 1) == 0)
|
||||
token_type = VERBOSITY;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ambiguous)
|
||||
throw CommandErrorException("Ambiguous command.");
|
||||
|
||||
return token_type;
|
||||
|
||||
#ifdef __GNUC__
|
||||
#if __GNUC__ < 3
|
||||
#undef compare
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
void verifyArgumentCount
|
||||
(const vector<string, ALLOC(string) >& command,
|
||||
vector<string, ALLOC(string) >::size_type min_arg_count,
|
||||
vector<string, ALLOC(string) >::size_type max_arg_count)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Verifies that the number of arguments given for a user
|
||||
* command is between a given interval.
|
||||
*
|
||||
* Arguments: command -- A reference to a constant vector of
|
||||
* strings (the user command and its
|
||||
* arguments).
|
||||
* min_arg_count -- Smallest allowed number of arguments.
|
||||
* max_arg_count -- Largest allowed number of arguments.
|
||||
*
|
||||
* Returns: Nothing.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
if (command.size() < min_arg_count + 1)
|
||||
throw CommandErrorException("Too few arguments for command.");
|
||||
else if (command.size() > max_arg_count + 1)
|
||||
throw CommandErrorException("Too many arguments for command.");
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
pair<string, bool> parseRedirection
|
||||
(vector<string, ALLOC(string) >& input_tokens)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Tests whether the last argument to a user command specifies
|
||||
* output redirection. If redirection is requested, the
|
||||
* "argument" specifying the redirection is removed from the
|
||||
* vector of strings forming the command.
|
||||
*
|
||||
* Argument: input_tokens -- A reference to a vector of strings giving
|
||||
* the user command and its arguments.
|
||||
*
|
||||
* Returns: A pair whose first component is the name of the output file
|
||||
* (or the empty string if no redirection was specified) and
|
||||
* whose second component determines whether the output should
|
||||
* be appended to the file instead of creating a new file.
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
string filename;
|
||||
bool append = false;
|
||||
|
||||
if (!input_tokens.empty())
|
||||
{
|
||||
string& token = input_tokens.back();
|
||||
|
||||
if (token[0] == '>')
|
||||
{
|
||||
if (token.length() > 1)
|
||||
{
|
||||
if (token[1] == '>')
|
||||
{
|
||||
if (token.length() > 2)
|
||||
{
|
||||
append = true;
|
||||
filename = token.substr(2);
|
||||
input_tokens.pop_back();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
filename = token.substr(1);
|
||||
input_tokens.pop_back();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (input_tokens.size() >= 2)
|
||||
{
|
||||
string& token = *(input_tokens.rbegin() + 1);
|
||||
|
||||
if (token[0] == '>' && (token.length() == 1
|
||||
|| (token.length() == 2 && token[1] == '>')))
|
||||
{
|
||||
filename = input_tokens.back();
|
||||
append = (token.length() == 2);
|
||||
input_tokens.pop_back();
|
||||
input_tokens.pop_back();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return make_pair(filename, append);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
bool parseFormulaType(vector<string, ALLOC(string) >& input_tokens)
|
||||
/* ----------------------------------------------------------------------------
|
||||
*
|
||||
* Description: Tests whether the first argument of a command specifies a
|
||||
* formula (i.e., whether the first argument of the command is
|
||||
* either a `+' or a `-'). If it is, the argument is removed
|
||||
* from the vector of strings forming the command.
|
||||
*
|
||||
* Argument: input_tokens -- A reference to a vector of strings giving
|
||||
* the user command.
|
||||
*
|
||||
* Returns: A truth value according to whether a formula or its negation
|
||||
* was specified; the effect of specifying no formula type is
|
||||
* the same as giving a `+' as an argument (i.e. the formula
|
||||
* type defaults to the positive formula).
|
||||
*
|
||||
* ------------------------------------------------------------------------- */
|
||||
{
|
||||
bool formula_type = true;
|
||||
|
||||
if (input_tokens.size() >= 2)
|
||||
{
|
||||
formula_type = (input_tokens[1] != "-");
|
||||
|
||||
if (input_tokens[1].length() == 1
|
||||
&& (input_tokens[1][0] == '+' || input_tokens[1][0] == '-'))
|
||||
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) + ").");
|
||||
}
|
||||
|
||||
}
|
||||
181
lbtt/src/UserCommandReader.h
Normal file
181
lbtt/src/UserCommandReader.h
Normal file
|
|
@ -0,0 +1,181 @@
|
|||
/*
|
||||
* Copyright (C) 1999, 2000, 2001, 2002
|
||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef USERCOMMANDREADER_H
|
||||
#define USERCOMMANDREADER_H
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma interface
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#include <config.h>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include "Alloc.h"
|
||||
#include "Configuration.h"
|
||||
#include "Exception.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
extern Configuration configuration;
|
||||
|
||||
extern bool user_break;
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Interactive user command interface.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
namespace UserCommandInterface
|
||||
{
|
||||
|
||||
void executeUserCommands(); /* Function for reading and
|
||||
* executing user commands
|
||||
* at the end of a test
|
||||
* round.
|
||||
*/
|
||||
|
||||
enum TokenType /* User commands. */
|
||||
{ALGORITHMS, BUCHI, BUCHIANALYZE,
|
||||
CONSISTENCYANALYSIS, CONTINUE, DISABLE, ENABLE,
|
||||
EVALUATE, FORMULA, HELP, INCONSISTENCIES, QUIT,
|
||||
RESULTANALYZE, RESULTS, SKIP, STATESPACE,
|
||||
STATISTICS, VERBOSITY, UNKNOWN, _NO_INPUT};
|
||||
|
||||
TokenType parseCommand(const string& token); /* Translates a command
|
||||
* name into its
|
||||
* corresponding
|
||||
* TokenType identifier.
|
||||
*/
|
||||
|
||||
void verifyArgumentCount /* Checks that the */
|
||||
(const vector<string, ALLOC(string) >& /* number of arguments */
|
||||
arguments, /* for a command is */
|
||||
vector<string, ALLOC(string) >::size_type /* within given limits. */
|
||||
min_arg_count,
|
||||
vector<string, ALLOC(string) >::size_type
|
||||
max_arg_count);
|
||||
|
||||
pair<string, bool> parseRedirection /* Checks whether an */
|
||||
(vector<string, ALLOC(string) >& input_tokens); /* user command given
|
||||
* will require
|
||||
* redirecting its
|
||||
* output to a file.
|
||||
*/
|
||||
|
||||
bool parseFormulaType /* Checks whether an */
|
||||
(vector<string, ALLOC(string) >& input_tokens); /* user command
|
||||
* 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 */
|
||||
2282
lbtt/src/UserCommands.cc
Normal file
2282
lbtt/src/UserCommands.cc
Normal file
File diff suppressed because it is too large
Load diff
168
lbtt/src/UserCommands.h
Normal file
168
lbtt/src/UserCommands.h
Normal file
|
|
@ -0,0 +1,168 @@
|
|||
/*
|
||||
* Copyright (C) 1999, 2000, 2001, 2002
|
||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef USERCOMMANDS_H
|
||||
#define USERCOMMANDS_H
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma interface
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#include <config.h>
|
||||
#include <deque>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include "Alloc.h"
|
||||
#include "BuchiAutomaton.h"
|
||||
#include "Configuration.h"
|
||||
#include "ProductAutomaton.h"
|
||||
#include "StateSpace.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
extern Configuration configuration;
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Implementations for user commands.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
namespace UserCommands
|
||||
{
|
||||
|
||||
void computeProductAutomaton /* Computes a product */
|
||||
(ProductAutomaton*& product_automaton, /* automaton. */
|
||||
const BuchiAutomaton& buchi_automaton,
|
||||
pair<unsigned long int, bool>& last_automaton,
|
||||
const pair<unsigned long int, bool>&
|
||||
new_automaton);
|
||||
|
||||
void printAlgorithmList /* Displays a list of */
|
||||
(ostream& stream, int indent); /* algorithms used in
|
||||
* the tests.
|
||||
*/
|
||||
|
||||
void synchronizePrefixAndCycle /* Synchronizes a prefix */
|
||||
(deque<Graph::Graph<GraphEdgeContainer> /* with a cycle in a */
|
||||
::size_type, /* sequence of graph */
|
||||
ALLOC(Graph::Graph<GraphEdgeContainer> /* state identifiers. */
|
||||
::size_type) >&
|
||||
prefix,
|
||||
deque<Graph::Graph<GraphEdgeContainer>
|
||||
::size_type,
|
||||
ALLOC(Graph::Graph<GraphEdgeContainer>
|
||||
::size_type) >&
|
||||
cycle);
|
||||
|
||||
void printCrossComparisonAnalysisResults /* Analyzes a */
|
||||
(ostream& stream, int indent, /* contradiction between */
|
||||
bool formula_type, /* test results of two */
|
||||
const vector<string, ALLOC(string) >& /* implementations. */
|
||||
input_tokens,
|
||||
ProductAutomaton*& product_automaton,
|
||||
pair<unsigned long int, bool>&
|
||||
last_product_automaton);
|
||||
|
||||
void printConsistencyAnalysisResults /* Analyzes a */
|
||||
(ostream& stream, int indent, /* contradicition in the */
|
||||
const vector<string, ALLOC(string) >& /* model checking result */
|
||||
input_tokens); /* consistency check for
|
||||
* an implementation.
|
||||
*/
|
||||
|
||||
void printAutomatonAnalysisResults /* Analyzes a */
|
||||
(ostream& stream, int indent, /* contradiction in the */
|
||||
unsigned long int algorithm1, /* Büchi automata */
|
||||
unsigned long int algorithm2); /* intersection
|
||||
* emptiness check.
|
||||
*/
|
||||
|
||||
void printPath /* Displays information */
|
||||
(ostream& stream, int indent, /* about a single */
|
||||
const deque<StateSpace::size_type, /* system execution. */
|
||||
ALLOC(StateSpace::size_type) >&
|
||||
prefix,
|
||||
const deque<StateSpace::size_type,
|
||||
ALLOC(StateSpace::size_type) >&
|
||||
cycle,
|
||||
const StateSpace& path);
|
||||
|
||||
void printAcceptingCycle /* Displays information */
|
||||
(ostream& stream, int indent, /* a single automaton */
|
||||
vector<Configuration::AlgorithmInformation, /* execution. */
|
||||
ALLOC(Configuration::AlgorithmInformation) >
|
||||
::size_type
|
||||
algorithm_id,
|
||||
const deque<StateSpace::size_type,
|
||||
ALLOC(StateSpace::size_type) >&
|
||||
prefix,
|
||||
const deque<StateSpace::size_type,
|
||||
ALLOC(StateSpace::size_type) >&
|
||||
cycle,
|
||||
const BuchiAutomaton& automaton);
|
||||
|
||||
void printBuchiAutomaton /* Displays information */
|
||||
(ostream& stream, int indent, /* about a Büchi */
|
||||
bool formula_type, /* automaton. */
|
||||
vector<string, ALLOC(string) >& input_tokens,
|
||||
Graph::GraphOutputFormat fmt);
|
||||
|
||||
void evaluateFormula /* Displays information */
|
||||
(ostream& stream, int indent, /* about existence of */
|
||||
bool formula_type, /* accepting system */
|
||||
vector<string, ALLOC(string) >& input_tokens); /* executions. */
|
||||
|
||||
void printFormula /* Displays a formula */
|
||||
(ostream& stream, int indent, /* used for testing. */
|
||||
bool formula_type);
|
||||
|
||||
void printCommandHelp /* Displays help about */
|
||||
(ostream& stream, int indent, /* user commands. */
|
||||
const vector<string, ALLOC(string) >&
|
||||
input_tokens);
|
||||
|
||||
void printInconsistencies /* Lists the system */
|
||||
(ostream& stream, int indent, /* states failing the */
|
||||
vector<string, ALLOC(string) >& input_tokens); /* consistency check
|
||||
* for an algorihm.
|
||||
*/
|
||||
|
||||
void printTestResults /* Displays the test */
|
||||
(ostream& stream, int indent, /* results of the last */
|
||||
vector<string, ALLOC(string) >& input_tokens); /* round performed. */
|
||||
|
||||
void printStateSpace /* Displays information */
|
||||
(ostream& stream, int indent, /* about a state space. */
|
||||
vector<string, ALLOC(string) >& input_tokens,
|
||||
Graph::GraphOutputFormat fmt);
|
||||
|
||||
void changeVerbosity /* Displays or changes */
|
||||
(const vector<string, ALLOC(string) >& /* the verbosity of */
|
||||
input_tokens); /* output. */
|
||||
|
||||
void changeAlgorithmState /* Enables or disables a */
|
||||
(vector<string, ALLOC(string) >& input_tokens, /* set of algorithms */
|
||||
bool enable); /* used in the tests. */
|
||||
|
||||
}
|
||||
|
||||
#endif /* !USERCOMMANDS_H */
|
||||
1055
lbtt/src/getopt.c
Normal file
1055
lbtt/src/getopt.c
Normal file
File diff suppressed because it is too large
Load diff
188
lbtt/src/getopt1.c
Normal file
188
lbtt/src/getopt1.c
Normal file
|
|
@ -0,0 +1,188 @@
|
|||
/* getopt_long and getopt_long_only entry points for GNU getopt.
|
||||
Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98
|
||||
Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include "gnu-getopt.h"
|
||||
|
||||
#if !defined __STDC__ || !__STDC__
|
||||
/* This is a separate conditional since some stdc systems
|
||||
reject `defined (const)'. */
|
||||
#ifndef const
|
||||
#define const
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* Comment out all this code if we are using the GNU C Library, and are not
|
||||
actually compiling the library itself. This code is part of the GNU C
|
||||
Library, but also included in many other GNU distributions. Compiling
|
||||
and linking in this code is a waste when using the GNU C library
|
||||
(especially if it is a shared library). Rather than having every GNU
|
||||
program understand `configure --with-gnu-libc' and omit the object files,
|
||||
it is simpler to just do this in the source for each such file. */
|
||||
|
||||
#define GETOPT_INTERFACE_VERSION 2
|
||||
#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
|
||||
#include <gnu-versions.h>
|
||||
#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
|
||||
#define ELIDE_CODE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ELIDE_CODE
|
||||
|
||||
|
||||
/* This needs to come after some library #include
|
||||
to get __GNU_LIBRARY__ defined. */
|
||||
#ifdef __GNU_LIBRARY__
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
int
|
||||
gnu_getopt_long (argc, argv, options, long_options, opt_index)
|
||||
int argc;
|
||||
char *const *argv;
|
||||
const char *options;
|
||||
const struct gnu_option *long_options;
|
||||
int *opt_index;
|
||||
{
|
||||
return _gnu_getopt_internal (argc, argv, options, long_options, opt_index, 0);
|
||||
}
|
||||
|
||||
/* Like getopt_long, but '-' as well as '--' can indicate a long option.
|
||||
If an option that starts with '-' (not '--') doesn't match a long option,
|
||||
but does match a short option, it is parsed as a short option
|
||||
instead. */
|
||||
|
||||
int
|
||||
gnu_getopt_long_only (argc, argv, options, long_options, opt_index)
|
||||
int argc;
|
||||
char *const *argv;
|
||||
const char *options;
|
||||
const struct gnu_option *long_options;
|
||||
int *opt_index;
|
||||
{
|
||||
return _gnu_getopt_internal (argc, argv, options, long_options, opt_index, 1);
|
||||
}
|
||||
|
||||
|
||||
#endif /* Not ELIDE_CODE. */
|
||||
|
||||
#ifdef TEST
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int
|
||||
main (argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
int c;
|
||||
int digit_optind = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
int this_option_optind = gnu_optind ? gnu_optind : 1;
|
||||
int option_index = 0;
|
||||
static struct gnu_option long_options[] =
|
||||
{
|
||||
{"add", 1, 0, 0},
|
||||
{"append", 0, 0, 0},
|
||||
{"delete", 1, 0, 0},
|
||||
{"verbose", 0, 0, 0},
|
||||
{"create", 0, 0, 0},
|
||||
{"file", 1, 0, 0},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
c = gnu_getopt_long (argc, argv, "abc:d:0123456789",
|
||||
long_options, &option_index);
|
||||
if (c == -1)
|
||||
break;
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case 0:
|
||||
printf ("option %s", long_options[option_index].name);
|
||||
if (gnu_optarg)
|
||||
printf (" with arg %s", gnu_optarg);
|
||||
printf ("\n");
|
||||
break;
|
||||
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
if (digit_optind != 0 && digit_optind != this_option_optind)
|
||||
printf ("digits occur in two different argv-elements.\n");
|
||||
digit_optind = this_option_optind;
|
||||
printf ("option %c\n", c);
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
printf ("option a\n");
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
printf ("option b\n");
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
printf ("option c with value `%s'\n", gnu_optarg);
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
printf ("option d with value `%s'\n", gnu_optarg);
|
||||
break;
|
||||
|
||||
case '?':
|
||||
break;
|
||||
|
||||
default:
|
||||
printf ("?? getopt returned character code 0%o ??\n", c);
|
||||
}
|
||||
}
|
||||
|
||||
if (gnu_optind < argc)
|
||||
{
|
||||
printf ("non-option ARGV-elements: ");
|
||||
while (gnu_optind < argc)
|
||||
printf ("%s ", argv[gnu_optind++]);
|
||||
printf ("\n");
|
||||
}
|
||||
|
||||
exit (0);
|
||||
}
|
||||
|
||||
#endif /* TEST */
|
||||
180
lbtt/src/gnu-getopt.h
Normal file
180
lbtt/src/gnu-getopt.h
Normal file
|
|
@ -0,0 +1,180 @@
|
|||
/* 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 <features.h>, but
|
||||
that does not exist if we are standalone. So: if __GNU_LIBRARY__ is
|
||||
not defined, include <ctype.h>, which will pull in <features.h> 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 <ctype.h>
|
||||
#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 */
|
||||
725
lbtt/src/main.cc
Normal file
725
lbtt/src/main.cc
Normal file
|
|
@ -0,0 +1,725 @@
|
|||
/*
|
||||
* Copyright (C) 1999, 2000, 2001, 2002
|
||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <csignal>
|
||||
#include <cstdlib>
|
||||
#include <ctime>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#ifdef HAVE_READLINE
|
||||
#include <cstdio>
|
||||
#include <readline/readline.h>
|
||||
#include <readline/history.h>
|
||||
#endif /* HAVE_READLINE */
|
||||
#include "Alloc.h"
|
||||
#include "Configuration.h"
|
||||
#include "DispUtil.h"
|
||||
#include "Exception.h"
|
||||
#include "LtlFormula.h"
|
||||
#include "Random.h"
|
||||
#include "SharedTestData.h"
|
||||
#include "StatDisplay.h"
|
||||
#include "TestOperations.h"
|
||||
#include "TestRoundInfo.h"
|
||||
#include "TestStatistics.h"
|
||||
#include "UserCommandReader.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Handler for the SIGINT signal.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
RETSIGTYPE breakHandler(int)
|
||||
{
|
||||
user_break = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* 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<AlgorithmTestResults, /* Test results for each */
|
||||
ALLOC(AlgorithmTestResults) > /* individual algorithm. */
|
||||
test_results;
|
||||
|
||||
vector<TestStatistics, ALLOC(TestStatistics) > /* Overall test */
|
||||
final_statistics; /* statistics for each
|
||||
* algorithm.
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Test loop.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
void 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 (tmpnam(round_info.formula_file_name[0]) == 0
|
||||
|| tmpnam(round_info.formula_file_name[1]) == 0
|
||||
|| tmpnam(round_info.automaton_file_name) == 0
|
||||
|| tmpnam(round_info.cout_capture_file) == 0
|
||||
|| tmpnam(round_info.cerr_capture_file) == 0)
|
||||
throw Exception("unable to allocate names for temporary files");
|
||||
|
||||
/*
|
||||
* If a name for the error log file was given in the configuration, create
|
||||
* the file.
|
||||
*/
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
try
|
||||
{
|
||||
if (!global_options.formula_input_filename.empty())
|
||||
openFile(global_options.formula_input_filename.c_str(),
|
||||
round_info.formula_input_file,
|
||||
ios::in,
|
||||
0);
|
||||
}
|
||||
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<short int>(LRAND(0, LONG_MAX));
|
||||
|
||||
SRAND(configuration.global_options.formula_random_seed);
|
||||
for (int i = 0; i < 3; i++)
|
||||
formula_random_state[i] = static_cast<short int>(LRAND(0, LONG_MAX));
|
||||
#endif /* HAVE_RAND48 */
|
||||
|
||||
/*
|
||||
* If using paths as state spaces, include the internal model checking
|
||||
* algorithm in the set of algorithms.
|
||||
*/
|
||||
|
||||
if (global_options.statespace_generation_mode & Configuration::PATH)
|
||||
{
|
||||
Configuration::AlgorithmInformation lbtt_info
|
||||
= {new string("lbtt"), new string(), new string(), true};
|
||||
|
||||
configuration.algorithms.push_back(lbtt_info);
|
||||
}
|
||||
|
||||
/*
|
||||
* Intialize the vector for storing the test results for each
|
||||
* implementation and the vector for collecting overall test statistics for
|
||||
* 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)
|
||||
{
|
||||
if (!printText(string("Round ") + toString(round_info.current_round)
|
||||
+ " of " + toString(global_options.number_of_rounds)
|
||||
+ "\n\n",
|
||||
2))
|
||||
{
|
||||
if (global_options.verbosity == 1)
|
||||
{
|
||||
if (round_info.current_round > 1)
|
||||
round_info.cout << ' ';
|
||||
round_info.cout << round_info.current_round;
|
||||
round_info.cout.flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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<short int>
|
||||
(LRAND(0, LONG_MAX));
|
||||
#else
|
||||
SRAND(global_options.statespace_random_seed);
|
||||
configuration.global_options.statespace_random_seed
|
||||
= LRAND(0, RAND_MAX);
|
||||
#endif /* HAVE_RAND48 */
|
||||
|
||||
if (global_options.statespace_change_interval == 0)
|
||||
round_info.next_round_to_change_statespace
|
||||
= global_options.number_of_rounds + 1;
|
||||
else
|
||||
round_info.next_round_to_change_statespace
|
||||
+= global_options.statespace_change_interval;
|
||||
|
||||
for (vector<AlgorithmTestResults, ALLOC(AlgorithmTestResults) >
|
||||
::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<short int>(LRAND(0, LONG_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<AlgorithmTestResults, ALLOC(AlgorithmTestResults) >
|
||||
::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(round_info.formula_input_file.is_open()
|
||||
? &round_info.formula_input_file
|
||||
: 0);
|
||||
}
|
||||
catch (const FormulaGenerationException&)
|
||||
{
|
||||
round_info.error = true;
|
||||
round_info.abort = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (user_break)
|
||||
{
|
||||
printText("[User break]\n\n", 2, 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].
|
||||
automaton_stats[0].emptiness_check_performed))
|
||||
verifyFormulaOnPath();
|
||||
|
||||
if (!round_info.error)
|
||||
{
|
||||
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++;
|
||||
|
||||
printText(configuration.algorithmString(algorithm_id) + '\n',
|
||||
2, 4);
|
||||
|
||||
for (int counter = 0; counter < 2; counter++)
|
||||
{
|
||||
if (user_break)
|
||||
{
|
||||
printText("[User break]\n\n", 2, 4);
|
||||
throw UserBreakException();
|
||||
}
|
||||
|
||||
printText(string(counter == 1 ? "Negated" : "Positive")
|
||||
+ " formula:\n",
|
||||
2,
|
||||
6);
|
||||
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
round_info.product_automaton = 0;
|
||||
|
||||
/*
|
||||
* Generate a Büchi automaton using the current algorithm.
|
||||
* `counter' determines the formula which is to be
|
||||
* translated into an automaton; 0 denotes the positive and
|
||||
* 1 the negated formula.
|
||||
*/
|
||||
|
||||
generateBuchiAutomaton(counter, algorithm_id);
|
||||
|
||||
if (global_options.do_cons_test
|
||||
|| global_options.do_comp_test)
|
||||
{
|
||||
/*
|
||||
* Compute the product of the Büchi automaton with the
|
||||
* state space.
|
||||
*/
|
||||
|
||||
generateProductAutomaton(counter, algorithm_id);
|
||||
|
||||
/*
|
||||
* Find the system states from which an accepting
|
||||
* execution cycle can be reached by checking the product
|
||||
* automaton for emptiness.
|
||||
*/
|
||||
|
||||
performEmptinessCheck(counter, algorithm_id);
|
||||
|
||||
/*
|
||||
* If a product automaton was computed in this test round
|
||||
* (it might have not if the emptiness checking result was
|
||||
* already available), release the memory allocated for
|
||||
* the product automaton.
|
||||
*/
|
||||
|
||||
if (round_info.product_automaton != 0)
|
||||
{
|
||||
printText("<deallocating memory>", 4, 8);
|
||||
|
||||
delete round_info.product_automaton;
|
||||
round_info.product_automaton = 0;
|
||||
|
||||
printText(" ok\n", 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
if (round_info.product_automaton != 0)
|
||||
{
|
||||
delete round_info.product_automaton;
|
||||
round_info.product_automaton = 0;
|
||||
}
|
||||
throw;
|
||||
}
|
||||
}
|
||||
catch (const BuchiAutomatonGenerationException&)
|
||||
{
|
||||
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", 2);
|
||||
}
|
||||
|
||||
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
|
||||
|| (num_enabled_implementations == 1
|
||||
&& global_options.statespace_generation_mode
|
||||
& Configuration::PATH))
|
||||
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
|
||||
&& global_options.interactive == Configuration::ONERROR)
|
||||
round_info.next_round_to_stop = round_info.current_round;
|
||||
|
||||
if (round_info.next_round_to_stop == round_info.current_round)
|
||||
{
|
||||
if (global_options.verbosity == 1)
|
||||
{
|
||||
round_info.cout << '\n';
|
||||
round_info.cout.flush();
|
||||
}
|
||||
|
||||
::UserCommandInterface::executeUserCommands();
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 2; i++)
|
||||
removeFile(round_info.formula_file_name[i], 2);
|
||||
|
||||
if (round_info.path_iterator != 0)
|
||||
delete round_info.path_iterator;
|
||||
else if (round_info.statespace != 0)
|
||||
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<AlgorithmTestResults, ALLOC(AlgorithmTestResults) >
|
||||
::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 >= 1)
|
||||
printCollectiveStats(cout, 0);
|
||||
|
||||
if (round_info.formula_input_file.is_open())
|
||||
round_info.formula_input_file.close();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* 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(-1);
|
||||
}
|
||||
|
||||
if (configuration.global_options.verbosity >= 3)
|
||||
configuration.print(cout);
|
||||
|
||||
user_break = false;
|
||||
signal(SIGINT, breakHandler);
|
||||
|
||||
#ifdef HAVE_OBSTACK_H
|
||||
obstack_alloc_failed_handler = &ObstackAllocator::failure;
|
||||
#endif /* HAVE_OBSTACK_H */
|
||||
|
||||
#ifdef HAVE_READLINE
|
||||
using_history();
|
||||
#endif /* HAVE_READLINE */
|
||||
|
||||
try
|
||||
{
|
||||
testLoop();
|
||||
}
|
||||
catch (const Exception& e)
|
||||
{
|
||||
cerr << argv[0] << ": " << e.what() << endl;
|
||||
exit(-1);
|
||||
}
|
||||
catch (const bad_alloc&)
|
||||
{
|
||||
cerr << argv[0] << ": out of memory" << endl;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
230
lbtt/src/translate.cc
Normal file
230
lbtt/src/translate.cc
Normal file
|
|
@ -0,0 +1,230 @@
|
|||
/*
|
||||
* Copyright (C) 1999, 2000, 2001, 2002
|
||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma implementation
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#include <config.h>
|
||||
#include <csignal>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include "Exception.h"
|
||||
#include "LbtWrapper.h"
|
||||
#include "LtlFormula.h"
|
||||
#include "SpinWrapper.h"
|
||||
#ifdef HAVE_GETOPT_LONG
|
||||
#include <getopt.h>
|
||||
#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;
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* A function for showing warnings to the user.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
void printWarning(const string& msg)
|
||||
{
|
||||
cerr << string(command_line_arguments[0]) + ": warning: " + msg << endl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Signal handler for debugging purposes.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
RETSIGTYPE signalHandler(int signal_number)
|
||||
{
|
||||
cerr << string(command_line_arguments[0]) + ": received signal "
|
||||
<< signal_number
|
||||
<< endl;
|
||||
signal(signal_number, SIG_DFL);
|
||||
raise(signal_number);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Main function.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
typedef enum {OPT_HELP = 'h', OPT_LBT, OPT_SPIN, 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},
|
||||
{"version", no_argument, 0, OPT_VERSION},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
command_line_arguments = argv;
|
||||
|
||||
opterr = 1;
|
||||
int opttype, option_index;
|
||||
|
||||
TranslatorInterface* translator = 0;
|
||||
|
||||
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"
|
||||
"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_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;
|
||||
|
||||
signal(SIGHUP, signalHandler);
|
||||
signal(SIGINT, signalHandler);
|
||||
signal(SIGQUIT, signalHandler);
|
||||
signal(SIGILL, signalHandler);
|
||||
signal(SIGABRT, signalHandler);
|
||||
signal(SIGFPE, signalHandler);
|
||||
signal(SIGSEGV, signalHandler);
|
||||
signal(SIGPIPE, signalHandler);
|
||||
signal(SIGALRM, signalHandler);
|
||||
signal(SIGTERM, signalHandler);
|
||||
|
||||
::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;
|
||||
}
|
||||
43
lbtt/src/translate.h
Normal file
43
lbtt/src/translate.h
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright (C) 1999, 2000, 2001, 2002
|
||||
* Heikki Tauriainen <Heikki.Tauriainen@hut.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef TRANSLATE_H
|
||||
#define TRANSLATE_H
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma interface
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#include <config.h>
|
||||
#include <string>
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* 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 */
|
||||
Loading…
Add table
Add a link
Reference in a new issue